управление циркуляционным насосом

electronic.24
Offline
Зарегистрирован: 12.09.2014
 Здравствуйте!
Проблемма заключается в следующем: 
При влючении, после приветствия контроллер определяет температуру равной 85.0 градусов (датчик 18B20), и включает насос на  13ом выводе.  Каким образом можно исправить? И еще буду признателен за конструктивную критику и советы вообщем по коду.

     <span style="font-family: Verdana, Geneva, Arial, sans-serif; font-size: 12px; line-height: 1.5em;">// Подключаем библиотеки</span>
#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x20, 16, 2); // Задаем адрес, а так-же размерность дисплея.
OneWire ds(10);  // датчик температуры на выводе 10
unsigned long INTERVAL = 10000; // на такое кол-во милисекунд будем включать насос
 
 
void setup()
{
#define vcc 9
#define gnd 11
  pinMode(vcc, OUTPUT); //удобство подключения
  pinMode(gnd, OUTPUT);
  digitalWrite(vcc, HIGH);
  digitalWrite(gnd, LOW);
  lcd.init();
  lcd.backlight();
  lcd.printstr("Termostat");  //приветствие
#define nasos 13
  pinMode(nasos, OUTPUT);
  delay(2000);
  lcd.clear();
}
 
void loop(void) {
 
  byte i;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;
 
  // Ищем алрес датчика
  if ( !ds.search(addr))
  {
    ds.reset_search();
    delay(250);
    return;
  }
  // Проверяем не было ли помех при передаче
  if (OneWire::crc8(addr, 7) != addr[7])
  {
 
    return;
  }
  /*   // Определяем серию датчика
   switch (addr[0]) {
     case 0x10:
       lcd.println("  Chip = DS18S20");
       type_s = 1;
       break;
     case 0x28:
       lcd.println("  Chip = DS18B20");   
       type_s = 0;
       break;
     case 0x22:
       lcd.println("  Chip = DS1822");
       type_s = 0;
       break;
     default:
       lcd.println("error device DS18B20.");
       return;
 
   }
   */
 
  ds.reset();
  ds.select(addr);       // Выбираем адрес
  ds.write(0x44);     // Производим замер, в режиме паразитного питания
  delay(100);
 
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);         // Считываем оперативную память датчика
 
  for ( i = 0; i < 9; i++) {
    data[i] = ds.read();  // Заполняем массив считанными данными
  }
 
  // Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число
  int16_t raw = (data[1] << 8) | data[0];
  // Переводим температуру в шкалы по Цельсию и Фаренгейту
  if (type_s)
  {
    raw = raw << 3;
  }
  if (data[7] == 0x10)
  {
    raw = (raw & 0xFFF0) + 12 - data[6];
  } else {
    byte cfg =  (data[4] & 0x60);
    if (cfg == 0x00)
      raw = raw << 3;
    else if  (cfg == 0x20)
      raw = raw << 2;
    else if  (cfg == 0x40) \
      raw = raw << 1;
  }
  celsius =  (float)raw / 16.0;   //выводим показания
  lcd.setCursor(0, 0); 
  lcd.print("Temp = ");
  lcd.print(celsius, 1);
  lcd.print(" C, ");
 
 
  if (celsius > 30){
                     digitalWrite(nasos, HIGH);  //включаем насос
                     lcd.setCursor(0, 1);
                      lcd.print("Nasos  ON");
                    } 
    static unsigned long previousMillis = 0;        
    //проверяем не прошел ли нужный интервал, если прошел то
    if (millis()- previousMillis > INTERVAL) {
 
      previousMillis = millis();  // сохраняем время последнего переключения
    
     if ((celsius < 28)){
                        digitalWrite(nasos, LOW);   //отключаем насос
                        lcd.setCursor(0,1);
                        lcd.print("Nasos OFF");
                       }
  
 }
 
}
leshak
Offline
Зарегистрирован: 29.09.2011

>При влючении, после приветствия контроллер определяет температуру равной 85.0 градусов

Смотрите даташит на свой датчик.  85-т, это "особая температура". Можно воспринимать ее как "сигнал ошибки". По какой-то причине он не смог выполнить замер. Слишком часто опрашиваете его, или питания ему не хватает, или дефектный....

И еще.. поищите библиотечку типа DallasTemperatureControl с ней пользоватся датчиком - гораздо проще.

electronic.24
Offline
Зарегистрирован: 12.09.2014

Еще вопрос эта функция  if (millis()- previousMillis > INTERVAL) previousMillis = millis();

будет корректно работать пока значение INTERVAL будет меньше беззнакового четырехбайтового значения 4294967295 я правильно понял?

  

    
electronic.24
Offline
Зарегистрирован: 12.09.2014

Действительно при разрешении в 12 бит в даташите указано 750 милисекунд. 

ds.reset();
ds.select(addr);       // Выбираем адрес
ds.write(0x44);     // Производим замер, в режиме паразитного питания

 

delay(750);
//решило проблему
 
leshak
Offline
Зарегистрирован: 29.09.2011

electronic.24 пишет:

Еще вопрос эта функция  if (millis()- previousMillis > INTERVAL) previousMillis = millis();

будет корректно работать пока значение INTERVAL будет меньше беззнакового четырехбайтового значения 4294967295 я правильно понял?

Да. Должно.

Хотя, если честно никогда не размышлял над тем что будет если брать INTERVAL близким к верхней границе.
Как правило он секунды, часы... максимум пара дней. 4294967295 - это чуть больше 49-ти дней.

electronic.24
Offline
Зарегистрирован: 12.09.2014

Благодарю за подсказки! 

А пока поразбираюсь с новой библиотекой.