Good afternoon, I wonder if you could help me. I have the code but the data from the sensors is not correct. Perhaps there are some errors, could you fix them?
I apologise for my inaccurate statement. I have the task of displaying data from three sensors on the screen. I've written a sketch, but it doesn't work correctly. That is, the data from two sensors (ds18b20, yl-69) is not displayed correctly. I think the problem is with the sketch. The data from sensor ds18b20 is constantly displayed differently, and partly depends on the data from sensor yl-69, although it should not. All sensors should work separately from each other, but give their data to the arduino
#include <DallasTemperature.h>
#include <OneWire.h>
#include <DS18B20.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
const uint8_t ds1Pin{7}; // DS18b20 будем подключать к пину D7
const uint32_t msRepTime {10000}; // DS18b20 будем опрашивать каждые 10 секунд (по факту каждые 11)
uint32_t msTemp {msRepTime}; // Объявляем счетчик для опроса DS18b20 и инициализируем его значением для моментального начала процедуры
const uint8_t simvol[8] = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000};
uint8_t ds1Qty {1}; // Количество датчиков DS18b20 на пине (не более 3-х). Если больше одного, значения будут усредняться
int8_t ds1Temp {0}; // Собственно, значение температуры по Цельсию от DS18b20
uint8_t ds1DS[3][8]; // Адреса положу пока здесь. Если кому не лень, их нужно убрать из глобальной ОВ, как и количество датчиков
const uint8_t DHTPin{8}; // DHT будем подключать к пину D8
float dhtTemp {0}; // DHT значение температуры
float dhtHum {0}; // DHT значение влажности
const uint32_t msDhtTime {5017}; // DHT будем опрашивать каждые 5+ секунд. "Кривое" значение, чтобы не пересекаться по времени с опросом DS
uint32_t msDht {msDhtTime}; // Объявляем счетчик для опроса DHT и инициализируем его значением для моментального начала процедуры
const uint8_t ylPin{14}; // YL будем подключать к пину A0(14). ВНИМАНИЕ: подключение аналогового выхода датчика!
uint16_t ylVal{0}; // Переменная для показаний датчика влажности YL
const uint32_t msYlTime {100}; // YL будем опрашивать каждые 0.1 секунд, чтобы МК хоть чем-то был занят в цикле))
uint32_t msYl {0}; // Объявляем счетчик для опроса YL-69
const uint32_t msPageExpo {5000}; // Устанавливаем по 5 секунд на отображение каждой страницы
uint32_t msPage {0}; // Объявили счетчик для экрана
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHTPin, DHT11);
OneWire oneWire(DS18B20);
void setup() {
Serial.begin(9600); // Скорость должна соответствовать настройкам монитора порта
lcd.init();
lcd.backlight();
dht.begin();
searchSensors(); // Запускаем первоначальный поиск датчиков DS18b20 на пине
}
void loop() {
if (millis() - msTemp > msRepTime) updateTemp(); // Опрашиваем температуру DS18b20 с частотой msRepTime
if (millis() - msDht > msDhtTime) runDht(); // Опрашиваем DHT
if (millis() - msYl > msYlTime) runYl(); // Опрашиваем YL-69
if (millis() - msPage > msPageExpo) updatePage(); // Листаем страницы
}
//************** Секция экранчег ****************************
void updatePage(){ // Листаем страницы на экранчике
static uint8_t page {0};
// Первая страница
if (page == 0){
lcd.setCursor(0,0);
lcd.print("temp water: ");
lcd.setCursor(0,1);
lcd.print((int8_t)ds1Temp);
lcd.setCursor(3,1);
lcd.print("C ");
msPage = millis();
page++;
return;
}
// Вторая страница
if (page == 1){
lcd.setCursor(0,0);
lcd.print("temp air: ");
lcd.setCursor(0,1);
lcd.print((int8_t)dhtTemp);
lcd.setCursor(2,1);
lcd.print("C ");
msPage = millis();
page++;
return;
}
// Третья страница
if (page == 2){
lcd.setCursor(0,0);
lcd.print("hum air: ");
lcd.setCursor(0,1);
lcd.print((uint8_t)dhtHum);
lcd.setCursor(2,1);
lcd.print("% ");
msPage = millis();
page++;
return;
}
// Последняя страница
if (page == 3){
lcd.setCursor(0,0);
lcd.print("hum earth: ");
lcd.setCursor(0,1);
lcd.print((uint16_t)ylVal);
lcd.setCursor(3,1);
lcd.print("% ");
msPage = millis();
page = 0;
return;
}
}
//************** Секция YL-69 ****************************
void runYl(void){
ylVal = analogRead(ylPin);; //Измеряем влажность. Маппинг пишем сами, если надо
msYl = millis();
}
//************** Секция DHT ****************************
void runDht(void){
dhtHum = dht.readHumidity(); //Измеряем влажность
dhtTemp = dht.readTemperature(); //Измеряем температуру
msDht = millis();
}
//************** Секция DS18b20 ****************************
void updateTemp(){ // Основная процедура обновления температурных данных со всех датчиков
static uint8_t stage {0};
// Первый этап. Отправка запросов на конвертацию
if (stage == 0){
if (ds1Qty) requestSensor(ds1Pin);
stage++;
msTemp = millis() - msRepTime + 800; // 0.75 секунды требуется датчику для осуществления конвертации на максимальном разрешении
return;
}
// Второй этап. Чтение показаний
if (stage == 1){
if (ds1Qty) readSensor(&ds1Temp, ds1Pin, ds1DS, ds1Qty);
msTemp = millis();
stage = 0;
return;
}
}
void readSensor(int8_t* t, uint8_t pin, void* buf, uint8_t qt){ // Чтение температуры с датчика ds18b20
OneWire ds(pin);
uint8_t addr[8];
uint8_t data[9];
float temp[3];
uint8_t qty {0};
for (uint8_t c {0}; c < qt; c++){
for(uint8_t i {0}; i<8 ;i++) addr[i] = *((uint8_t*)buf+c*8+i);
ds.reset(); ds.select(addr); ds.write(0xBE);
for (uint8_t d {0}; d<9; d++) data[d] = ds.read();
int16_t raw = (data[1] << 8) | data[0];
raw = raw & ~1;
temp[qty++] = raw / 16.0;
}
float tmp {0};
for (uint8_t i {0}; i<qty; i++) tmp+= temp[i];
*t = round(tmp/qty);
Serial.print("Температура пин "); Serial.print(pin); Serial.print(" : "); Serial.println(*t);
}
void requestSensor(uint8_t pin){ // Отправка запроса на конвертацию ds18b20
OneWire ds(pin);
ds.reset();
ds.skip();
ds.write(0x44,0);
}
void searchSensors(){ // Поиск датчиков на всех линиях
ds1Qty = src(ds1DS, ds1Pin);
}
uint8_t src(void * adr, uint8_t pin){ // Вспомогательная функция для поиска на одной шине. Возвращает количество найденных датчиков
if (pin == 0) return 0;
OneWire ds(pin);
uint8_t newAddr[8]{0};
uint8_t count {0};
ds.reset_search();
delay(5);
while (ds.search(newAddr) && count <3){
if (ds.crc8(newAddr, 7) == newAddr[7]){
for (uint8_t i{0}; i<8; i++) *((uint8_t*)adr + count * 8 + i) = newAddr[i];
count++;
}
}
return count;
}
do not put in comments