"Термометр для бани"

Рабочие проекты Ардуино
dok
Сообщения: 5
Зарегистрирован: 11 дек 2017, 21:46

"Термометр для бани"

Сообщение dok » 13 дек 2017, 21:34


Благодаря урокам Эдуарда создаю один из своих первых проектов на основе Ардуино.
Хочу родителям в деревню в баню термометр сделать на 7-ми сегментном индикаторе и трёх датчиках DS18B20. Плата: Ардуино Нано. Индикаторы подключены по схеме из уроков : // тип индикатора 1; выводы разрядов 5,4,3,2; выводы сегментов 6,7,8,9,10,11,12,13
Led4Digits disp(1, 5,4,3,2, 6,7,8,9,10,11,12,13);
. Датчики на выводах А0, А1, А2. На данный момент разработки проекта, следующая последовательность вывода: Отрицательные температуры всех трёх датчиков выводятся, как обычно, с минусом в старшем разряде. Положительная температура первого датчика индицируется с тремя горизонтальными полосками в старшем разряде. disp.digit[3] = 0x49; Сегменты A , G и D. Положительная температура второго датчика -- с двумя горизонтальными полосками. disp.digit[3] = 0x48; Сегменты G и D . Положительная температура третьего датчика с одной полоской -- горит нижний сегмент D disp.digit[3] = 0x08 .
Парилка, моечная и предбанник по очереди. Это чтобы как-то их отличать друг от друга. Была шальная мысль зажигать, как вариант, 3 отдельных светодиода напротив надписей "Парилка", "Моечная" , "Предбанник". Но плата Нано, места мало. Расхотелось в эту паутину проводов добавлять ещё 3 светодиода с резисторами. Остаётся некоторая "Некрасивость" в работе устройства, на которую поднимал Ирик в комментариях к 26-му уроку, а именно переход нулевой отметки. Не хотелось, конечно видеть "-00,2", но без нулей тоже как-то коряво смотрится. "- ,2". Народ, может кому пригодятся "мои хождения по мукам". Привожу код. Может, кто чего умного подскажет. Как разнообразить, улучшить.

Код: Выделить всё

// термометр, 3 датчикa DS18B20  plata Nano
#include <MsTimer2.h>
#include <Led4Digits.h>
#include <OneWire.h>

#define POWER_MODE  0 // режим питания, 0 - внешнее, 1 - паразитное

// тип индикатора 1; выводы разрядов 5,4,3,2; выводы сегментов 6,7,8,9,10,11,12,13
Led4Digits disp(1, 5,4,3,2, 6,7,8,9,10,11,12,13);

OneWire sensDs (14);  // датчик подключен к выводу 14 (A0)
OneWire sensDs2 (15);  // датчик подключен к выводу 15 (A1)
OneWire sensDs3 (16);  // датчик подключен к выводу 16 (A2)

byte bufData[9];  // буфер данных
byte bufData2[9];  // буфер данных 2
byte bufData3[9];  // буфер данных 3
float temperature;  // измеренная температура
float temperature2;  // измеренная температура 2
float temperature3;  // измеренная температура 3

void setup() {
  MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс
  MsTimer2::start();               // разрешаем прерывание по таймеру
  Serial.begin(9600); // инициализируем порт, скорость 9600 
}
void loop() {
  sensDs.reset();  // сброс шины
  sensDs.write(0xCC, POWER_MODE); // пропуск ROM
  sensDs.write(0x44, POWER_MODE); // инициализация измерения
  delay(900);  // пауза 0,9 сек
  sensDs.reset();  // сброс шины
  sensDs.write(0xCC, POWER_MODE); // пропуск ROM 
  sensDs.write(0xBE, POWER_MODE); // команда чтения памяти датчика 
  sensDs.read_bytes(bufData, 9);  // чтение памяти датчика, 9 байтов
   
  if ( OneWire::crc8(bufData, 8) == bufData[8] ) {  // проверка CRC
    // данные правильные
    temperature=  (float)((int)bufData[0] | (((int)bufData[1]) << 8)) * 0.0625 + 0.03125;

// вывод измеренной температуры на индикаторы
    if (temperature >= 0){
   
// температура положительная
   disp.print((int)(temperature * 10.), 4, 1);
   disp.digit[3] = 0x49; // индицируется с тремя горизонтальными полосками в старшем разряде
         }
    else {
      // температура отрицательная
      disp.print((int)(temperature * -1 * 10.), 3, 1);         
      disp.digit[3]= 0x40; } // отображается минус
      disp.digit[1] |= 0x80;  // зажечь точку второго разряда                 
     
    // передача температуры на компьютер
     Serial.print(" Температура 1  ");
    Serial.println(temperature);   
  }
  else { 
    // ошибка CRC, отображается ----
      disp.digit[0]= 0x40;
      disp.digit[1]= 0x40;
      disp.digit[2]= 0x40;
      disp.digit[3]= 0x40; }
 delay(2000);
  sensDs2.reset();  // сброс шины
  sensDs2.write(0xCC, POWER_MODE); // пропуск ROM
  sensDs2.write(0x44, POWER_MODE); // инициализация измерения
  delay(900);  // пауза 0,9 сек
  sensDs2.reset();  // сброс шины
  sensDs2.write(0xCC, POWER_MODE); // пропуск ROM 
  sensDs2.write(0xBE, POWER_MODE); // команда чтения памяти датчика 
  sensDs2.read_bytes(bufData2, 9);  // чтение памяти датчика, 9 байтов

  if ( OneWire::crc8(bufData2, 8) == bufData2[8] ) {  // проверка CRC
    // данные правильные
    temperature2=  (float)((int)bufData2[0] | (((int)bufData2[1]) << 8)) * 0.0625 + 0.03125;
 
    // вывод измеренной температуры на индикаторы
    if (temperature2 >= 0) {
      // температура положительная
      disp.print((int)(temperature2 * 10.), 4, 1);
      disp.digit[3] = 0x48;  //  индицируется с двумя горизонтальными полосками в старшем разряде     
    }
    else {
      // температура отрицательная
      disp.print((int)(temperature2 * -1 * 10.), 3, 1);         
      disp.digit[3]= 0x40;  // отображается минус
    }
    disp.digit[1] |= 0x80;  // зажечь точку второго разряда                 
       
    // передача температуры на компьютер
    Serial.print(" Температура 2  ");
    Serial.println(temperature2);   
  }
  else { 
    // ошибка CRC, отображается ----
      disp.digit[0]= 0x40;
      disp.digit[1]= 0x40;
      disp.digit[2]= 0x40;
      disp.digit[3]= 0x40;
       }
    delay(2000);
 {
  sensDs3.reset();  // сброс шины
  sensDs3.write(0xCC, POWER_MODE); // пропуск ROM
  sensDs3.write(0x44, POWER_MODE); // инициализация измерения
  delay(900);  // пауза 0,9 сек
  sensDs3.reset();  // сброс шины
  sensDs3.write(0xCC, POWER_MODE); // пропуск ROM 
  sensDs3.write(0xBE, POWER_MODE); // команда чтения памяти датчика 
  sensDs3.read_bytes(bufData3, 9);  // чтение памяти датчика, 9 байтов

  if ( OneWire::crc8(bufData3, 8) == bufData3[8] ) {  // проверка CRC
    // данные правильные
    temperature3=  (float)((int)bufData3[0] | (((int)bufData3[1]) << 8)) * 0.0625 + 0.03125;

    // вывод измеренной температуры на индикаторы
    if (temperature3 >= 0) {
      // температура положительная
      disp.print((int)(temperature3 * 10.), 4, 1);
      disp.digit[3] = 0x08;     // индицируется с одной горизонтальной полоской в старшем разряде   
    }
    else {
      // температура отрицательная
      disp.print((int)(temperature3 * -1 * 10.), 3, 1);         
      disp.digit[3]= 0x40;  // отображается минус
    }
    disp.digit[1] |= 0x80;  // зажечь точку второго разряда                 
         
    // передача температуры на компьютер
    Serial.print(" Температура 3  ");
    Serial.println(temperature3);   
  }
  else { 
    // ошибка CRC, отображается ----
      disp.digit[0]= 0x40;
      disp.digit[1]= 0x40;
      disp.digit[2]= 0x40;
      disp.digit[3]= 0x40; }
      delay(2000);
    }
  }
 
//-------------------------------------- обработчик прерывания 2 мс
void  timerInterrupt() {
  disp.regen(); // регенерация индикатора
}


Эдуард
Администратор
Сообщения: 484
Зарегистрирован: 30 окт 2016, 20:53

Re: "Термометр для бани"

Сообщение Эдуард » 13 дек 2017, 22:06

Здравствуйте!
Можно перед отображением температуры зажигать на индикаторах символическое название параметра.
Может лучше использовать жидкокристаллический (LCD) индикатор. На нем вывести все 3 температуры.
Можно добавить кнопку и переключать с помощь нее.
Использовать светодиоды тоже неплохая мысль.

В программе есть некоторая избыточность. Вы используете 3 программных блока для измерения 3 температур. Блоки работают по очереди. Непонятно зачем вы завели разные переменные для них.
byte bufData[9]; // буфер данных
byte bufData2[9]; // буфер данных 2
byte bufData3[9]; // буфер данных 3
float temperature; // измеренная температура
float temperature2; // измеренная температура 2
float temperature3; // измеренная температура 3

Достаточно в каждом блоке использовать:
byte bufData[9]; // буфер данных
float temperature; // измеренная температура

dok
Сообщения: 5
Зарегистрирован: 11 дек 2017, 21:46

Re: "Термометр для бани"

Сообщение dok » 14 дек 2017, 14:00

Спасибо за советы и поддержку. Убрал лишнее --- всё замечательно работает. Просто весь мой прежний опыт (ремонт радиотелефонов) в программировании сводился к прошивке программатором (Тритон) базы и трубок. Считываешь пару прошивок с рабочего аппарата -- заливаешь в клиентский. С паяльником тоже дружу. Но то, что вижу сейчас, идёт вразрез почти всему, что я знал раньше. Не надо что-то паять, травить платы и т. д. Изменил пару тройку строчек и всё ! Смотрю на всё это, как папуас на бусы. Фантастика! Бум дальше изучать.


Вернуться в «Проекты Ардуино»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей