/*
parking access is demo application born to show a state
machine implementation.
Copyright (C) 2022 Maurilio Pizzurro
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Parking access application
Pulsante verde per simulare la barriera IR
https://www.adafruit.com/product/2168
https://www.adafruit.com/product/2167
IR Break Beam Sensor with Premium Wire Header Ends - 5mm LEDs
*/
#include <IRremote.h>
#include <LiquidCrystal.h>
#include <Servo.h>
#define PIN_RECEIVER 2 // Signal Pin of IR receiver
IRrecv receiver(PIN_RECEIVER);
Servo RCservo;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
/* SERVO_UP servo in posizione verticale */
#define SERVO_UP 180
/* SERVO_UP servo in posizione orizzontale */
#define SERVO_DOWN 90
/* PIN_IR_BARRIER contatto pulito relay IR RX */
const byte PIN_IR_BARRIER = 4;
// g_state è la variabile di stato
uint8_t g_state = 0;
uint32_t g_saveMillis = 0;
uint8_t g_servoPos = SERVO_DOWN;
/* S_XXX stati della macchina a stati g_state */
#define S_START 0
#define S_INOPENING 1
#define S_ISUP 2
#define S_INCLOSING 3
#define IRCMD_PLAY 168
void setup() {
Serial.begin(115200);
pinMode(PIN_IR_BARRIER, INPUT_PULLUP);
receiver.enableIRIn(); // Start the receiver
lcd.begin(16, 2);
lcd.print("Press play");
RCservo.attach(5);
RCservo.write(g_servoPos);
}
void loop() {
uint8_t command = 0;
if (receiver.decode()) {
command = receiver.decodedIRData.command;
receiver.resume(); // Receive the next value
}
switch (g_state) {
case S_START:
if (command == IRCMD_PLAY) {
/* CHANGE STATE */
g_state = S_INOPENING;
}
break;
case S_INOPENING:
if (millis() - g_saveMillis > 35) {
g_saveMillis = millis();
if (g_servoPos <= SERVO_UP) {
g_servoPos++;
RCservo.write(g_servoPos);
}
if (g_servoPos == SERVO_UP) {
/* CHANGE STATE */
g_state = S_ISUP;
g_saveMillis = millis();
}
}
break;
case S_ISUP:
if (millis() - g_saveMillis > 2000) {
/* CHANGE STATE */
g_state = S_INCLOSING;
}
/* CHECK IR BARRIER */
if (digitalRead(PIN_IR_BARRIER) == LOW) {
/* RESTART TIMER */
g_saveMillis = millis();
}
break;
case S_INCLOSING:
if (millis() - g_saveMillis > 50) {
g_saveMillis = millis();
if (g_servoPos >= SERVO_DOWN) {
g_servoPos--;
RCservo.write(g_servoPos);
}
if (g_servoPos == SERVO_DOWN) {
/* CHANGE STATE */
g_state = S_START;
}
}
/* CHECK IR BARRIER */
if (digitalRead(PIN_IR_BARRIER) == LOW) {
/* CHANGE STATE */
g_state = S_INOPENING;
}
break;
} // end switch
} // end loop()