где может быть проблема в датчике или коде? ds18b20

Valerman
Offline
Зарегистрирован: 06.01.2020

Ребята, подскажите почему при подключении 2х датчиков DS18B20, один из них ведет себя странно? Он показывает температуру с шагом 0,5 градусов. Со вторым все в порядке. 



#include <Wire.h>                   //Подключаем библиотеку                                    
#include <OneWire.h>                //Подключаем библиотеку
 

#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)) &gt; TEMP_UPDATE_TIME) { lastUpdateTime = millis(); ds.reset(); ds.select(addr1); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp1 = ds.read() | (ds.read()&lt;&lt;8); //прочитаны 2 байта ds.reset(); ds.select(addr2); ds.write(0xBE); // Read Scratchpad (чтение регистров) temp2 = ds.read() | (ds.read()&lt;&lt;8); //прочитаны 2 байта } } void loop() { dTemperature2(); Serial.print(temp1/16.00); Serial.print(&quot; &quot;); Serial.println(temp2/16.00); }

 

Valerman
Offline
Зарегистрирован: 06.01.2020

#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);

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Это именно тот код, который выдавал в монитор ту печать?

Давайте Вы запустите его ещё раз, только

1. В строку №45 вставьте Serial.prinln("Read it");
2. В мониторе порта включите временные метки;
3. Содержимое монитора порта выкладывайте текстом
4. Не забудьте также выложить актуальный (после п.1) код - (нужно чтобы мы видели код и его печать в монитор, а не догадывались что и куда Вы вставили)

genia1991
Offline
Зарегистрирован: 25.12.2019

датчику наверное кирдык

Valerman
Offline
Зарегистрирован: 06.01.2020

Да это именно тот код который я запустил. 

Я delay(2000) еще в loop добавил. 

18:05:12.603 -> Read it
18:05:12.603 -> 28.00  26.75
18:05:14.633 -> Read it
18:05:14.633 -> 28.00  27.00
18:05:16.635 -> Read it
18:05:16.635 -> 28.50  27.44
18:05:18.657 -> Read it
18:05:18.657 -> 29.00  27.87
18:05:20.683 -> Read it
18:05:20.683 -> 29.00  28.31
18:05:22.674 -> Read it
18:05:22.674 -> 29.50  28.81
18:05:24.698 -> Read it
18:05:24.698 -> 29.50  29.37
18:05:26.720 -> Read it
18:05:26.720 -> 30.00  29.94
18:05:28.750 -> Read it
18:05:28.750 -> 30.50  30.50
18:05:30.736 -> Read it
18:05:30.736 -> 31.00  31.00
18:05:32.766 -> Read it
18:05:32.766 -> 31.00  31.56
18:05:34.791 -> Read it
18:05:34.791 -> 31.50  32.06
18:05:36.817 -> Read it
18:05:36.817 -> 32.00  32.50
18:05:38.803 -> Read it
18:05:38.803 -> 32.50  33.00
18:05:40.834 -> Read it
18:05:40.834 -> 32.50  33.44
18:05:42.855 -> Read it
18:05:42.855 -> 33.00  34.00
18:05:44.883 -> Read it
18:05:44.883 -> 33.50  34.50
18:05:46.877 -> Read it
 
#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);

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Valerman пишет:

Я delay(2000) еще в loop добавил. 

Блин, Вас кто-то просил? У Вас ошибка в loop, я хотел в этом убедиться и показать Вам, а своим делеем Вы её замаскировали.

Кроме того, я просил Вас добавить ещё одну печать (п. 1). Вы этого не сделали. Виноват. Заметил, что сделали. Это моя вина, я ошибся. Эта печать нужна в строке №40, простите

Вам нужна помощь? Так делайте что говорят! Давайте ещё раз, только точно, как я написал.

Valerman
Offline
Зарегистрирован: 06.01.2020

Да конечно нужна помощь. 

[spoiler]

22:26:31.666 -> 0.00  0.00
22:26:31.701 -> 0.00  0.00
22:26:31.701 -> 0.00  0.00
22:26:31.701 -> 0.00  0.00
22:26:31.736 -> Read it
22:26:31.736 -> 31.00  28.37
22:26:31.736 -> 31.00  28.37
22:26:31.771 -> 31.00  28.37
22:26:31.771 -> 31.00  28.37
22:26:31.805 -> 31.00  28.37
22:26:31.805 -> 31.00  28.37
22:26:31.839 -> 31.00  28.37
22:26:31.839 -> 31.00  28.37
22:26:31.872 -> 31.00  28.37
22:26:31.872 -> 31.00  28.37
22:26:31.872 -> 31.00  28.37
22:26:31.906 -> 31.00  28.37
22:26:31.906 -> 31.00  28.37
22:26:31.941 -> 31.00  28.37
22:26:31.941 -> 31.00  28.37
22:26:31.941 -> 31.00  28.37
22:26:31.941 -> 31.00  28.37
22:26:31.941 -> 31.00  28.37
22:26:31.975 -> 31.00  28.37
22:26:31.975 -> 31.00  28.37
22:26:32.008 -> 31.00  28.37
22:26:32.008 -> 31.00  28.37
22:26:32.042 -> 31.00  28.37
22:26:32.042 -> 31.00  28.37
22:26:32.075 -> 31.00  28.37
22:26:32.075 -> 31.00  28.37
22:26:32.075 -> 31.00  28.37
22:26:32.110 -> 31.00  28.37
22:26:32.110 -> 31.00  28.37
22:26:32.143 -> 31.00  28.37
22:26:32.143 -> 31.00  28.37
22:26:32.178 -> 31.00  28.37
22:26:32.178 -> 31.00  28.37
22:26:32.178 -> 31.00  28.37
22:26:32.211 -> 31.00  28.37
22:26:32.211 -> 31.00  28.37
22:26:32.245 -> 31.00  28.37
22:26:32.245 -> 31.00  28.37
22:26:32.279 -> 31.00  28.37
22:26:32.279 -> 31.00  28.37
22:26:32.312 -> 31.00  28.37
22:26:32.312 -> 31.00  28.37
22:26:32.312 -> 31.00  28.37
22:26:32.346 -> 31.00  28.37
22:26:32.346 -> 31.00  28.37
22:26:32.380 -> 31.00  28.37
22:26:32.380 -> 31.00  28.37
22:26:32.413 -> 31.00  28.37
22:26:32.413 -> 31.00  28.37
22:26:32.413 -> 31.00  28.37
22:26:32.448 -> 31.00  28.37
22:26:32.448 -> 31.00  28.37
22:26:32.482 -> 31.00  28.37
22:26:32.482 -> 31.00  28.37
22:26:32.515 -> 31.00  28.37
22:26:32.515 -> 31.00  28.37
22:26:32.548 -> 31.00  28.37
22:26:32.548 -> 31.00  28.37
22:26:32.548 -> 31.00  28.37
22:26:32.581 -> 31.00  28.37
22:26:32.581 -> 31.00  28.37
22:26:32.614 -> 31.00  28.37
22:26:32.614 -> 31.00  28.37
22:26:32.649 -> 31.00  28.37
22:26:32.649 -> 31.00  28.37
22:26:32.649 -> 31.00  28.37
22:26:32.684 -> 31.00  28.37
22:26:32.684 -> 31.00  28.37
22:26:32.717 -> 31.00  28.37
22:26:32.717 -> 31.00  28.37
22:26:32.752 -> 31.00  28.37
22:26:32.752 -> 31.00  28.37
22:26:32.787 -> 31.00  28.37
22:26:32.787 -> 31.00  28.37
22:26:32.787 -> 31.00  28.37
22:26:32.820 -> 31.00  28.37
22:26:32.820 -> 31.00  28.37
22:26:32.853 -> 31.00  28.37
22:26:32.853 -> 31.00  28.37
22:26:32.887 -> 31.00  28.37
22:26:32.887 -> 31.00  28.37
22:26:32.887 -> 31.00  28.37
22:26:32.922 -> 31.00  28.37
22:26:32.922 -> 31.00  28.37
22:26:32.955 -> 31.00  28.37
22:26:32.955 -> 31.00  28.37
22:26:32.990 -> 31.00  28.37
22:26:32.990 -> 31.00  28.37
22:26:33.023 -> 31.00  28.37
22:26:33.023 -> 31.00  28.37
22:26:33.023 -> 31.00  28.37
22:26:33.058 -> 31.00  28.37
22:26:33.058 -> 31.00  28.37
22:26:33.092 -> 31.00  28.37
22:26:33.092 -> 31.00  28.37
22:26:33.126 -> 31.00  28.37
22:26:33.126 -> 31.00  28.37
22:26:33.126 -> 31.00  28.37
22:26:33.159 -> 31.00  28.37
22:26:33.159 -> 31.00  28.37
22:26:33.192 -> 31.00  28.37
22:26:33.192 -> 31.00  28.37
22:26:33.226 -> 31.00  28.37
22:26:33.226 -> 31.00  28.37
22:26:33.260 -> 31.00  28.37
22:26:33.260 -> 31.00  28.37
22:26:33.260 -> 31.00  28.37
22:26:33.294 -> 31.00  28.37
22:26:33.294 -> 31.00  28.37
22:26:33.328 -> 31.00  28.37
22:26:33.328 -> 31.00  28.37
22:26:33.362 -> 31.00  28.37
22:26:33.362 -> 31.00  28.37
22:26:33.362 -> 31.00  28.37
22:26:33.397 -> 31.00  28.37
22:26:33.397 -> 31.00  28.37
22:26:33.430 -> 31.00  28.37
22:26:33.430 -> 31.00  28.37
22:26:33.463 -> 31.00  28.37
22:26:33.463 -> 31.00  28.37
22:26:33.496 -> 31.00  28.37
22:26:33.496 -> 31.00  28.37
22:26:33.496 -> 31.00  28.37
22:26:33.529 -> 31.00  28.37
22:26:33.529 -> 31.00  28.37
22:26:33.564 -> 31.00  28.37
22:26:33.564 -> 31.00  28.37
22:26:33.597 -> 31.00  28.37
22:26:33.597 -> 31.00  28.37
22:26:33.597 -> 31.00  28.37
22:26:33.632 -> 31.00  28.37
22:26:33.632 -> 31.00  28.37
22:26:33.667 -> 31.00  28.37
22:26:33.667 -> 31.00  28.37
22:26:33.700 -> 31.00  28.37
22:26:33.700 -> 31.00  28.37
22:26:33.734 -> 31.00  28.37
22:26:33.734 -> Read it
22:26:33.734 -> 31.50  28.87
22:26:33.767 -> 31.50  28.87
22:26:33.767 -> 31.50  28.87
[/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);

}

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вот и смотрите на свою печать. Вы видите сколько раз она печатает "между" реальными измерениями? Вы и раньше это видели, потому и поставили задержку. Только задержка эта маскирует проблему, а не решает.

Проблема же в том, что у Вас неверно написана логика. Смотрите на свой loop. Он тупо в цикле вызывает detectTemperature2, печатает и снова вызывает detectTemperature2, и так постоянно. Т.е. detectTemperature2 вызывается (судя по Вашей печати) каждые 40 мс.

И что же Вы делаете каждые 40 мс? Вы делаете reset и приказываете всем датчикам начать преобразование (строки №№ 26-28). Через 40 мс Вы снова делаете reset и приказываете всем датчикам начать преобразование, потом ещё и ещё. Потом, когда сработает условие в строке №29 Вы кидаетесь читать значение, хотя начать преобразование приказали только что! Получается, что вместо того, чтобы начать преобразование и спокойно ждать (не дёргая датчик), Вы дёргаете его каждые 40 мс, приказывая отресетится начать преобразование заново. Удивительно, что он у Вас хоть что-то показывает.

Эту логику надо переписывать. Так оно работать не должно и не будет. Вы должны запустить преобразование, выждать интервал и только после этого читать датчик. А не дергать его каждые 40мс приказами "ресет" - "начинай по новой".

Я понятно написал?

MaksVV
Offline
Зарегистрирован: 06.08.2015

С температурами связано несколько параметров - собственно само значение 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

 

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

Возможно, датчик стоял уже где- нибудь, и у него в eeprom записано, с каким разрешением считать температуру...