#include <LiquidCrystal.h>
#include <AccelStepper.h>
#include <Servo.h>
#include <EEPROM.h>
// Pin set
//Ethernet
#define PIN_RST_ETHERNET A15
#define PIN_ETH_SCS 53
// Stepper
#define PIN_MOTOR_DIR 13
#define PIN_MOTOR_STEP 12
//Foto sensor
#define PIN_FOTO 18
//Laser
#define PIN_LASER 17
//RFID
#define PIN_PN532_IRQ 19
#define PIN_PN532_RESET 46
//Servo
#define PIN_SERVO_TOP 6
#define PIN_SERVO_DOWN 7
//LCD
#define LCD_RS 33
#define LCD_EN 31
#define LCD_D4 35
#define LCD_D5 29
#define LCD_D6 37
#define LCD_D7 27
//DIP SWITCH
#define PIN_DIP_SWITCH_1 9
#define PIN_DIP_SWITCH_2 8
// Global variables
unsigned long timeTmp;
uint8_t timesMotorRunWithoutCapsule = 0; // Количество попыток крутить мотор
boolean isReadyForGet = false; // Готовность выдавать браслет
byte bufferTag[7] = {0, 0, 0, 0, 0, 0, 0}; // Буффер для работы с тэгом
String barCode = ""; // Буффер для работы с шк
String customerId = ""; // Буффер для работы с ID клиента
boolean isHaveCapsule = 0; // Наличие капсулы
uint8_t countCycles = 0; // Количество пройденых циклов
boolean access = 0; // Разрешение на выдачу браслета
uint8_t result; // Результать выполнения запроса на сервер
// //Ethernet
// byte mac[] = {0x10,0xBF,0x48,0xBC,0xC5,0xC1};
// IPAddress ipServerBars(10,0,11,16); //Указываем адрес сервера
// IPAddress ip(10,0,11,20); //Указываем адрес устройства
// IPAddress mask(255,255,255,0);
// //IPAddress ipServerBars(EEPROM.read(41), EEPROM.read(42), EEPROM.read(43), EEPROM.read(44)); //Указываем адрес сервера
// //IPAddress ip(EEPROM.read(21), EEPROM.read(22), EEPROM.read(23), EEPROM.read(24)); //Указываем адрес устройства
// //byte mac[] = {EEPROM.read(31), EEPROM.read(32), EEPROM.read(33), EEPROM.read(34), EEPROM.read(35), EEPROM.read(36)}; // Задаём MAC-адрес
// unsigned long beginMicros;
//Шаговый двигатель
AccelStepper myStepper(1, PIN_MOTOR_STEP, PIN_MOTOR_DIR);
//Сервоприводы
Servo servoTop;
Servo servoDown;
#define ANGLE_SERVO_DOWN_MID 84
// NFC PN532 (I2C)
// Adafruit_PN532 nfc(PIN_PN532_IRQ, PIN_PN532_RESET);
// Cканер ШК
#define BARCODE_SERIAL Serial3
// Дисплей
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7); //LCD (rs, en, d4, d5, d6, d7)
//------------------------------------------------------------------------------------------------//
void setup() {
// Инициализация дисплея
lcd.begin(16, 2); // LCD количество символов в строке и количество строк
message(F("Vending v0.40"),F("Bailamos!!!"),1);
//Init DIP switch
pinMode(PIN_DIP_SWITCH_1, INPUT);
pinMode(PIN_DIP_SWITCH_2, INPUT);
message(("MODE = " + String(getMode())),F(""),1);
// Инициализация Фотосенсор
pinMode(PIN_FOTO, INPUT_PULLUP);
// Инициализация лазер
pinMode(PIN_LASER, OUTPUT);
digitalWrite(PIN_LASER, HIGH);
// Инициализация шаговый двигатель
myStepper.setMaxSpeed(600);
myStepper.setAcceleration(100);
myStepper.setSpeed(600);
// Инициализация сервопривода
servoTop.attach(PIN_SERVO_TOP);
servoDown.attach(PIN_SERVO_DOWN);
servoStart();
// Инициализация ШК
BARCODE_SERIAL.begin(9600);
servoDrop(); //На всякий случай делаем сброс капсулы
if(getMode() == 2){
testMode();
}
}
void loop() {
message(("MODE = " + String(getMode())),F(""),1);
delay(100);
}
uint8_t getMode(){
if(digitalRead(PIN_DIP_SWITCH_1)){
return 1;
if(digitalRead(PIN_DIP_SWITCH_2)){
return 3;
}
}
if(digitalRead(PIN_DIP_SWITCH_2)){
return 2;
}
return 0;
}
void testMode(){
myStepper.moveTo(myStepper.currentPosition()+10000);
message(F("Тест мотора"), F("Тестирование"),2);
while(1){
myStepper.run();
if (myStepper.distanceToGo() == 0){
message("Тест мотора", "ЗАВЕРШЕН",2);
myStepper.disableOutputs();
break;
}
}
message("Тест фотосенсора", "Тестирование",1);
while(1){
if(isFotoOff()){
message("Источник света", "Высокий",0);
}else{
message("Источник света", "Низкий",0);
}
}
}
//Привести в стартовое положение
void servoStart(){
servoDown.write(ANGLE_SERVO_DOWN_MID);
delay(600);
servoTop.write(0);
delay(600);
}
//Перемешать
void servoMix(){
servoDown.write(ANGLE_SERVO_DOWN_MID);
delay(200);
uint8_t deg = 0;
uint8_t dir = 1;
servoTop.write(deg);
delay(600);
unsigned long timeLocal = millis();
// while(!nfcRead(bufferTag, 300)){
// if(deg==175){
// deg=0;
// }else{
// deg=175;
// }
// servoTop.write(deg);
// delay(1200);
// if((millis()-timeLocal)>10000) break;
// }
servoTop.write(0);
delay(200);
}
// Отдать капсулу
void servoGet(){
servoTop.write(0);
delay(500);
servoDown.write(0);
delay(1000);
servoDown.write(ANGLE_SERVO_DOWN_MID);
delay(500);
isHaveCapsule = 0;
}
// Сбросить капсулу
void servoDrop(){
servoTop.write(0);
delay(500);
servoDown.write(180);
delay(1000);
servoDown.write(ANGLE_SERVO_DOWN_MID);
delay(500);
isHaveCapsule = 0;
}
void message(String s1, String s2, uint8_t second){
lcdPrintRow(0,s1,0);
if(s2.length()==0)
s2 = " ";
lcdPrintRow(1,s2,second);
}
void lcdPrintRow(uint8_t nRow, String msg, uint8_t seconds){ // Вывод сообщений на LCD дисплей (номер строки, текст, задержка в секундах)
lcd.setCursor(0, nRow);
lcd.print(" ");
lcd.setCursor(0, nRow);
lcd.print(msg);
delay(seconds * 1000);
}
uint8_t getWaitingAnswer(){
return 5;
}
// -------------- IP адрес --------------
void saveIp(uint8_t ip1, uint8_t ip2, uint8_t ip3, uint8_t ip4){
EEPROM.update(21, ip1);
EEPROM.update(22, ip2);
EEPROM.update(23, ip3);
EEPROM.update(24, ip4);
}
// IPAddress getIp(){
// return IPAddress(EEPROM.read(21), EEPROM.read(22), EEPROM.read(23), EEPROM.read(24));
// }
// -------------- IP адрес сервера --------------
//void saveIpSrv(IPAddress ip){
// EEPROM.update(41, ip[0]);
// EEPROM.update(42, ip[1]);
// EEPROM.update(43, ip[2]);
// EEPROM.update(44, ip[3]);
//}
void saveIpSrv(uint8_t ip1, uint8_t ip2, uint8_t ip3, uint8_t ip4){
EEPROM.update(41, ip1);
EEPROM.update(42, ip2);
EEPROM.update(43, ip3);
EEPROM.update(44, ip4);
}
// IPAddress getIpSrv(){
// return IPAddress(EEPROM.read(41), EEPROM.read(42), EEPROM.read(43), EEPROM.read(44));
// }
//----------------------------------------------------------
boolean motorStart(){
myStepper.moveTo(myStepper.currentPosition()+20000);
message("Выборка", "капсулы",2);
while(1){
myStepper.run();
if(isFotoOff()){
message("Проверка", "капсулы",0);
timeTmp = millis();
while ((millis()-timeTmp)<1000){
myStepper.run();
}
myStepper.disableOutputs();
return 1;
}
if (myStepper.distanceToGo() == 0){
message("Капсулы", "отсутствуют",2);
myStepper.disableOutputs();
return 0;
}
}
}
boolean isFotoOff(){
if(digitalRead(PIN_FOTO)==HIGH){
return 1;
}else{
return 0;
}
}
void laserSwitch(boolean isLaserOn){
if(isLaserOn){
digitalWrite(PIN_LASER, HIGH); // Laser on
}else{
digitalWrite(PIN_LASER, LOW); // Laser on
}
}