#include <LiquidCrystal.h>
#define LED 7
#define PIR_SENSOR 5
#define JOY_HORZ A1
#define JOY_VERT A0
#define JOY_SEL 6
class Joystick
{
public:
Joystick(int pinHorz, int pinVert, int pinSel, LiquidCrystal *lcd)
{
_pinSel = pinSel;
_pinVert = pinVert;
_pinHorz = pinHorz;
_deadZone = 100;
_selState = 0;
_lcd = lcd;
_delay = 2000;
pinMode(_pinSel, INPUT);
pinMode(_pinVert, INPUT);
pinMode(_pinHorz, INPUT);
}
~Joystick() = default;
void start()
{
_delay = 2000;
printDelay();
}
int getDelay()
{
return _delay;
}
void process()
{
int y = analogRead(_pinVert);
int x = analogRead(_pinHorz);
int push = debounce();
if(x > 512 + _deadZone)//влево
{
decrementDelay();
printDelay();
}
else if(x < 512 - _deadZone)//вправо
{
incrementDelay();
printDelay();
}
else if(y > 512 + _deadZone)//вверх
{
incrementDelay();
printDelay();
}
else if(y < 512 - _deadZone)//вниз
{
decrementDelay();
printDelay();
}
if(push != _selState)
{
_delay = 2000;
printDelay();
_selState = push;
}
}
private:
int _pinSel;
int _pinHorz;
int _pinVert;
int _selState;
int _deadZone;
LiquidCrystal *_lcd;
int _delay;
int debounce ()
{
int current = digitalRead(_pinSel);
if(_selState != current)
{
delay(5);
current = digitalRead(_pinSel);
}
return current;
}
void incrementDelay()
{
_delay += 1000;
if(_delay > 10000)
{
_delay = 10000;
}
};
void decrementDelay()
{
_delay -= 1000;
if(_delay < 2000)
{
_delay = 2000;
}
}
void printDelay()
{
_lcd->clear();
_lcd->print("Delay: ");
_lcd->print(_delay/1000);
_lcd->print(" s");
}
};
class Lamp
{
public:
Lamp(int pin, int time)
{
pinMode(pin, OUTPUT);
_pinLed = pin;
_startTime = 0;
_delay = time;
_light = false;
};
~Lamp() = default;
bool isLighted()
{
return _light;
}
void setTimedLight(int time, unsigned long start)
{
_startTime = start;
_delay = time;
digitalWrite(_pinLed, HIGH);
_light = true;
}
void timedLight()
{
if(_startTime + _delay <= millis())
{
digitalWrite(_pinLed, LOW);
_light = false;
}
}
private:
int _pinLed;
unsigned long _startTime;
int _delay;
bool _light;
};
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
Joystick joystick(JOY_HORZ, JOY_VERT, JOY_SEL, &lcd);
Lamp lamp(LED, 2000);
void setup()
{
pinMode(PIR_SENSOR, INPUT);
analogReference(DEFAULT);
lcd.begin(16, 2, LCD_5x8DOTS);
joystick.start();
}
bool processed = false;
void loop()
{
unsigned long curLoopTime = millis();
//обеспечение интервала опроса джойстика = 100 мс, чтобы не блокировать поток моргания светодиода через delay(100)
if(curLoopTime % 100 > 90 && !processed)
{
joystick.process();
processed = true;
}
else if(curLoopTime % 100 < 90)
{
processed = false;
}
//если лампа не горит и сработал датчик стартуем свечение на заданное время начиная с екущего момента
if(digitalRead(PIR_SENSOR) == HIGH && !lamp.isLighted())
{
lamp.setTimedLight(joystick.getDelay(), millis());
}
if(lamp.isLighted())
{
lamp.timedLight();
}
}