где может быть проблема в датчике или коде? ds18b20
- Войдите на сайт для отправки комментариев
Ребята, подскажите почему при подключении 2х датчиков DS18B20, один из них ведет себя странно? Он показывает температуру с шагом 0,5 градусов. Со вторым все в порядке.
#define TEMP_PIN 2 //пин D2 для DS18B20 //================================== Температурный датчик OneWire ds(TEMP_PIN); //Создаем объект для работы с термометром float temp1, temp2; unsigned long lastUpdateTime = 0; // Переменная для хранения времени последнего считывания с датчика const int TEMP_UPDATE_TIME = 2000; // Определяем периодичность проверок byte addr1[8]={0x28,0x2A,0x94,0x5E,0x32,0x14,0x01,0x1A}; byte addr2[8]={0x28,0x01,0xBC,0xBC,0x13,0x19,0x01,0x6A}; void setup() { Serial.begin(9600); pinMode(TEMP_PIN, INPUT); // устанавливает режим работы - вход } //================================== Считывание температуры ds18b20 int dTemperature2(){ ds.reset();// сброс шины ds.write(0xCC);// обращение ко всем датчикам ds.write(0x44);// начать преобразование (без паразитного питания) if ((abs(millis() - lastUpdateTime)) > TEMP_UPDATE_TIME) { lastUpdateTime = millis(); ds.reset(); ds.select(addr1); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp1 = ds.read() | (ds.read()<<8); //прочитаны 2 байта ds.reset(); ds.select(addr2); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp2 = ds.read() | (ds.read()<<8); //прочитаны 2 байта } } void loop() { dTemperature2(); Serial.print(temp1/16.00); Serial.print(" "); Serial.println(temp2/16.00); }

#include <Wire.h> //Подключаем библиотеку для использования однопроводного интерфейса #include <OneWire.h> //Подключаем библиотеку для температурного датчика DS18B20 //=============================Датчики и управление #define TEMP_PIN 2 //пин D2 для DS18B20 (2шт) //================================== Температурный датчик* OneWire ds(TEMP_PIN); //Создаем объект для работы с термометром float temp1, temp2; //Температура воды unsigned long lastUpdateTime = 0; // Переменная для хранения времени последнего считывания с датчика const int TEMP_UPDATE_TIME = 2000; // Определяем периодичность проверок byte addr1[8]={0x28,0x2A,0x94,0x5E,0x32,0x14,0x01,0x1A}; byte addr2[8]={0x28,0x01,0xBC,0xBC,0x13,0x19,0x01,0x6A}; void setup() { Serial.begin(9600); pinMode(TEMP_PIN, INPUT); // устанавливает режим работы - вход } int detectTemperature2(){ ds.reset();// сброс шины ds.write(0xCC);// обращение ко всем датчикам (2шт) ds.write(0x44);// начать преобразование (без паразитного питания) if ((abs(millis() - lastUpdateTime)) > TEMP_UPDATE_TIME) { lastUpdateTime = millis(); ds.reset(); ds.select(addr1); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp1 = ds.read() | (ds.read()<<8); //прочитаны 2 байта ds.reset(); ds.select(addr2); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp2 = ds.read() | (ds.read()<<8); //прочитаны 2 байта } } void loop() { detectTemperature2(); Serial.print(temp1/16.00); Serial.print(" "); Serial.println(temp2/16.00); }Это именно тот код, который выдавал в монитор ту печать?
Давайте Вы запустите его ещё раз, только
1. В строку №45 вставьте Serial.prinln("Read it");
2. В мониторе порта включите временные метки;
3. Содержимое монитора порта выкладывайте текстом
4. Не забудьте также выложить актуальный (после п.1) код - (нужно чтобы мы видели код и его печать в монитор, а не догадывались что и куда Вы вставили)
датчику наверное кирдык
Да это именно тот код который я запустил.
Я delay(2000) еще в loop добавил.
#include <Wire.h> //Подключаем библиотеку для использования однопроводного интерфейса #include <OneWire.h> //Подключаем библиотеку для температурного датчика DS18B20 //=============================Датчики и управление #define TEMP_PIN 2 //пин D2 для DS18B20 (2шт) //================================== Температурный датчик* OneWire ds(TEMP_PIN); //Создаем объект для работы с термометром float temp1, temp2; //Температура воды unsigned long lastUpdateTime = 0; // Переменная для хранения времени последнего считывания с датчика const int TEMP_UPDATE_TIME = 2000; // Определяем периодичность проверок byte addr1[8]={0x28,0x2A,0x94,0x5E,0x32,0x14,0x01,0x1A}; byte addr2[8]={0x28,0x01,0xBC,0xBC,0x13,0x19,0x01,0x6A}; void setup() { Serial.begin(9600); pinMode(TEMP_PIN, INPUT); // устанавливает режим работы - вход } int detectTemperature2(){ ds.reset();// сброс шины ds.write(0xCC);// обращение ко всем датчикам (2шт) ds.write(0x44);// начать преобразование (без паразитного питания) if ((abs(millis() - lastUpdateTime)) > TEMP_UPDATE_TIME) { lastUpdateTime = millis(); ds.reset(); ds.select(addr1); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp1 = ds.read() | (ds.read()<<8); //прочитаны 2 байта ds.reset(); ds.select(addr2); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp2 = ds.read() | (ds.read()<<8); //прочитаны 2 байта } } void loop() { delay(2000); detectTemperature2(); Serial.println("Read it"); Serial.print(temp1/16.00); Serial.print(" "); Serial.println(temp2/16.00); }Я delay(2000) еще в loop добавил.
Блин, Вас кто-то просил? У Вас ошибка в loop, я хотел в этом убедиться и показать Вам, а своим делеем Вы её замаскировали.
Кроме того, я просил Вас добавить ещё одну печать (п. 1). Вы этого не сделали.Виноват. Заметил, что сделали. Это моя вина, я ошибся. Эта печать нужна в строке №40, проститеВам нужна помощь? Так делайте что говорят! Давайте ещё раз, только точно, как я написал.
Да конечно нужна помощь.
[spoiler]
#include <Wire.h> //Подключаем библиотеку для использования однопроводного интерфейса #include <OneWire.h> //Подключаем библиотеку для температурного датчика DS18B20 //=============================Датчики и управление #define TEMP_PIN 2 //пин D2 для DS18B20 (2шт) //================================== Температурный датчик* OneWire ds(TEMP_PIN); //Создаем объект для работы с термометром float temp1, temp2; //Температура воды unsigned long lastUpdateTime = 0; // Переменная для хранения времени последнего считывания с датчика const int TEMP_UPDATE_TIME = 2000; // Определяем периодичность проверок byte addr1[8]={0x28,0x2A,0x94,0x5E,0x32,0x14,0x01,0x1A}; byte addr2[8]={0x28,0x01,0xBC,0xBC,0x13,0x19,0x01,0x6A}; void setup() { Serial.begin(9600); pinMode(TEMP_PIN, INPUT); // устанавливает режим работы - вход } int detectTemperature2(){ ds.reset();// сброс шины ds.write(0xCC);// обращение ко всем датчикам (2шт) ds.write(0x44);// начать преобразование (без паразитного питания) if ((abs(millis() - lastUpdateTime)) > TEMP_UPDATE_TIME) { lastUpdateTime = millis(); ds.reset(); ds.select(addr1); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp1 = ds.read() | (ds.read()<<8); //прочитаны 2 байта ds.reset(); ds.select(addr2); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp2 = ds.read() | (ds.read()<<8); //прочитаны 2 байта Serial.println("Read it"); } } void loop() { detectTemperature2(); Serial.print(temp1/16.00); Serial.print(" "); Serial.println(temp2/16.00); }Вот и смотрите на свою печать. Вы видите сколько раз она печатает "между" реальными измерениями? Вы и раньше это видели, потому и поставили задержку. Только задержка эта маскирует проблему, а не решает.
Проблема же в том, что у Вас неверно написана логика. Смотрите на свой loop. Он тупо в цикле вызывает detectTemperature2, печатает и снова вызывает detectTemperature2, и так постоянно. Т.е. detectTemperature2 вызывается (судя по Вашей печати) каждые 40 мс.
И что же Вы делаете каждые 40 мс? Вы делаете reset и приказываете всем датчикам начать преобразование (строки №№ 26-28). Через 40 мс Вы снова делаете reset и приказываете всем датчикам начать преобразование, потом ещё и ещё. Потом, когда сработает условие в строке №29 Вы кидаетесь читать значение, хотя начать преобразование приказали только что! Получается, что вместо того, чтобы начать преобразование и спокойно ждать (не дёргая датчик), Вы дёргаете его каждые 40 мс, приказывая отресетится начать преобразование заново. Удивительно, что он у Вас хоть что-то показывает.
Эту логику надо переписывать. Так оно работать не должно и не будет. Вы должны запустить преобразование, выждать интервал и только после этого читать датчик. А не дергать его каждые 40мс приказами "ресет" - "начинай по новой".
Я понятно написал?
С температурами связано несколько параметров - собственно само значение t, адрес датчика этой t, название этой t. Когда датчиков много, удобнее работать со структурами. Ну и между опросом и чтением, само собой, паузу минимум в секунду делать. Также важно проверять контрольную сумму от датчиков, а то частенько пролетают "лютые" значения.
#define Dallas_pin 2 // определяем пин для линии связи 1-wire датчиков DS18B20 const byte TEMP_UPDATE_TIME = 2; // Определяем периодичность опроса датчиков, сек #include <OneWire.h> // библиотека для DS18B20 OneWire ds(Dallas_pin); // датчики DS18B20 на нужный пин // структура данных для температур struct temperature { const char NameTemp[10]; // название температуры. в скобках макс. число символов , не превышать!!! byte Addr [8]; // адрес датчика float Temp; // значение температуры }; // пишем список нужных температур (в конце - размер массива температур, так и оставляем) enum Temperature_enum { Voda, Vozduh, Ulica, size_arrayTemp }; // забиваем в структуру нужные данные в той же последовательности, что список выше temperature Temperature[size_arrayTemp] = { "Voda", {0x28, 0xFF, 0xB2, 0xB5, 0xC1, 0x17, 0x05, 0xD1}, 20.00, "Vozduh",{0x28, 0xFF, 0xD3, 0xE2, 0xC1, 0x17, 0x04, 0x0D}, 20.00, "Ulica", {0x28, 0xFF, 0xF8, 0xBC, 0xC1, 0x17, 0x04, 0x48}, 20.00, }; #define NEWLINE 1 #define ALLSENSORS size_arrayTemp void DS18B20_communic () { static uint32_t prevtime = 0; // для таймера отсчета интервала времени // каждый интервал времени либо делаем запрос датчиков, либо чтение t : if (millis()- prevtime > (uint32_t)(1000UL*TEMP_UPDATE_TIME) ) { prevtime = millis(); static bool request_readT = 0; // флаг запрос/чтение request_readT=!request_readT; // меняем состояние флага if (request_readT) // если запрос: { ds.reset(); // сброс шины ds.write(0xCC); // обращение ко всем датчикам ds.write(0x44); // начать преобразование (без паразитного питания) } else // если чтение: { for (byte i=0; i<size_arrayTemp; i++) // читаем все датчики в цикле { float Temper_ = 20.00; byte buff[9]; ds.reset(); ds.select(Temperature[i].Addr); ds.write(0xBE); // чтение регистров датчиков for (byte j=0; j<9; j++) buff[j]=ds.read(); // читаем все 9 байт от датчика ds.reset(); if (OneWire::crc8(buff, 8) == buff[8]){ // если контрольная сумма совпадает Temper_ = buff[0]|(buff[1]<<8); // читаем температуру из первых двух байт (остальные были нужны только для проверки CRC) Temper_ = Temper_ / 16.00; if (Temper_<150 && Temper_>-55) Temperature[i].Temp = Temper_; } }// end for }//end reading t }// end interval } void PrintT(const byte &temper, byte ln=0) { for (int i=0; i<size_arrayTemp; i++ ) { Serial.print (Temperature[temper<size_arrayTemp?temper:i].NameTemp); Serial.print (" "); Serial.print (Temperature[temper<size_arrayTemp?temper:i].Temp); Serial.print (" "); if (temper < size_arrayTemp) break; } if (ln>0 || temper >= size_arrayTemp ) Serial.println(); } void setup() { Serial.begin (9600); } void loop() { DS18B20_communic (); // опрос датчиков t даллас // распечатаем периодически температуры: static uint32_t prevtime_print = 0; if (millis() - prevtime_print >1000 ) { prevtime_print = millis(); PrintT (Voda); // просто печать PrintT (Vozduh, NEWLINE); // печать с переводом строки PrintT (ALLSENSORS); // печать t сразу всех датчиков } }// end loopВозможно, датчик стоял уже где- нибудь, и у него в eeprom записано, с каким разрешением считать температуру...