Это старая версия документа!


Эксперимент 41. Двухзонный термометр с LCD дисплеем

Теперь у нас есть опыт создания аналогового термометра с термистором в качестве датчика, и цифрового с датчиком DS18B20. Почему бы не объединить эти датчики, чтобы сделать двухзонный термометр. Учитывая исполнение датчиков, с помощью DS18B20 можно измерять температуру в комнате, а термистор в корпусе вывести на улицу, чтобы видеть на дисплее данные о температуре в комнате и на улице одновременно.

Схема эксперимента

Рисунок 1. Монтажная схема эксперимента

Программный код эксперимента

Exp41.ino
  1. #include <OneWire.h>
  2. #include <DallasTemperature.h>
  3. #include <LCDI2C_Multilingual.h>
  4.  
  5. #define ACD_PIN A0
  6. #define BUS_PIN 12
  7. #define DEFAULT_I2C_ADDR 0x3F // Или 0x27 в зависимости от твоей платы IoT
  8.  
  9. OneWire oneWire(BUS_PIN);
  10. DallasTemperature sensors(&oneWire);
  11. LCDI2C_Generic lcd(DEFAULT_I2C_ADDR, 16, 2);
  12.  
  13. const int Bcoef = 3950;
  14. const int R1 = 10000;
  15. const int Rtnom = 10000;
  16. const float T0 = 273.15;
  17.  
  18. void setup() {
  19. sensors.begin();
  20. lcd.init();
  21. lcd.setBacklight(0);
  22. }
  23.  
  24. void loop() {
  25. int value = analogRead(ACD_PIN);
  26. float R2 = (-R1 * value) / (value - 1023);
  27. float temp_outodor = 1 / (log(R2 / Rtnom) / Bcoef + 1/(25 + T0)) - T0;
  28.  
  29. sensors.requestTemperatures();
  30. float temp_inroom = sensors.getTempCByIndex(0);
  31.  
  32. lcd.clear();
  33. lcd.print("Outodor: ");
  34. lcd.println(temp_outodor, 2);
  35. lcd.print("In room: ");
  36. lcd.print(temp_inroom, 2);
  37. delay(1000);
  38. }

Код программы состоит из кода двух экспериментов, посвящённых термометру на термисторе и термометру на DS18B20.

Сначала подключаем необходимые библиотеки:

  1. #include <OneWire.h>
  2. #include <DallasTemperature.h>
  3. #include <LCDI2C_Multilingual.h>

Определяем константы, необходимые для вычисления температуры с помощью терморезистора (подробно разбиралось в Проекте 3. "Термометр").

  1. const int Bcoef = 3950;
  2. const int R1 = 10000;
  3. const int Rtnom = 10000;
  4. const float T0 = 273.15;

Создаем объекты АЦП, шины 1-Wire на выводе 12 и датчика DS18B20:

  1. adc = machine.ADC(0)
  2. ow = onewire.OneWire(Pin(12))
  3. ds = ds18x20.DS18X20(ow)

Определяем адрес контроллера LCD дисплея на шине I2C:

  1. DEFAULT_I2C_ADDR = 0x3F

Создаем объект шины I2C и настраиваем ее. Создаем объект LCD дисплея и настраиваем его. Включаем подсветку дисплея:

  1. i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000)
  2. lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)
  3. lcd.backlight_on()

В основном цикле программы мы получаем данные с АЦП, к которому подключен делитель напряжения с нижнем плече с термистором:

  1. value = adc.read()

Определяем сопротивление термистора, из которого вычисляем температуру (подробно рассматривалось в эксперименте 32). Округляем температуру до десятых (1 знак после десятичной точки) и сохраняем в переменной outodor_temp:

  1. R = (-R1 * value)/(value-1023)
  2. temp = 1 / (math.log(R / Rtnom) / Bcoef + 1/(25+T0)) -T0
  3. outodor_temp = round(temp,1)

Считываем температуру из датчика DS18B20, округляем температуру до десятых (1 знак после десятичной точки) и сохраняем в переменной inroom_temp:

  1. roms = ds.scan()
  2. ds.convert_temp()
  3. temp = ds.read_temp(roms[0])
  4. inroom_temp = round(temp,1)

!!!!!!!Выводим температуру в комнате и на улице в терминал. Перед выводом температур преобразовываем их из чисел в строки с помощью оператора str():

  1. print("Outodor: " + str(inroom_temp))
  2. print('In room: ' + str(outodor_temp))

Очищаем дисплей (при этом курсор дисплея перемещается в верхний левый угол), выводим строку с информацией о температуре на улице. Функция lcd.println() переводит курсор на следующую строку после вывода заданного текста.

  1. lcd.clear();
  2. lcd.print("Outodor: ");
  3. lcd.println(temp_outodor, 2);

Перемещаем курсор дисплея на нулевой (самый левый) символ второй строки и выводим информацию о температуре в комнате:

  1. lcd.print("In room: ");
  2. lcd.print(temp_inroom, 2);

Пауза на 1 секунду перед следующим измерением:

  1. delay(1000);