может кто подскажет, а как этот код заставить работать и в Proteus ?
Чёт Вы всю тему жалуетесь на протеус, неужели до сих пор не разобрались?
Там в свойствах датчика есть временной интервал. И интервал этот не имеет никакого отношения к такому же интервалу, заданному в OneWire. Поставьте такой, как в OneWire и всё заработает.
Не стОит.)
Вспомнилось. Как то после очередного коммунистического субботника сидим мы в кабаке (известно же чем эти субботники заканчиваются). И тут товарищ предлагает послушать его стихи. Ну, валяй. И вдруг.
"Обрушился на наше поколение... социализм предельно развитой..." Мы сразу тише, тише, тише...)
в протеусе работает этот код, но он не работает в ESP32, ругается на библиотеку MsTimer2.h, пытался без с нее, сделать таймер на millis, не получилось (((
#include <MsTimer2.h>
#include <OneWire.h>
OneWire sensDs (2);
#define POWER_MODE 0 // режим питания, 0 - внешнее, 1 - паразитное
#define MEASURE_PERIOD 500 // время измерения, * 2 мс
int timeCount; // счетчик времени измерения
boolean flagSensReady; // признак готовности данных с датчика
byte bufData[9]; // буфер данных
float temperature; // измеренная температура
void setup() {
MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс
MsTimer2::start(); // разрешаем прерывание по таймеру
Serial.begin(57600); // инициализируем порт, скорость 9600
}
void loop() {
if ( flagSensReady == true ) {
flagSensReady= false;
// данные готовы
if ( OneWire::crc8(bufData, 8) == bufData[8] ) { // проверка CRC
// данные правильные
temperature= (float)((int)bufData[0] | (((int)bufData[1]) << 8)) * 0.0625 + 0.03125;
Serial.println(temperature);
}
}
}
//--- обработчик прерывания 2 мс
void timerInterrupt() {
// управление датчиком DS18B20 паралллельным процессом
timeCount++; if ( timeCount >= MEASURE_PERIOD ) { timeCount=0; flagSensReady=true; }
if (timeCount == 0) sensDs.reset(); // сброс шины
if (timeCount == 1) sensDs.write(0xCC, POWER_MODE); // пропуск ROM
if (timeCount == 2) sensDs.write(0x44, POWER_MODE); // инициализация измерения
if (timeCount == 480) sensDs.reset(); // сброс шины
if (timeCount == 481) sensDs.write(0xCC, POWER_MODE); // пропуск ROM
if (timeCount == 482) sensDs.write(0xBE, POWER_MODE); // команда чтения памяти датчика
if (timeCount == 483 ) bufData[0]= sensDs.read(); // чтение памяти датчика
if (timeCount == 484 ) bufData[1]= sensDs.read(); // чтение памяти датчика
if (timeCount == 485 ) bufData[2]= sensDs.read(); // чтение памяти датчика
if (timeCount == 486 ) bufData[3]= sensDs.read(); // чтение памяти датчика
if (timeCount == 487 ) bufData[4]= sensDs.read(); // чтение памяти датчика
if (timeCount == 488 ) bufData[5]= sensDs.read(); // чтение памяти датчика
if (timeCount == 489 ) bufData[6]= sensDs.read(); // чтение памяти датчика
if (timeCount == 490 ) bufData[7]= sensDs.read(); // чтение памяти датчика
if (timeCount == 491 ) bufData[8]= sensDs.read(); // чтение памяти датчика
}
На reset отвечает, обмен есть. Я бы зациклил reset и какую-нибудь SKIP_ROM. И сравнил бы времена...
Так а зачем вы тогда рабочую в Протеусе проверяете? Тоже прикалываетесь? Я пас.(
Так а зачем вы тогда рабочую в Протеусе проверяете? Тоже прикалываетесь? Я пас.(
это другая прошивка, не работает на esp32, а мне нужна простая прошивка, без проверок, без наворотов, температура в целых числах, но что бы она работала в ардуине, есп32 и протеусе...
в протеусе работает этот код, но он не работает в ESP32, ругается на библиотеку MsTimer2.h, пытался без с нее, сделать таймер на millis, не получилось (((
зачем весь этот ужас аж с пятнадцатью! событиями по таймеру? - вы ветку с начала не читали? - события только два - сначала запрашиваем данные, потом по миллис отмеряем 750-1000 мс и получаем температуру. ВСЕ
Код элементарнейший и работает на любом МК, где есть реализация OneWire
и вообще, последние 3 страницы - какой-то невероятный бред. Вам дали готовый код в сообщении #282. Все, что от вас требовалось - правильно вставить его в программу. Что вы тут обсуждаете пятый день?
Мне кажется, Ваша проблема в том, что Вы - а) нифига не понимаете и, к сожалению б) не хотите учиться. Вам "некогда разбираться с этим долбаным датчиком", вы хотели по-быстрому - а по факту ваш быстрый путь буксует который день. Значительно правильнее было бы сесть и спокойно разобраться с протоколом, потратили бы один вечер и решили проблему
да, таки получилось. Спасибо за наводку. Почитал что такое указатели и ссылки, и заработало. Оказалось еще проще чем я думал.
Теперь хочу сделать еще варинт - один пин на десять датчиков, хранение номера каждого датчика в епром с последовательным чтением этих номеров из епром. Но наверное не в эту тему писать.
интересный момент - код автора из самого первого сообщения, выводит разные данные на разных MCU, если адрес термосенсора НЕ правильный, то есть на шине нет сенсора с таким адресом.
например на Arduino based - выводит "-0.06"
а на другом MCU - Cubecell AB01/02 на базе другого чипа - выводит "4095.94"
упростил до минимума, наверное, работает )))
#include <OneWire.h> OneWire ds(4); int16_t temperature; unsigned long lastUpdateTime; unsigned long timing; void setup() { Serial.begin(57600); } void loop() { if (millis() - timing > 2000) { timing = millis(); detectTemperature(); Serial.println(temperature); } } int detectTemperature() { byte data[2]; ds.reset(); ds.write(0xCC); ds.write(0x44); if (millis() - lastUpdateTime > 1500) { lastUpdateTime = millis(); ds.reset(); ds.write(0xCC); ds.write(0xBE); data[0] = ds.read(); data[1] = ds.read(); temperature = (data[1] << 8) + data[0]; temperature = temperature >> 4; } }не, посмотри как у деда, сначала читаем а потом сразу же запрос
Дет, црц - это заибок, а есть ли там фича, шо даччик апосля ресета или инита ответил на шину?
Столь далеко мои компетенции не простираюца.
Вы что, прикалываетесь?) Любой обмен начинается с ресет, на который ус-во должно ответить presence. Вот и проверяйте, а не однажды при старте.)
может кто подскажет, а как этот код заставить работать и в Proteus ?
может кто подскажет, а как этот код заставить работать и в Proteus ?
Чёт Вы всю тему жалуетесь на протеус, неужели до сих пор не разобрались?
Там в свойствах датчика есть временной интервал. И интервал этот не имеет никакого отношения к такому же интервалу, заданному в OneWire. Поставьте такой, как в OneWire и всё заработает.
не жалуюсь, а всего лишь прошу совета!
А у нас уже давно не Страна Советов.)
Та что ж вы такой обидчивый! Там же смайлик.
извините!
Не стОит.)
Вспомнилось. Как то после очередного коммунистического субботника сидим мы в кабаке (известно же чем эти субботники заканчиваются). И тут товарищ предлагает послушать его стихи. Ну, валяй. И вдруг.
"Обрушился на наше поколение... социализм предельно развитой..." Мы сразу тише, тише, тише...)
Ну, чё, разобрались? Заработало в протеусе?
нет, пока не получается (((
Ну, смотрите какое время в OneWire и поставьте такое же в протеусе. Всё всегда работало.
меняю, но эффекта нет, что то не так видно делаю..
Там в свойствах ещё другие времена есть. Time Reset Low и пр.
да, менял везде, чувствую где то какой то подвох, а где, не могу понять (((
Ну тогда станьте на шину осциллографом и зарядите простой скетч. Начните с reset, посмотрите на ответ. Ну и так далее.
встал, но мне это ничего не дает )))
в протеусе работает этот код, но он не работает в ESP32, ругается на библиотеку MsTimer2.h, пытался без с нее, сделать таймер на millis, не получилось (((
#include <MsTimer2.h> #include <OneWire.h> OneWire sensDs (2); #define POWER_MODE 0 // режим питания, 0 - внешнее, 1 - паразитное #define MEASURE_PERIOD 500 // время измерения, * 2 мс int timeCount; // счетчик времени измерения boolean flagSensReady; // признак готовности данных с датчика byte bufData[9]; // буфер данных float temperature; // измеренная температура void setup() { MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс MsTimer2::start(); // разрешаем прерывание по таймеру Serial.begin(57600); // инициализируем порт, скорость 9600 } void loop() { if ( flagSensReady == true ) { flagSensReady= false; // данные готовы if ( OneWire::crc8(bufData, 8) == bufData[8] ) { // проверка CRC // данные правильные temperature= (float)((int)bufData[0] | (((int)bufData[1]) << 8)) * 0.0625 + 0.03125; Serial.println(temperature); } } } //--- обработчик прерывания 2 мс void timerInterrupt() { // управление датчиком DS18B20 паралллельным процессом timeCount++; if ( timeCount >= MEASURE_PERIOD ) { timeCount=0; flagSensReady=true; } if (timeCount == 0) sensDs.reset(); // сброс шины if (timeCount == 1) sensDs.write(0xCC, POWER_MODE); // пропуск ROM if (timeCount == 2) sensDs.write(0x44, POWER_MODE); // инициализация измерения if (timeCount == 480) sensDs.reset(); // сброс шины if (timeCount == 481) sensDs.write(0xCC, POWER_MODE); // пропуск ROM if (timeCount == 482) sensDs.write(0xBE, POWER_MODE); // команда чтения памяти датчика if (timeCount == 483 ) bufData[0]= sensDs.read(); // чтение памяти датчика if (timeCount == 484 ) bufData[1]= sensDs.read(); // чтение памяти датчика if (timeCount == 485 ) bufData[2]= sensDs.read(); // чтение памяти датчика if (timeCount == 486 ) bufData[3]= sensDs.read(); // чтение памяти датчика if (timeCount == 487 ) bufData[4]= sensDs.read(); // чтение памяти датчика if (timeCount == 488 ) bufData[5]= sensDs.read(); // чтение памяти датчика if (timeCount == 489 ) bufData[6]= sensDs.read(); // чтение памяти датчика if (timeCount == 490 ) bufData[7]= sensDs.read(); // чтение памяти датчика if (timeCount == 491 ) bufData[8]= sensDs.read(); // чтение памяти датчика }На reset отвечает, обмен есть. Я бы зациклил reset и какую-нибудь SKIP_ROM. И сравнил бы времена...
Так а зачем вы тогда рабочую в Протеусе проверяете? Тоже прикалываетесь? Я пас.(
это другая прошивка, не работает на esp32, а мне нужна простая прошивка, без проверок, без наворотов, температура в целых числах, но что бы она работала в ардуине, есп32 и протеусе...
Вот Вам рабочие значения. С такими, вроде, работает, как видите.
в протеусе работает этот код, но он не работает в ESP32, ругается на библиотеку MsTimer2.h, пытался без с нее, сделать таймер на millis, не получилось (((
зачем весь этот ужас аж с пятнадцатью! событиями по таймеру? - вы ветку с начала не читали? - события только два - сначала запрашиваем данные, потом по миллис отмеряем 750-1000 мс и получаем температуру. ВСЕ
Код элементарнейший и работает на любом МК, где есть реализация OneWire
и вообще, последние 3 страницы - какой-то невероятный бред. Вам дали готовый код в сообщении #282. Все, что от вас требовалось - правильно вставить его в программу. Что вы тут обсуждаете пятый день?
Мне кажется, Ваша проблема в том, что Вы - а) нифига не понимаете и, к сожалению б) не хотите учиться. Вам "некогда разбираться с этим долбаным датчиком", вы хотели по-быстрому - а по факту ваш быстрый путь буксует который день. Значительно правильнее было бы сесть и спокойно разобраться с протоколом, потратили бы один вечер и решили проблему
все! с вашими значениями и у меня заработало! спасибо!
Как сделать попроще три датчика на три вывода. Код набросал, работает, но хотелось бы еще упростить.
float getTemp3() {int ii; ii = 0; label: wdt_reset(); //Serial.println(ci); if (ii < 6) { // если неудачно то делаем 6 попыток byte data[12]; // byte addr[8]; if ( !ds3.search(addr)) { Serial.println F("No more addresses."); wdt_reset(); //Serial.println(addr[8]); ds3.reset_search(); delay(250); wdt_reset(); ++ii; goto label; } if (OneWire::crc8(addr, 7) != addr[7]) { //проверка массива адреса на срц Serial.println F("CRC is not valid!"); ++ii; goto label; wdt_reset(); } ds3.search(addr); // ds3.reset_search(); ds3.reset(); ds3.select(addr); ds3.write(0x44); delay(1000); wdt_reset(); ds3.reset(); ds3.select(addr); ds3.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds3.read(); if (OneWire::crc8(data, 8) != data[8]) { // проверка црц считанной температуры. Serial.println F("Data CRC is not valid!"); wdt_reset(); ++ii; goto label; } int raw = (data[1] << 8) | data[0]; // Переводим в температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; wdt_reset(); } }Выше код на третий датчик, тоесть :
как бы извернуться, и не три раза повторять float getTemp3() float getTemp2() float getTemp1()
а написать один для всех датчиков? Но именно по тому пути, который я выбрал. Код выше - полностью рабочий.
Чтобы указать в итоге как то так:
Ну, добавьте в параметры функции ссылку на объект датчика, например
OneWire & ds
внутри функции используйте этот ds, а при вызове, передавайте тот, который нужен, просто имя безо всяких значков.
Или я чего-то не понял?
да, таки получилось. Спасибо за наводку. Почитал что такое указатели и ссылки, и заработало. Оказалось еще проще чем я думал.
Теперь хочу сделать еще варинт - один пин на десять датчиков, хранение номера каждого датчика в епром с последовательным чтением этих номеров из епром. Но наверное не в эту тему писать.
Удалось кому-нибудь получать температуру с этого датчика (только чтение) быстрее 10 миллисекунд?
Интервал между запросами не важен
8 мс за 1 проход обычно. За несколько итого меньше.
8 мс за 1 проход обычно. За несколько итого меньше.
у меня в районе 14 получается, долго, нужно как можно быстрее, лучше 1мс было бы то, что надо
Минимум 850мкс, если растянуть. Примерно так:
void Ds18b20Exe() { static uint16_t state; static uint16_t timer; static uint16_t temp; if (timer) --timer; else switch (state) { case 0: if (!ds_reset()) break; next(state); ds_byte(SKIP_ROM); next(state); ds_byte(READ_SCRATCHPAD); next(state); temp = ds_byte(0xff); next(state); temp |= ds_byte(0xff)<<8; temperature = ds2cels(temp); next(state); if (!ds_reset()) { state = 0; break; } next(state); ds_byte(SKIP_ROM); next(state); ds_byte(CONVERT_T); timer = ms2sys(CONVERTION_TIME); state = 0; break; } }По очереди открывал от комментариев функции и получал время выполнения. Результаты я свел в таблицу.
Нарисуй на таймере с прерываниями. Будет меньше 1 мс процессорного времени легко.
Нарисуй на таймере с прерываниями. Будет меньше 1 мс процессорного времени легко.
я ненастоящий сталевар
интересный момент - код автора из самого первого сообщения, выводит разные данные на разных MCU, если адрес термосенсора НЕ правильный, то есть на шине нет сенсора с таким адресом.
например на Arduino based - выводит "-0.06"
а на другом MCU - Cubecell AB01/02 на базе другого чипа - выводит "4095.94"
никак не пойму, почему так..