
Постоянно сталкиваюсь в работе с датчиком измерения температуры DS18b20. Все в нем прекрасно, кроме тормозной работы. Особенно доставляет работа через библиотеку DallasTemperature.h . Опрос датчика занимает до 1мс, при этом весь скетч тормозит со страшной силой. Я предлагаю иной вариант работы с ним, без библиотек и тормозов
Сама функция на 1 датчик с автоматическим поиском его адреса:
Вызов в цикле void loop
void dallRead(unsigned long interval) { static unsigned long prevTime = 0; if (millis() - prevTime > interval) { //Проверка заданного интервала static boolean flagDall = 0; //Признак операции prevTime = millis(); flagDall = ! flagDall; //Инверсия признака if (flagDall) { /////////// if ( !ds.search(addr)) { ds.reset_search(); return +1000; } if ( addr[0] != 0x10 && addr[0] != 0x28) { return -1000; } ds.reset(); // сброс шины ds.select(0xCC); //выставить адрес ds.write(0x4E); // разрешение записать конфиг ds.write(0x7F); // точность 0,5гр = 1F; 0,25гр = 3F; 0,125гр = 5F; 0,0625гр = 7F ds.write(0xFF); //Tl контроль температуры мин -128грд //////////// ds.reset(); ds.write(0xCC); //Обращение ко всем датчикам ds.write(0x44, 1); //Команда на конвертацию 1 -паразитное питание flagDallRead = 1; //Время возврата в секундах } else { ds.reset(); ds.select(addr); // обращаемся по адресу ds.write(0xBE, 1); // чтение из памяти for (int i = 0; i < 9; i++) { data[i] = ds.read (); } ds.reset_search(); int16_t raw = ((data[1] << 8) | data[0]);//=======Пересчитываем в температуру Temp_val = (float)raw / 16.0; } } }
Пример вызова:
dallRead(flagDallRead * 1000)
Скетч пример:
#include <OneWire.h> float Temp_val; // переменная температуы OneWire ds(12); // Пин OneWire где висит датчик температуры byte addr[8]; byte flagDallRead; byte data[12]; //для температуры void setup() { // put your setup code here, to run once: Serial.begin(9600); } //***Функция считывания температуры c Далласов***** void dallRead(unsigned long interval) { static unsigned long prevTime = 0; if (millis() - prevTime > interval) { //Проверка заданного интервала static boolean flagDall = 0; //Признак операции prevTime = millis(); flagDall = ! flagDall; //Инверсия признака if (flagDall) { /////////// if ( !ds.search(addr)) { ds.reset_search(); return +1000; } if ( addr[0] != 0x10 && addr[0] != 0x28) { return -1000; } ds.reset(); // сброс шины ds.select(0xCC); //выставить адрес ds.write(0x4E); // разрешение записать конфиг ds.write(0x7F); // точность 0,5гр = 1F; 0,25гр = 3F; 0,125гр = 5F; 0,0625гр = 7F ds.write(0xFF); //Tl контроль температуры мин -128грд //////////// ds.reset(); ds.write(0xCC); //Обращение ко всем датчикам ds.write(0x44, 1); //Команда на конвертацию 1 -паразитное питание flagDallRead = 1; //Время возврата в секундах } else { ds.reset(); ds.select(addr); // обращаемся по адресу ds.write(0xBE, 1); // чтение из памяти for (int i = 0; i < 9; i++) { data[i] = ds.read (); } ds.reset_search(); int16_t raw = ((data[1] << 8) | data[0]);//=======Пересчитываем в температуру Temp_val = (float)raw / 16.0; } } } //***Функция считывания температуры c Далласов***** void loop() { dallRead(flagDallRead * 1000); // put your main code here, to run repeatedly: Serial.println(Temp_val); }
Ссылка на али: Купить
Добрый день, уважаемый Скромный Айтишник!
Программа, действительно, компактная и соблазнительная. Но моих слабых знаний не хватает для того, чтобы понять её и применить для своих целей. Буду очень признателен, если поделитесь более подробным комментарием к строкам программы.
Комментарии почти в каждой строке, что именно не понятно?
Можно полный скетч, а не ислючительно функцию?
Скетч чего? Это просто функция, которую вы можете использовать любом скетче где нужно измерение температуры.
тоже делаю первые шаги на ардуинке и ищу пример скетча чтения температуры без задержки. функция — это круто, но тут еще переменные нужно объявить, с типами данных не напартачить, баблиотеки подключить. я так понимаю тут использовалсь OneWire.h
так можно пример?
и еще есть мысль — структура «if (millis() — prevTime > interval)» каждый раз делает расчет + сравнение. может лучше сделать типа
if (millis() > interval)
interval = millis() + interval
тогда расчет будет только после выполнения условия…
Добавил скетч-пример
Спасибо.Очень интересное решения.Прошу ответить на вопросы :
1. в функции ds.write (0x44, 1) аргумент 1 (для паразитарного питания) если у мене не паразитарное то мне не надо писать «0», просто писать ds.write (0x44)?
2. как после обнаруженя датчика присвоить ему имя? Например, нашел 1 датчик — присвоить имя «сенсор 1» и т.д.?
3.
Функция void dallRead(…) не имеет возвращаемых данных, но вы пытаетесь их вернуть: return +1000 (retrun -1000)
if ( !ds.search(addr)) {
ds.reset_search();
return +1000;
}
if ( addr[0] != 0x10 && addr[0] != 0x28) {
return -1000;
}