Senior Member
Регистрация: 20.01.2013
Адрес: Уфа
Сообщений: 444
Вес репутации: 800
|
Re: Акваконтроллер
От таймеров отказался, с этим чипом мало работал - много подводных камней надо изучать, сделал на костылях как-то так, попробуй изменять значения интервала до приемлимого тобой
PHP код:
#include <Wire.h>//Подключаем библиотеку для использования I2C интерфейса с модулем RTC
#include "RTClib.h"//Подключаем библиотеку для использования модуля часов реального времени RTC
#include <OneWire.h>
#include <DallasTemperature.h>
#include "LiquidCrystal.h" // библиотека экрана
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
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(16, 2); // запускаем библиотеку экрана
pinMode(40, OUTPUT); // Включаем кипятильник
pinMode(41, OUTPUT);
digitalWrite(40, Relay_On);
digitalWrite(41, Relay_On);
Wire.begin(); //Инициируем I2C интерфейс
RTC.begin(); //Инициирум RTC модуль
analogWrite(PWM_LW_PIN, PWM_LW_MIN); //Пишем в порт минимальное значение
analogWrite(PWM_LR_PIN, PWM_LR_MIN);
analogWrite(PWM_LB_PIN, PWM_LB_MIN);
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
RTC.adjust(DateTime(2014, 7, 12, 22, 48, 1));
}//RTC.adjust(DateTime(__DATE__, __TIME__));
} // КОНЕЦ ИНИЦИАЛИЗАЦИИ
//********************************************************************************************
void loop() // ПРОГРАММЫй безусловный ЦИКЛ
{
analogWrite(10, 100);
lcd.setCursor(0, 1);
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_PIN, pwm_LW);//Пишем в порт вычисленное значение
analogWrite(PWM_LR_PIN, pwm_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_PIN, pwm_LB); //Пишем в порт вычисленное значение
}
byte i;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
// Ищем алрес датчика
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
// Проверяем не было ли помех при передаче
if (OneWire::crc8(addr, 7) != 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(0x44, 1); // Производим замер, в режиме паразитного питания
delay(750);
ds.reset();
ds.select(addr);
ds.write(0xBE); // Считываем оперативную память датчика
for ( i = 0; i < 9; i++) {
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(0, 0);
lcd.print("T=");
lcd.setCursor(2, 0);
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(15, 1);
lcd.print("A");
// Если температура достигает 28,3 (с погрешностью), отключаем кипятильник Н1
if (celsius > 28.3)
{
digitalWrite(40, Relay_Off);
lcd.setCursor(0, 1);
lcd.print("H1-Off");
}
// Если температура достигает 28,5 (с погрешностью), отключаем кипятильник Н2
if (celsius > 28.5)
{
digitalWrite(41, Relay_Off);
lcd.setCursor(7, 1);
lcd.print("H2-Off");
}
// Если температура падает до 28 (с погрешностью), включаем оба кипятильника
if (celsius < 28.0)
{
digitalWrite(40, Relay_On);
lcd.setCursor(0, 1);
lcd.print("H1-On ");
digitalWrite(41, Relay_On);
lcd.setCursor(7, 1);
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(41, Relay_Off);
lcd.setCursor(7, 1);
lcd.print("H2-Off");
break;
}
case btnLEFT:
{
digitalWrite(41, Relay_On);
lcd.setCursor(7, 1);
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(15, 1);
lcd.print("A");}
else
{reg=1;
lcd.setCursor(15, 1);
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_PIN, valW+1); };
if (valR<PWM_LR_MAX) {analogWrite(PWM_LR_PIN, valR+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_PIN, valW-1); };
if (valR>PWM_LR_MIN) {analogWrite(PWM_LR_PIN, valR-1); };
ti=millis();
if(valW-1<=PWM_LW_MIN && valR-1<=PWM_LR_MIN){LUD=0;};
};
};
};
}
//------------Конец ЦИКЛА--------------------------
|