Форум обсуждения систем  

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Сделай сам

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.04.2014, 13:34   #51
kirex
Member
 
Регистрация: 24.03.2014
Сообщений: 38
Вес репутации: 0
kirex is an unknown quantity at this point
По умолчанию Re: Акваконтроллер

Цитата:
Сообщение от Bulatovor Посмотреть сообщение
От таймеров отказался, с этим чипом мало работал - много подводных камней надо изучать, сделал на костылях как-то так, попробуй изменять значения интервала до приемлимого тобой
PHP код:
#include <Wire.h>//Подключаем библиотеку для использования I2C интерфейса с модулем RTC 
#include "RTClib.h"//Подключаем библиотеку для использования модуля часов реального времени RTC

#include <OneWire.h>
#include <DallasTemperature.h>

#include "LiquidCrystal.h" // библиотека экрана
LiquidCrystal lcd(894567);

OneWire  ds(53);  // Подключаем датчик к 53 цифровому пину

int lcd_key     0;
int adc_key_in  0;
int reg=0;// вводим флаг для автоматического (при значении-0) или ручного регулирования -1

#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
 
adc_key_in analogRead(0);      // read the value from the sensor 
 // my buttons when read are centered at these valies: 0, 142, 328, 504, 741
 // we add approx 50 to those values and check to see if we are close
 
if (adc_key_in 1000) return btnNONE// We make this the 1st option for speed reasons since it will be the most likely result

 
if (adc_key_in 50)   return btnRIGHT;  
 if (
adc_key_in 200)  return btnUP
 if (
adc_key_in 400)  return btnDOWN
 if (
adc_key_in 600)  return btnLEFT
 if (
adc_key_in 850)  return btnSELECT;  
 return 
btnNONE;  // when all others fail, return this...
}


#define PWM_LW_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LW_MAX 128//Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LW_PIN 11 //Пин порта, где будет ШИМ LW

#define PWM_LR_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LR_MAX 200//Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LR_PIN 3 //Пин порта, где будет ШИМ LR

#define PWM_LB_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LB_MAX 235 //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LB_PIN 12 //Пин порта, где будет ШИМ LB

#define mn 60UL  //Дополнительные константы для удобства
#define hr 3600UL //Отражают соответствующие количества секунд 
#define d 86400UL

// Переменные для плавного ручного регулирования света
long ti=0// время последнего изменения яркости
int tp=100;// период изменения ярокости на одно значение в миллисекундах
unsigned long LUD=0;// флаг изменения яркости: 0 -не менять, 1 увеличить, 2 уменьшить

int Relay_Off HIGH;
int Relay_On LOW;

RTC_DS1307 RTC;          

long sunrise_start 17*hr+00*mn//Начало восхода в 9 - 45 
long sunrise_duration 3*mn;  //Длительность восхода 30 минут     
long sunset_start 22*hr+00*mn//начало заката в 21-15
long sunset_duration 3*mn//Длительность заката 30 минут 
long moonrise_start 22*hr+00*mn ;//Начало луны в 9 - 45
long moonrise_duration 3*mn;//Длительность восхода
long moonset_start 23*hr+00*mn;//Конец луны в 11
long moonset_duration 3*mn//Длительность заката луны
//********************************************************************************************
void setup(){

Serial.begin(9600);
     
lcd.begin(162); // запускаем библиотеку экрана
  
pinMode(40OUTPUT);  // Включаем кипятильник
  
pinMode(41OUTPUT);
  
digitalWrite(40Relay_On);  
  
digitalWrite(41Relay_On);
  
Wire.begin(); //Инициируем I2C интерфейс
  
RTC.begin();  //Инициирум RTC модуль
  
analogWrite(PWM_LW_PINPWM_LW_MIN); //Пишем в порт минимальное значение 
  
analogWrite(PWM_LR_PINPWM_LR_MIN); 
  
analogWrite(PWM_LB_PINPWM_LB_MIN);
  if (! 
RTC.isrunning()) {
           
Serial.println("RTC is NOT running!");
           
RTC.adjust(DateTime(201471222481));
           }
//RTC.adjust(DateTime(__DATE__, __TIME__));
}   // КОНЕЦ ИНИЦИАЛИЗАЦИИ

//********************************************************************************************
void loop() // ПРОГРАММЫй безусловный ЦИКЛ 
{
  
analogWrite(10100);
  
lcd.setCursor(01);
    
long pwm_LW;
   
long pwm_LR;
  
long pwm_LB
    
DateTime myTime RTC.now(); //Читаем данные времени из RTC при каждом выполнении цикла
    
long Day_time myTime.unixtime() % 86400//сохраняем в переменную - время в формате UNIX
 
lcd.setCursor(11,0);
 if(
myTime.hour()<10)lcd.print(0);
 
lcd.print(myTime.hour(),DEC);
 
lcd.print(":"); 
 if(
myTime.minute()<10)lcd.print(0);
 
lcd.print(myTime.minute(),DEC);

if (
reg==0){
//*********************************************************************************************
//           обработка интервала до восхода и после заката
//*********************************************************************************************
    
if ((Day_time<sunrise_start) ||//Если с начала суток меньше чем начало восхода 
        
(Day_time>=sunset_start+sunset_duration)) { //Или больше чем начало заката + длительность
                  
pwm_LW PWM_LW_MIN//Величина для записи в порт равна минимуму  
                  
pwm_LR PWM_LR_MIN;

//*********************************************************************************************
//           обработка интервала восхода 
//*********************************************************************************************
    
}else if ((Day_time>=sunrise_start) && //Если с начала суток больше чем начало восхода
              
(Day_time<sunrise_start+sunrise_duration)){ //И меньше чем начало восхода + длительность 

                  
pwm_LW =  ((Day_time sunrise_start)*(PWM_LW_MAX-PWM_LW_MIN)) / sunrise_duration;   //Вычисляем для рассвета величину для записи в порт ШИМ
                  
pwm_LR =  ((Day_time sunrise_start)*(PWM_LR_MAX-PWM_LR_MIN)) / sunrise_duration;

//*********************************************************************************************
//           обработка интервала заката 
//*********************************************************************************************
    
}else if ((Day_time>=sunset_start) && //Если  начала суток больше чем начало заката и меньше чем  
              
(Day_time<sunset_start+sunset_duration)){//начало заката плюс длительность

                  
pwm_LW = ((sunset_start+sunset_duration Day_time)*(PWM_LW_MAX-PWM_LW_MIN)) / sunrise_duration;    //Вычисляем для заката величину для записи в порт ШИМ
                  
pwm_LR = ((sunset_start+sunset_duration Day_time)*(PWM_LR_MAX-PWM_LR_MIN)) / sunrise_duration;
 
//********************************************************************************************
//           обработка интервала от конца рассвета и до начала заката,
//           когда свет должен быть включен на максимальную яркость 
//********************************************************************************************
    
}else {
                  
pwm_LW PWM_LW_MAX//Устанавливаем максимальную величину для записи в порт ШИМ 
                  
pwm_LR PWM_LR_MAX;
    }
    
    
analogWrite(PWM_LW_PINpwm_LW);//Пишем в порт вычисленное значение      
    
analogWrite(PWM_LR_PINpwm_LR);    
   
  
//           обработка интервала до восхода луны и после заката
//*********************************************************************************************
    
if ((Day_time<moonrise_start) || //Если с начала суток меньше чем начало восхода 
        
(Day_time>=moonset_start+moonset_duration)) {//Или больше чем начало заката + длительность
                  
pwm_LB PWM_LB_MIN//Величина для записи в порт равна минимуму  

//*********************************************************************************************
//           обработка интервала восхода луны
//*********************************************************************************************
    
}else if ((Day_time>=moonrise_start) &&//Если с начала суток больше чем начало восхода
              
(Day_time<moonrise_start+moonrise_duration)){ //И меньше чем начало восхода + длительность 

                  
pwm_LB =  ((Day_time moonrise_start)*(PWM_LB_MAX-PWM_LB_MIN)) / moonrise_duration//Вычисляем для рассвета величину для записи в порт ШИМ

//*********************************************************************************************
//           обработка интервала заката луны
//*********************************************************************************************
    
}else if ((Day_time>=moonset_start) &&  //Если  начала суток больше чем начало заката и меньше чем  
              
(Day_time<moonset_start+moonset_duration)){//начало заката плюс длительность

                  
pwm_LB = ((moonset_start+moonset_duration Day_time)*(PWM_LB_MAX-PWM_LB_MIN)) / moonrise_duration;    //Вычисляем для заката величину для записи в порт ШИМ
 
//********************************************************************************************
//           обработка интервала от конца рассвета и до начала заката луны,
//           когда свет должен быть включен на максимальную яркость 
//********************************************************************************************
    
}else {
                  
pwm_LB PWM_LB_MAX;  //Устанавливаем максимальную величину для записи в порт ШИМ 
    
}
    
    
analogWrite(PWM_LB_PINpwm_LB); //Пишем в порт вычисленное значение 
  
}
  
byte i;
  
byte type_s;
  
byte data[12];
  
byte addr[8];
  
float celsiusfahrenheit;
  
  
// Ищем алрес датчика
  
if ( !ds.search(addr)) {
    
Serial.println("No more addresses.");
    
Serial.println();
    
ds.reset_search();
    
delay(250);
    return;
  }

  
// Проверяем не было ли помех при передаче
  
if (OneWire::crc8(addr7) != addr[7]) {
      
Serial.println("CRC is not valid!");
      return;
  }
  
Serial.println();
 
  
// Определяем серию датчика
  
switch (addr[0]) {
    case 
0x10:
      
Serial.println("  Chip = DS18S20");  
      
type_s 1;
      break;
    case 
0x28:
      
Serial.println("  Chip = DS18B20");
      
type_s 0;
      break;
    case 
0x22:
      
Serial.println("  Chip = DS1822");
      
type_s 0;
      break;
    default:
      
Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  
ds.reset();            
  
ds.select(addr);       // Выбираем адрес
  
ds.write(0x441);     // Производим замер, в режиме паразитного питания
  
delay(750);    
  
  
ds.reset();
  
ds.select(addr);    
  
ds.write(0xBE);         // Считываем оперативную память датчика

  
for ( 09i++) {           
    
data[i] = ds.read();  // Заполняем массив считанными данными
  
}

  
// Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число
  
unsigned int 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(00);
  
lcd.print("T=");
  
lcd.setCursor(20);
  
lcd.print(celsius);
  
  
delay (10);
  
  
celsius =  (float)raw 16.0;
  
fahrenheit celsius 1.8 32.0;
  
Serial.print("Temp = ");
  
Serial.print(celsius);
  
Serial.print(" C, ");
  
Serial.print(fahrenheit);
  
Serial.println(" F");

  if (
reg==0){ // Если регулирование автоматическое -регулируем по температуре
  
lcd.setCursor(151);
  
lcd.print("A");
  
  
// Если температура достигает 28,3 (с погрешностью), отключаем кипятильник Н1
  
if (celsius 28.3)
  {
  
digitalWrite(40Relay_Off); 
  
lcd.setCursor(01);
  
lcd.print("H1-Off");   
  }
  
// Если температура достигает 28,5 (с погрешностью), отключаем кипятильник Н2
  
if (celsius 28.5)
  {
     
digitalWrite(41Relay_Off); 
  
lcd.setCursor(71);
  
lcd.print("H2-Off");
  }
  
// Если температура падает до 28 (с погрешностью), включаем оба кипятильника
  
if (celsius 28.0)
  {
     
digitalWrite(40Relay_On); 
  
lcd.setCursor(01);
  
lcd.print("H1-On ");
     
digitalWrite(41Relay_On); 
  
lcd.setCursor(71);
  
lcd.print("H2-On ");
  }
 }
lcd_key read_LCD_buttons();  // read the buttons

switch (lcd_key)               // depending on which button was pushed, we perform an action
 
{
   case 
btnRIGHT:
     {
     
digitalWrite(41Relay_Off); 
     
lcd.setCursor(71);
     
lcd.print("H2-Off");
      break;
     }
   case 
btnLEFT:
    {
      
digitalWrite(41Relay_On); 
     
lcd.setCursor(71);
     
lcd.print("H2-On ");
      break;
     }
   case 
btnUP:
    {
        
LUD=1;
        
ti=millis();
     break;
     }
   case 
btnDOWN:
    {
        
LUD=2;
        
ti=millis();
     break;
     }
     case 
btnSELECT:
     { 
     if(
reg==1)
   {
reg=0;
   
lcd.setCursor(151);
  
lcd.print("A");}
   else 
   {
reg=1;
   
lcd.setCursor(151);
  
lcd.print("M");}
     break;
     }
     case 
btnNONE
     {  
     break; 
     } 
   }

   
// Подпрограмма плавного включения и гашения ламп в ручном режиме

   
if (reg==1)// если режим ручной
   
{if(LUD==1)// если плавное включение света
       
{
           if(
millis()-ti>tp)
           {
int valW analogRead(PWM_LW_PIN);
            
int valR analogRead(PWM_LR_PIN);
            if (
valW<PWM_LW_MAX) {analogWrite(PWM_LW_PINvalW+1); };
            if (
valR<PWM_LR_MAX) {analogWrite(PWM_LR_PINvalR+1); };
            
ti=millis();
            if(
valW+1>=PWM_LW_MAX && valR+1>=PWM_LR_MAX){LUD=0;}; 
           };
       };
    if(
LUD==2)// если плавное включение света
       
{
           if(
millis()-ti>tp)
           {
int valW analogRead(PWM_LW_PIN);
            
int valR analogRead(PWM_LR_PIN);
            if (
valW>PWM_LW_MIN) {analogWrite(PWM_LW_PINvalW-1); };
            if (
valR>PWM_LR_MIN) {analogWrite(PWM_LR_PINvalR-1); };
            
ti=millis();
            if(
valW-1<=PWM_LW_MIN && valR-1<=PWM_LR_MIN){LUD=0;}; 
           };
       };
    };
  

//------------Конец ЦИКЛА-------------------------- 
Спасибо, попробовал.

При нажатии кнопки UP ничего не происходит. При нажатии DOWN Свет включается, но както не плавно.

Последний раз редактировалось kirex; 01.04.2014 в 14:21.
kirex вне форума   Ответить с цитированием
Старый 02.04.2014, 04:37   #52
kirex
Member
 
Регистрация: 24.03.2014
Сообщений: 38
Вес репутации: 0
kirex is an unknown quantity at this point
По умолчанию Re: Акваконтроллер

Неужто никак ?
kirex вне форума   Ответить с цитированием
Старый 02.04.2014, 09:25   #53
Bulatovor
Senior Member
 
Регистрация: 20.01.2013
Адрес: Уфа
Сообщений: 444
Вес репутации: 799
Bulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond reputeBulatovor has a reputation beyond repute
По умолчанию Re: Акваконтроллер

чуть попозже, все времени нет пока разобраться
Bulatovor вне форума   Ответить с цитированием
Старый 17.04.2014, 16:28   #54
kirex
Member
 
Регистрация: 24.03.2014
Сообщений: 38
Вес репутации: 0
kirex is an unknown quantity at this point
По умолчанию Re: Акваконтроллер

Собранный контроллер работает без проблем уже 3-ю неделю. Я всем доволен, единственное есть один нюанс.
Температура на дисплей выводится в виде 28,85
т.е. два знака после запятой. Проблема в том, что через некоторое время появляется 3-й знак, а потом и 4-й.
И ещё иногда изредка реле срабатывают раньше заданной температуры. Задано отключение Н1 при темп. 28,8 и Н2 при 29,0, а отключается Н1 при 28,7 и Н2 при 28,8. Может проблема с датчиком, может не совсем герметичен?
Заранее благодарен.

Последний раз редактировалось kirex; 27.04.2014 в 18:39.
kirex вне форума   Ответить с цитированием
Старый 15.05.2014, 09:01   #55
kirex
Member
 
Регистрация: 24.03.2014
Сообщений: 38
Вес репутации: 0
kirex is an unknown quantity at this point
По умолчанию Re: Акваконтроллер

Всё-таки проблема была с самим датчиком, он был не герметичен. Сделал сам другой датчик из антенной трубки и все проблемы исчезли. Сегодня уже 5-й день в работе, левые цифры не появляются и реле срабатывает как положено.
Теперь прошу помощи по поводу света. Как сделать в ручном режиме включение и выключение света плавным для обоих каналов (LW и LR), чтобы яркость для каждого канала былы как в автоматичеком режиме.
Вот кусок кода:
Цитата:
case btnUP:
{
lcd.setCursor(9, 0);
lcd.print("L");
for(int fadeValue = 0 ; fadeValue <= PWM_LW_MAX; fadeValue +=1)
{
analogWrite(PWM_LW_PIN, fadeValue);
analogWrite(PWM_LR_PIN, PWM_LR_MAX);
delay(250);
}
break;
}
case btnDOWN:
{
lcd.setCursor(9, 0);
lcd.print("0");
for(int fadeValue = PWM_LW_MAX ; fadeValue >= 0; fadeValue -=1)
{
analogWrite(PWM_LR_PIN, 0);
analogWrite(PWM_LW_PIN, fadeValue);
delay(150);
}
break;
}
kirex вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 6 (пользователей: 0 , гостей: 6)
 
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 12:01. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика