#include <LiquidCrystal_I2C.h>
// CONSTANTS
#define INVERSE_SENSOR 1 // Инверсия сенсора
#define IS_IMPULSE false // Импульсное управление турникетом
#define WAITING_PASS 7 // Время ожидания прохода
#define QR_KEY "icecold" // Контрольная фраза
#define TIME_SHOW_MESSAGE 2000 // Время показа сообщений
#define TIME_OF_IMPULSE 700 // Время импульса открытия турникета
#define PIN_SENSOR_1 A0 // пин сенсора
#define PIN_RELAY_E1 7 // пин релле электромагнитное
#define BARCODE_SERIAL Serial // Порт сканера ШК
#define BARCODE_SPEED 9600 // Скорость порта ШК
#define LOG_SERIAL Serial // Порт логгирования
#define LOG_ON 0 // 0 - Логгирование отключено
// GLOBAL VARIABLES
String qrCode = "";
// LCD Setting
LiquidCrystal_I2C lcd(0x27, 16, 2);
// д
uint8_t symbol_d[8] = {0b00110,
0b01010,
0b01010,
0b01010,
0b01010,
0b01010,
0b11111,
0b10001};
// и
uint8_t symbol_i[8] = {0b10001,
0b10001,
0b10001,
0b10011,
0b10101,
0b11001,
0b10001,
0b00000};
// п
uint8_t symbol_p[8] = {0b11111,
0b10001,
0b10001,
0b10001,
0b10001,
0b10001,
0b10001,
0b00000};
// ч
uint8_t symbol_ch[8] = {0b10001,
0b10001,
0b10001,
0b01111,
0b00001,
0b00001,
0b00001,
0b00000};
// ш
uint8_t symbol_sh[8] = {0b10001,
0b10001,
0b10001,
0b10101,
0b10101,
0b10101,
0b11111,
0b00000};
// щ
uint8_t symbol_sch[8] = {0b10001,
0b10001,
0b10001,
0b10101,
0b10101,
0b10101,
0b11111,
0b00001};
// START SETUP ---------------------------------------------------------------------------------------------------
void setup() {
//Инициализация релле
pinMode(PIN_RELAY_E1, OUTPUT);
// Инициализация сенсора
pinMode(PIN_SENSOR_1, INPUT_PULLUP);
// Инициализация Barcode
BARCODE_SERIAL.begin(BARCODE_SPEED);
// Инициализация дисплея
lcd.init(); // Инициируем работу с LCD дисплеем
lcd.backlight(); // Включаем подсветку LCD дисплея
lcd.createChar(0, symbol_ch);
lcd.createChar(1, symbol_d); // 1-д 2-ч 3-и 4-п 5- 6-ш 7-щ
lcd.createChar(2, symbol_ch);
lcd.createChar(3, symbol_i);
lcd.createChar(4, symbol_p);
lcd.createChar(6, symbol_sh);
lcd.createChar(7, symbol_sch);
// Приветствие
BARCODE_SERIAL.println("Controller T_QR");
lcd.setCursor(0, 0);
lcd.print("Controller T_QR");
lcd.setCursor(0, 1);
lcd.print("v. 0.2.1");
delay(TIME_SHOW_MESSAGE);
lcdMessage(3); // Приглашение на проход
}
void loop() {
// Проверяем наличие тэга со сканера
if (BARCODE_SERIAL.available()) {
char c;
qrCode = "";
while (BARCODE_SERIAL.available()){
c = BARCODE_SERIAL.read();
qrCode += c;
delay(5);
}
logWrite("QR-code was read: " + qrCode);
// проверяем тэг
if(checkQR()){
lcdMessage(1); // Разрешение прохода
// Открываем турникет
if (openTurnstile(PIN_RELAY_E1, PIN_SENSOR_1, WAITING_PASS, IS_IMPULSE)){
// TODO Если проход совершён
}
}else{
lcdMessage(2); // Запрет прохода
delay(TIME_SHOW_MESSAGE);
}
lcdMessage(3); // Приглашение на проход
}
delay(500);
}
boolean checkQR(){
if(qrCode.indexOf(QR_KEY) == -1){
return false;
}else{
return true;
}
}
void logWrite(String message){
if(LOG_ON){
LOG_SERIAL.println(message);
}
}
// Управление турникетом
bool openTurnstile(uint8_t relPin, uint8_t senPin, uint8_t timer, bool isImpulse){ // (пин релле, пин сенсора, время ожидания прохода)
bool checkImpulse; // Выставляем флаги для импульса
if(isImpulse)
checkImpulse = true;
else
checkImpulse = false;
digitalWrite(relPin, HIGH); // открываем турникет
unsigned long lockalTimer = millis(); // фиксируем время открытия
while(millis()-lockalTimer < timer*1000){ // Ждем пока не сработает таймер
if(checkImpulse){ // Если ипульсное управление
if(millis()-lockalTimer > TIME_OF_IMPULSE){ // Если длина импульса превысила свое премя
digitalWrite(relPin, LOW); // закрываем импульс
checkImpulse = false; // отключаем проверку на импульс
}
}
if((digitalRead(senPin)==HIGH) ^ INVERSE_SENSOR){ // Положение сенсора (+антидребезг)
delay(50);
if((digitalRead(senPin)==HIGH) ^ INVERSE_SENSOR){
digitalWrite(relPin, LOW); // закрываем турникет
return true; // Возвращаем успешный проход
}
}
delay(100);
}
digitalWrite(relPin, LOW); // закрываем турникет
return false; // Возвращаем несоверщённый проход
}
bool checkSensor(uint8_t pinSensor, bool isInvert){
uint8_t count = 0;
for(uint8_t i=0; i<3;i++){
if((digitalRead(pinSensor) == HIGH)^isInvert)
count++;
delay(10);
}
if(count > 2)
return true;
else
return false;
}
void lcdMessage(uint8_t nMessage){
lcd.clear();
// 1-д 2-ч 3-и 4-п 6-ш 7-щ
if(nMessage == 1){
lcd.print(" BXO\1");
lcd.setCursor(0, 1);
lcd.print(" PA3PE\6EH");
}else if(nMessage == 2){
lcd.print(" BXO\1");
lcd.setCursor(0, 1);
lcd.print(" 3A\4PE\7EH");
}else if(nMessage == 3){
lcd.print(" C\2\3TA\3TE");
lcd.setCursor(0, 1);
lcd.print(" QR-KO\1");
}
}