набросал тут программу для астрокоррекции боевых блоков по опорным звездам.
Но, чтобы никто не догадался, замаскировал её под управление светом в туалете.
Программа работает так, как я хочу. проблем никаких нет.
Но... весьма расточительно цельную ардуину гонять только на лампочку в сортире. Есть мысль, что ей по силам взять на себя управление светом в прилегающем коридорчике. Опять-же, не проблема три раза повторить приведенную программу, добавив другие входные и выходные пины.
но будет как-то неаккуратненько©.
Хотелось-бы свою программу превратить в подпрограмму(?) функцию(?) внешний модуль(?) в которую на вход подавал бы статус текущего сенсора, показание текущего таймера, а она выдавала-бы яркость для текущего светодиода.
На будущее в планах добавить RTC модуль, чтобы если в ночи пошёл отлить, то свет не включался-бы махом на полную.
ну и в дальнейшем, конечно, подключить вайфайный модуль, чтобы
светом в сортире ориентацией боевого блока рулить с любой точки планеты
ах, да, сам листинг прилагается
code c
#define PIR_PIN 9 //пин пир сенсора
#define LAMP_PIN 10 //пин светодиода
#define CONTROL_LED 13 //пин контрольного светодиода
float brightCurrent=0; //текущая яркость
int brightMax=254; // максимальная яркость (в будущем зависит от времени суток)
float brightDelta=0.002; //дельта, с которой происходит изменение яркости светодиода
unsigned long timerCurrent=80000;
unsigned long timerMax=100000; //максимальная задержка, в течении которой горит светодиод с максимальной яркостью
//задаем состояния светодиода
enum lampState
{
LIGHT_OFF, //свет выключен
LIGHT_UP, //свет разжигается
LIGHT_ON, //свет полностью включен
LIGHT_DOWN, //свет выключен
TOTAL_STATES
};
//задаём исходные значения переменных
int lampState = LIGHT_OFF;
bool pirStatus = false;
void setup()
{
pinMode(PIR_PIN, INPUT);
pinMode(LAMP_PIN, OUTPUT);
pinMode (CONTROL_LED,OUTPUT);
}
void loop()
{
bool pirStatus = digitalRead(PIR_PIN);
//analogWrite (CONTROL_LED,255);
switch (lampState) {
//блок выключеного света
// если обнаружено движение, то текущий статус меняется на LIGHT_UP- розжиг светодиода
// если движения нет, то статус остаётся прежним - LIGHT_OFF
case LIGHT_OFF:
if (pirStatus==1) { //
lampState=LIGHT_UP; //если обнаружено движение, то меняем статус лампы на "розжиг"
} //
else {
lampState=LIGHT_OFF;
}
brightCurrent=0; //текущую яркость лампы принимаем равную 0
break;
// плавный розжиг светодиода
// к текущей яркости добавляем дельту.
// если яркость достигает максимума, то меняем состояние светодиода на LIGHT_ON
case LIGHT_UP:
brightCurrent= brightCurrent+brightDelta;
if (brightCurrent >=brightMax){
timerCurrent=timerMax;
lampState= LIGHT_ON;
}
break;
// свечение с постоянной (максимальной) яркостью
// если обнаружено движение, то таймер принимает максимальное значение
// если движения нет, то уменьшаем таймер
// если таймер достиг минимального значения, то статус светодиода меняем на LIGHT_DOWN
case LIGHT_ON:
if (pirStatus){
timerCurrent=timerMax;
}
else {
timerCurrent=timerCurrent-1;
}
if (timerCurrent<1) {
lampState =LIGHT_DOWN;
brightCurrent=brightMax;
}
//analogWrite(LAMP_PIN, 100);
break;
// плавное гашение светодиода
//если движение не обнаружено, то от текущей яркости отнимаем дельту
//если движение обнаружено, то переходим к розжигу светодиода в блоке LIGHT_UP
// если достигнута минимальная яркость, то ререходим в блок LIGHT_OFF
case LIGHT_DOWN:
if (pirStatus==0){
brightCurrent= brightCurrent-(brightDelta/2);
}
else {
lampState=LIGHT_UP;
timerCurrent=timerMax;
};
if (brightCurrent <1){
lampState= LIGHT_OFF;
}
//analogWrite(LAMP_PIN, 255);
break;
//default:
//lampState=LIGHT_OFF;
};
//светим светодиод с текущей яркостью brightCurrent
analogWrite(LAMP_PIN, brightCurrent);
//это для контроля - когда яркость максимальная, то зажигаем контрольный светодиод
if (lampState==LIGHT_ON) {
analogWrite(CONTROL_LED,255);
}
else {
analogWrite (CONTROL_LED,0);
}
}