
Постоянно сталкиваюсь в работе с датчиком измерения температуры 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;
}