// Датчик освещения на ATtiny45
// 16.09.2018
// Roman Kotelnirov
#include // Библиотека работы с EEPROM-памятью
#include // Библиотека защиты от дребезга
#define SWITCH0_PIN 0 //Кнопка выбора порога включения (при отключенном искуственном освещения)
#define SWITCH1_PIN 1 //Кнопка выбора порога отключения (при включенном искуственном освещении))
#define LDR_PIN 3 //Фоторезистор
#define REL_PIN 4 //Реле
#define POROG0_EM 1 //Адрес памяти, где будет хранится младший байт порога 0, соответственно старший байт +1
#define POROG1_EM 3 //Адрес памяти, где будет хранится младший байт порога 1, соответственно старший байт +1
int porog0; //Порог включения
int porog1; //Порог отключения
int d=50; // Защита от "дребезга"
bool threshold = false; // Флаг наличия темноты (если true, то темно и нужно включать свет)
int lightness;
Bounce b0 = Bounce(); // Объекты работы с кнопкой (для процедуры защиты от дребезга)
Bounce b1 = Bounce(); // Объекты работы с кнопкой (для процедуры защиты от дребезга)
void setup() {
// Определяем назначение выходов
pinMode(SWITCH0_PIN, INPUT);
pinMode(SWITCH1_PIN, INPUT);
pinMode(LDR_PIN, INPUT);
pinMode(REL_PIN, OUTPUT);
b0.attach(SWITCH0_PIN); // объект Bounce будет слушать кнопку на пине switchPin
b0.interval(10); // устанавливаем время задержки в [мс]
b1.attach(SWITCH1_PIN); // объект Bounce будет слушать кнопку на пине switchPin
b1.interval(10); // устанавливаем время задержки в [мс]
porog0 = (EEPROM.read(POROG0_EM+1) << 8 | EEPROM.read(POROG0_EM));//Считываем значение порога отключения (два байта, старший и младший)
porog1 = (EEPROM.read(POROG1_EM+1) << 8 | EEPROM.read(POROG1_EM));// Считываем значение порога включения (два байта, старший и младший)
mignled (3); //Мигнуть для наглядности 3 раза
}
void loop() {
if (b0.update() && b0.read() == 1) { // Если было нажатие кнопки 0 (порог включения)
digitalWrite(REL_PIN,LOW); // Замер должен быть при отключенном свете (так как порог будет использоваться для включения)
delay(1000); // Подождем когда утихнут переходные процессы (для большинства систем не обязательно)
porog0 = analogRead(LDR_PIN); // Устанавливаем порог включения (при отключенном свете!)
EEPROM.write(POROG0_EM, lowByte(porog0)); //Записываем младший байт значения порога включеня
EEPROM.write(POROG0_EM + 1, highByte(porog0)); //Записываем младший байт значения порога включени
// Проверяем, чтобы сразу не отключилось
digitalWrite(REL_PIN,HIGH); // Замер должен быть при включенном свете
delay(1000);
lightness = analogRead(LDR_PIN); // Считываем значение освещенности.
if (porog1 < lightness+d); { // Проверяем, требуется ли корректировка верхнего порога
porog1 = lightness+d; // Корректируем
if (porog1>1023) porog1=1023; // Защита от переполнения
EEPROM.write(POROG1_EM, lowByte(porog1)); //Записываем младший байт значение верхнего отключения
EEPROM.write(POROG1_EM + 1, highByte(porog1)); //Записываем старший байт значение верхнего отключения
}
mignled (1);
threshold = true;
}
if (b1.update() && b1.read() == 1) { // Если было нажатие кнопки 1 (порог отключения)
digitalWrite(REL_PIN,HIGH); // Замер должен быть при включенном свете (так как порог будет использоваться для отключения)
delay(1000);
porog1 = analogRead(LDR_PIN); // Считываем значение освещенности.
EEPROM.write(POROG1_EM, lowByte(porog1)); //Записываем младший байт значение верхнего порога
EEPROM.write(POROG1_EM + 1, highByte(porog1)); //Записываем старший байт значение верхнего порога
digitalWrite(REL_PIN,LOW); // ну и отключаем свет
lightness = analogRead(LDR_PIN); // Считываем значение освещенности
if (porog0 > lightness-d); { // Проверяем, требуется ли корректировка нижнего порога
porog0 = lightness-d;
if (lightness<0) porog0=0; // Если да, то проверяем можно ли добавить запасс
EEPROM.write(POROG0_EM, lowByte(porog0)); //Записываем младший байт значения порога включеня
EEPROM.write(POROG0_EM + 1, highByte(porog0)); //Записываем младший байт значения порога включени
}
mignled (3);
threshold = false;
}
lightness = analogRead(LDR_PIN); // Считываем значение освещенности
if (threshold) { //Свет включен (режим "темно")
if (lightness > porog1) { // Если текущий режим "темно", т.е. горит искуственное освещение и общая освещенность стала выше верхнего порога,
threshold = false; // то отменяем режим "темно",
digitalWrite(REL_PIN, LOW); // и отключим свет
}
}
else { //Свет отключен режим "светло")
if (lightness < porog0) { // Если текущий режим не "темно" (т.е. светло и искуственное освещение выключено) и общая освещенность стала ниже нижнего порога,
threshold = true; //считаем что стало "темно"
digitalWrite(REL_PIN, HIGH); // и включаем свет
}
}
}
void mignled (int n){ // Мигнуть светодиодом n раз
for (int i = 1; i<=n;i++){
digitalWrite(REL_PIN,LOW);
delay (1000);
digitalWrite(REL_PIN,HIGH);
delay (1000);
}
}