I’m working on a Blynk controlled arduino project involving two Arduino Uno Wifi rev 2 boards connecting to my Blynk local server using dhcp wifi connection. On the app both devices are set to generic board and wifi connection type. One board has a sketch that controls an armuno robot, while the other board has sparkfun’s UHF RFID shield connected to it. My phone is a One Plus 7 pro with Oxygen OS 10.3.7, and the Blynk library version number is 0.6.1. On the robot sketch I used a custom library I wrote for the Position and Robot classes, and on the RFID sketch I wrote a User and RFAdmin class. I don’t have any blynk functions in either of those libraries though.
The issue I am having is that both boards eventually permanently lose the connection to my local server. This happens (seemingly) randomly. I have tried changing the heartbeat interval to 8 hours and that still doesn’t fix the issue although it did take around that 8 hour mark for the rfid sketch to freeze (this one had no timers running at the time). The robot sketch froze sooner but has a 11 sec interval timer to update the ‘screen saver’ lcd display clock. I have looked at the serial monitor and it looks like it sent the heartbeat command to my local server, but received nothing back. I tried updating the local server to the most recent release, but it had no effect. I have put countless hours of searching through google and the forums, but still am no closer to figuring this out. Any help anyone can give me would be much appreciated. I have posted the code for both sketches below.
Door_Unlocker-Robot
#define BLYNK_PRINT Serial
#define BLYNK_DEBUG
//#define BLYNK_MAX_READBYTES 1024
//#define BLYNK_MAX_SENDBYTES 256
#include <SoftwareSerial.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <WiFiUDP.h>
#include <WidgetRTC.h>
#include "Robot.h"
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
int i = 0, j = 0;
int j1, j2, j3, j4;
int s[4] = {2, 0, 1, 3};
int curAngle, curI, rCount;
int bridgeInt = 0;
bool isLocked = true, armed = true;
bool relocking = false;
bool prevState1 = false, prevState2 = false;
Position curPos, testPos, prevPos;
unsigned long t;
int timerID, timer2ID, timer3ID, timer4ID, timer5ID, timer6ID;
int prevTime;
WidgetLED led1(V3);
WidgetLED led2(V15);
WidgetLED led3(V31);
WidgetLCD blynkLCD(V16);
BlynkTimer timer;
char auth[] = "***************************************";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "********";
char pass[] = "********";
IPAddress ip(192, 168, 1, 50); // IP address of the server
IPAddress gateway(192, 168, 1, 1); // gateway of your network
IPAddress subnet(255, 255, 255, 0); // subnet mask of your network
// NTP Servers:
IPAddress timeServer(129, 6, 15, 26); // time-a.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov
//IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov
unsigned int localPort = 8888; // local port to listen for UDP packets
//const int timeZone = 1; // Central European Time
int timeZone = -5; // Eastern Standard Time (USA)
//const int timeZone = -4; // Eastern Daylight Time (USA)
//const int timeZone = -8; // Pacific Standard Time (USA)
//const int timeZone = -7; // Pacific Daylight Time (USA)
time_t prevDisplay = 0; // when the digital clock was displayed
WiFiUDP Udp;
Robot myRobot;
void checkAndConnect();
void checkTeachMode();
void teachMode(Robot&, Position&);
void curPosLCD();
void isSavedPos();
void updateWidgets(Position&);
void zeroWidgets();
void updateLCD();
void deleteAllPos();
void relockDoor();
void clockDisplay();
void startClockDisplay();
void setup()
{
delay(6000);
lcd.init();
lcd.backlight();
Serial.begin(9600);
myRobot.init(lcd, curPos);
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("Finished Robot");
lcd.setCursor(3, 1);
lcd.print("Initialization");
// Blynk.begin(auth, ssid, pass, IPAddress(192, 168, 1, 251));
Blynk.begin(auth, ssid, pass, IPAddress(**, ***, ***, **), 8080); // public IP + port forwarded on router
setSyncInterval(60 * 10); // Sync interval in seconds (10 minutes)
timer.setInterval(1997L, updateLCD);
// timer.setInterval(607L, isSavedPos);
// timer.setInterval(1801L, checkAndConnect);
timer.setInterval(501L, checkTeachMode);
Udp.begin(localPort);
setSyncProvider(getNtpTime);
timer3ID = timer.setTimeout(60000, startClockDisplay);
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("Startup Process");
lcd.setCursor(6, 1);
lcd.print("Complete");
delay(1000);
lcd.clear();
led2.off();
led1.off();
zeroWidgets();
}
void loop()
{
Blynk.run();
timer.run();
checkAndConnect();
}
void checkAndConnect() // workaround I found for 'no sockets available'/ 'packet too big' errors
{
if (!Blynk.connected())
{
WiFi.end();
Blynk.begin(auth, ssid, pass, IPAddress(**, ***, ***, **), 8080);
}
}
void checkTeachMode()
{
if (myRobot.getTeachMode()) teachMode(myRobot, curPos);
}
void teachMode(Robot& r, Position& p)
{
prevPos = curPos;
Blynk.virtualWrite(V4, p.getJ3Pos());
Blynk.virtualWrite(V5, p.getJ1Pos());
Blynk.virtualWrite(V6, p.getJ2Pos());
Blynk.virtualWrite(V7, p.getJ4Pos());
isSavedPos();
while (myRobot.getTeachMode())
{
Blynk.run();
if (curPos != prevPos)
{
curPosLCD();
isSavedPos();
}
}
led2.off();
}
void curPosLCD()
{
if (curPos != prevPos)
{
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("Current Position");
lcd.setCursor(2, 2);
lcd.print("J1:");
lcd.print(curPos.getJ3Pos());
lcd.setCursor(12, 2);
lcd.print("J2:");
lcd.print(curPos.getJ1Pos());
lcd.setCursor(2, 3);
lcd.print("J3:");
lcd.print(curPos.getJ2Pos());
lcd.setCursor(12, 3);
lcd.print("J4:");
lcd.print(curPos.getJ4Pos());
prevPos = curPos;
}
}
void isSavedPos()
{
(curPos == myRobot.getP(j)) ? led2.on() : led2.off();
}
void updateWidgets(Position& p)
{
Blynk.virtualWrite(V4, curPos.getJ3Pos());
Blynk.virtualWrite(V5, curPos.getJ1Pos());
Blynk.virtualWrite(V6, curPos.getJ2Pos());
Blynk.virtualWrite(V7, curPos.getJ4Pos());
Blynk.virtualWrite(V8, curPos.getJ3Pos());
Blynk.virtualWrite(V9, curPos.getJ1Pos());
Blynk.virtualWrite(V10, curPos.getJ2Pos());
Blynk.virtualWrite(V11, curPos.getJ4Pos());
}
void zeroWidgets()
{
led2.off();
Blynk.virtualWrite(V4, 0);
Blynk.virtualWrite(V5, 0);
Blynk.virtualWrite(V6, 0);
Blynk.virtualWrite(V7, 0);
Blynk.virtualWrite(V8, 0);
Blynk.virtualWrite(V9, 0);
Blynk.virtualWrite(V10, 0);
Blynk.virtualWrite(V11, 0);
}
void updateLCD()
{
if (prevState1 != isLocked || prevState2 != armed)
{
blynkLCD.clear();
(isLocked) ? blynkLCD.print(5, 0, "Locked") : blynkLCD.print(4, 0, "Unlocked");
blynkLCD.print(3, 1, "Armed:");
(armed) ? blynkLCD.print(10, 1, "Yes") : blynkLCD.print(10, 1, "No");
prevState1 = isLocked;
prevState2 = armed;
}
}
void deleteAllPos()
{
for (int i = 0 ; i < EEPROM.length() ; i++) //put '0' in for all eeprom values
{
EEPROM.write(i, 0);
}
for (int i = 0; i < MAX_NUM_P; i++)
{
myRobot.setP(Position(), i);
}
led3.on();
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("Positions");
lcd.setCursor(4, 2);
lcd.print("Erased");
}
void relockDoor()
{
myRobot.goToFinal(isLocked, curPos, lcd);
isLocked = !isLocked;
myRobot.goToHome(isLocked, curPos, lcd);
timer.deleteTimer(timerID);
// timerID = timer.setTimeout(60000, relockDoor);
// timer.disable(timerID);
Blynk.virtualWrite(V17, 0);
Blynk.virtualWrite(V1, 0);
relocking = false;
}
void clockDisplay()
{
// You can call hourFormat12(), minute(), ... at any time
// Please see Time library examples for details
String currentTime;
if (hourFormat12() < 10) currentTime = "0" + String(hourFormat12()) + ":";
else currentTime = String(hourFormat12()) + ":";
if (minute() < 10) currentTime += "0" + String(minute());
else currentTime += String(minute());
// if (second() < 10) currentTime += "0" + String(second());
// else currentTime += String(second());
if (isAM()) currentTime += " AM";
else currentTime += " PM";
String currentDate;
if (month() < 10) currentDate = "0";
currentDate += String(month()) + "/";
if (day() < 10) currentDate += "0";
currentDate += String(day()) + "/" + String(year());
Serial.print("Current time: ");
Serial.print(currentTime);
Serial.print(" ");
Serial.print(currentDate);
Serial.println();
if (prevTime != minute())
{
lcd.clear();
lcd.setCursor(6, 1);
lcd.print(currentTime);
lcd.setCursor(5, 2);
lcd.print(currentDate);
prevTime = minute();
}
}
void startClockDisplay()
{
timer2ID = timer.setInterval(12599L, clockDisplay);
}
void stopClockDisplay()
{
timer.deleteTimer(timer3ID);
timer.deleteTimer(timer2ID);
timer3ID = timer.setTimeout(60001L, startClockDisplay);
lcd.clear();
}
// internet time sync code for clock display functions
/*-------- NTP code ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime()
{
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
sendNTPpacket(timeServer);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
BLYNK_WRITE(V1)
{
if (myRobot.getTeachMode() && param.asInt())
{
myRobot.goToFinal(isLocked, curPos, lcd);
isLocked = !isLocked;
myRobot.goToHome(isLocked, curPos, lcd);
myRobot.goToFinal(isLocked, curPos, lcd);
isLocked = !isLocked;
myRobot.goToHome(isLocked, curPos, lcd);
updateWidgets(curPos);
}
}
BLYNK_WRITE(V2)
{
myRobot.setTeachMode(param.asInt());
Serial.print("teach mode = ");
Serial.print(myRobot.getTeachMode());
if (myRobot.getTeachMode())
{
timer.deleteTimer(timer3ID); // startClockDisplay
timer.deleteTimer(timer2ID); // clockDisplay
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("Teach Mode");
lcd.setCursor(6, 2);
lcd.print("Enabled");
updateWidgets(curPos);
led1.on();
}
else
{
stopClockDisplay();
led1.off();
zeroWidgets();
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("Teach Mode");
lcd.setCursor(6, 2);
lcd.print("Disabled");
}
j = 0;
Blynk.virtualWrite(V14, j);
}
BLYNK_WRITE(V4)
{
if (myRobot.getTeachMode())
{
j1 = param.asInt();
curPos.setServoPos(s[0], myRobot.moveS(j1, s[0]));
Blynk.virtualWrite(V8, j1);
}
}
BLYNK_WRITE(V5)
{
if (myRobot.getTeachMode())
{
j2 = param.asInt();
curPos.setServoPos(s[1], myRobot.moveS(j2, s[1]));
Blynk.virtualWrite(V9, j2);
}
}
BLYNK_WRITE(V6)
{
if (myRobot.getTeachMode())
{
j3 = param.asInt();
curPos.setServoPos(s[2], myRobot.moveS(j3, s[2]));
Blynk.virtualWrite(V10, j3);
}
}
BLYNK_WRITE(V7)
{
if (myRobot.getTeachMode())
{
j4 = param.asInt();
curPos.setServoPos(s[3], myRobot.moveS(j4, s[3]));
Blynk.virtualWrite(V11, j4);
}
}
BLYNK_WRITE(V12)
{
if (myRobot.getTeachMode() && param.asInt())
{
(j >= 4) ? j = 0 : j++;
Blynk.virtualWrite(V14, j);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("skipping to");
lcd.setCursor(0, 1);
lcd.print("j=");
lcd.print(j);
led2.off();
}
}
BLYNK_WRITE(V13)
{
if (myRobot.getTeachMode())
{
curPos.setLocation(sizeof(Position) * j);
curPos.setSetP(true);
myRobot.setP(curPos, j);
EEPROM_readAnything(myRobot.getP(j).getLocation(), testPos);
if ( testPos != myRobot.getP(j) )
{
EEPROM_writeAnything(myRobot.getP(j).getLocation(), myRobot.getP(j));
}
// make coresponding positions for unlocked state
int lockMemL = sizeof(Position) * (j + 5);
int newJ4Pos = myRobot.getP(j).getJ4Pos();
(newJ4Pos < 90) ? newJ4Pos = 180 : newJ4Pos = myRobot.getP(0).getJ4Pos();
Position lockPos(curPos.getJ1Pos(), curPos.getJ2Pos(), curPos.getJ3Pos(), newJ4Pos, lockMemL);
lockPos.setSetP(true);
myRobot.setP(lockPos, j + 5);
EEPROM_readAnything(myRobot.getP(j + 5).getLocation(), testPos);
if ( testPos != myRobot.getP(j + 5) )
{
EEPROM_writeAnything(lockMemL, myRobot.getP(j + 5));
}
led2.on();
myRobot.printP(lcd, "PS=", j, myRobot.getP(j));
led3.off();
}
}
BLYNK_WRITE(V17)
{
if (!bridgeInt && !relocking)
{
stopClockDisplay();
myRobot.goToFinal(isLocked, curPos, lcd);
isLocked = !isLocked;
myRobot.goToHome(isLocked, curPos, lcd);
timerID = timer.setTimeout(60000, relockDoor);
relocking = true;
}
}
BLYNK_WRITE(V19)
{
if ( param.asInt())
{
timeZone = -4;
setSyncProvider(getNtpTime);
lcd.clear();
lcd.setCursor(2, 1);
lcd.print("Daylight Savings");
lcd.setCursor(4, 2);
lcd.print("Time Enabled");
}
else
{
timeZone = -5;
setSyncProvider(getNtpTime);
lcd.clear();
lcd.setCursor(2, 1);
lcd.print("Daylight Savings");
lcd.setCursor(3, 2);
lcd.print("Time Disabled");
}
}
BLYNK_WRITE(V24)
{
armed = param.asInt();
stopClockDisplay();
if (armed)
{
lcd.clear();
lcd.setCursor(4, 1);
lcd.print("RFID Enabled");
}
else
{
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("RFID Disabled");
}
}
BLYNK_WRITE(V25)
{
bridgeInt = param.asInt();
if (bridgeInt && !relocking)
{
myRobot.goToFinal(isLocked, curPos, lcd);
isLocked = !isLocked;
Blynk.virtualWrite(V17, 1);
myRobot.goToHome(isLocked, curPos, lcd);
bridgeInt = 0;
relocking = true;
timerID = timer.setTimeout(60000, relockDoor);
}
else bridgeInt = 0;
}
BLYNK_WRITE(V26)
{
if (myRobot.getTeachMode())
{
int jBefore = myRobot.getClosestIndex(curPos);
myRobot.movPos(curPos, myRobot.getP(jBefore));
if (jBefore < j)
{
for (int i = jBefore; i < (j + 1); i++) myRobot.movPos(curPos, myRobot.getP(i));
}
else
{
for (int i = jBefore; i > (j - 1); i--) myRobot.movPos(curPos, myRobot.getP(i));
}
updateWidgets(curPos);
}
}
BLYNK_WRITE(V27)
{
if (myRobot.getTeachMode() && param.asInt())
{
(j <= 0) ? j = 4 : j--;
Blynk.virtualWrite(V14, j);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("skipping to");
lcd.setCursor(0, 1);
lcd.print("j=");
lcd.print(j);
led2.off();
}
}
BLYNK_WRITE(V30)
{
if ((myRobot.getTeachMode() && param.asInt()))
{
// button pressed
timer5ID = timer.setTimeout(5000L, deleteAllPos);
}
else
{
timer.deleteTimer(timer5ID);
}
}
Door_Unlocker-RFID
#define BLYNK_PRINT Serial
#define BLYNK_DEBUG
//#define BLYNK_MAX_READBYTES 2048
//#define BLYNK_MAX_SENDBYTES 512
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <SparkFun_UHF_RFID_Reader.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include "RF_Admin.h"
#include "User.h"
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
RFID nano; // create uhf rfid object
SoftwareSerial softSerial(2, 3); //RX, TX for RFID Shield
RF_Admin database; // holds users
int bridgeInt = 0;
int choice = 0;
int enterPressed = 0;
int exitMaster = 0;
int scanningTags = 0;
int prevVal = 0;
bool armed = false;
bool masterEnabled = false;
char newStr[MAX_NAME_LEN];
//byte ledPin = LED_BUILTIN;
char ssid[] = "********";
char pass[] = "********";
//IPAddress server(192,168,1,50); // the fix IP address of the server
//WiFiClient client;
// Bridge widget on virtual pin 24
WidgetBridge bridge1(V24);
WidgetBridge bridge2(V25);
WidgetLED masterLED(V21);
WidgetLED cardReadLED(V29);
WidgetLCD masterModeLCD(V28);
char robotAuth[] = "********************************";
char auth[] = "********************************";
// Timer for blynking
BlynkTimer timer;
int timerID;
void checkAndConnect();
void scanForTags();
void blynkUsrPrint(User);
void masterMode(int&);
//void selectAction(int);
void getBlynkName(User&);
void setup()
{
Serial.begin(9600); // only for debug
lcd.init();
lcd.backlight();
nano.enableDebugging(Serial);
database.init(lcd, nano, softSerial, 2000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("Finished Database");
lcd.setCursor(3, 1);
lcd.print("Initialization");
delay(800);
Serial.println("finished database.init");
Serial.println(database.getOwner().getName());
// timerID = timer.setInterval(2001, scanForTags);
Blynk.begin(auth, ssid, pass, IPAddress(**, ***, ***, **), 8080); // public IP connects to local server through port forwarding
// Blynk.begin(auth, ssid, pass, IPAddress(192, 168, 1, 251));
// timer.setInterval(1001, checkAndConnect);
masterModeLCD.clear();
masterLED.off();
}
void loop ()
{
Blynk.run();
timer.run();
checkAndConnect();
}
void checkAndConnect()
{
if (!Blynk.connected())
{
WiFi.end();
Blynk.begin(auth, ssid, pass, IPAddress(73, 121, 190, 66), 8080);
}
}
void scanForTags()
{
char owner2[MAX_NAME_LEN] = "Ricki";
// cardReadLED.off();
User tmpUsr = database.readCard(lcd, nano);
if ( tmpUsr != User() )
{
cardReadLED.on();
database.printUsr(lcd, tmpUsr);
blynkUsrPrint(tmpUsr);
}
if ( tmpUsr == database.getMaster() )
{
cardReadLED.on();
masterEnabled = true;
while (!exitMaster) masterMode(choice);
masterEnabled = false;
exitMaster = 0;
enterPressed = 0;
masterLED.off();
cardReadLED.off();
}
if ( (tmpUsr == database.getOwner() ) || ( strcmp(tmpUsr.getName(), owner2) == 0) )
{
cardReadLED.on();
bridge2.virtualWrite(V25, 1);
String notification = tmpUsr.getName();
notification += " is unlocking the door";
Blynk.notify(notification);
}
int i = database.findGuest(lcd, tmpUsr);
if (i != -1 && ((strcmp(tmpUsr.getName(), owner2) != 0) || !armed ))
{
String notification = tmpUsr.getName();
notification += " is at the front door";
Blynk.notify(notification);
}
}
void blynkUsrPrint(User usr)
{
String tagID;
for ( byte x = 0; x < 3; x++)
{
String tmpStr = String(usr.getUID()[x], HEX);
if (usr.getUID()[x] < 0x10) tagID.concat("0");
tagID.concat(tmpStr);
tagID.concat(" ");
}
masterModeLCD.clear();
masterModeLCD.print(0, 0, usr.getName());
masterModeLCD.print(0, 1, tagID);
delay(1000);
}
void masterMode(int& choice)
{
User tmpUsr, sResults, notFound;
// lcd.clear();
// lcd.setCursor(0,0);
masterLED.on();
cardReadLED.off();
masterModeLCD.clear();
masterModeLCD.print(0, 0, "Select an action");
masterModeLCD.print(0, 1, "and press enter");
Blynk.setProperty(V20, "labels", "Select Action and Press Confirm", "New Master", "New Owner", "New Guest", "Delete Owner", "Delete Guest");
while (!enterPressed && !exitMaster) Blynk.run();
Serial.print("Choice = ");
Serial.print(choice);
Serial.print(" D_GUEST = ");
Serial.print(D_GUEST);
Serial.print(" choice == D_GUEST = ");
Serial.print(choice == D_GUEST);
if ( exitMaster )
{
masterModeLCD.clear();
masterLED.off();
enterPressed = 0;
}
// Serial.print("Choice = ");
// Serial.println(choice);
if (choice == N_MAS)
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, "Scan card to add");
masterModeLCD.print(0, 1, " new master");
// database.printCardPrompt(lcd, ADD, "Master");
while (tmpUsr == notFound && !exitMaster)
{
Blynk.run();
tmpUsr = database.readCard(lcd, nano);
}
if ( exitMaster )
{
masterModeLCD.clear();
masterLED.off();
enterPressed = 0;
return;
}
cardReadLED.on();
sResults = database.lookupID(lcd, tmpUsr.getUID());
if ( sResults != database.getMaster() )
{
tmpUsr.setName("Master");
tmpUsr.setLocation(MEM_START_L);
tmpUsr.setIsSet(true);
database.setMaster(tmpUsr);
database.writeEEPROM(lcd, tmpUsr);
exitMaster = 0;
enterPressed = 0;
}
return;
}
else if (choice == N_OWN)
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, "Scan card to add");
masterModeLCD.print(0, 1, " new owner");
// database.printCardPrompt(lcd, ADD, "Owner");
while (tmpUsr == notFound && !exitMaster)
{
Blynk.run();
tmpUsr = database.readCard(lcd, nano);
}
if ( exitMaster )
{
masterModeLCD.clear();
masterLED.off();
enterPressed = 0;
return;
}
cardReadLED.on();
sResults = database.lookupID(lcd, tmpUsr.getUID());
if ( sResults != database.getMaster() )
{
getBlynkName(tmpUsr);
Serial.println(tmpUsr.getName());
tmpUsr.setLocation(sizeof(User));
tmpUsr.setIsSet(true);
database.setOwner(tmpUsr);
Serial.println(database.getOwner().getName());
Serial.println(tmpUsr.getName());
database.writeEEPROM(lcd, tmpUsr);
exitMaster = 0;
enterPressed = 0;
}
enterPressed = 0;
}
else if (choice == N_GUEST)
{
if (database.getCount() == MAX_GUESTS)
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, " Max number of ");
masterModeLCD.print(0, 1, " guests reached ");
delay(1000);
enterPressed = 0;
return;
}
masterModeLCD.clear();
masterModeLCD.print(0, 0, "Scan card to add");
masterModeLCD.print(0, 1, " new guest");
// database.printCardPrompt(lcd, ADD, "Guest");
while (tmpUsr == notFound && !exitMaster)
{
Blynk.run();
tmpUsr = database.readCard(lcd, nano);
}
if ( exitMaster )
{
masterModeLCD.clear();
masterLED.off();
enterPressed = 0;
return;
}
int i = database.findGuest(lcd, tmpUsr);
if ( i == -1 )
{
getBlynkName(tmpUsr);
tmpUsr.setLocation(MEM_START_L + (2 * (sizeof(User))) + (database.getCount()*sizeof(User)));
tmpUsr.setIsSet(true);
database.setGuest(database.getCount(), tmpUsr);
if (database.getCount() != MAX_GUESTS) database.incCount();
database.writeEEPROM(lcd, tmpUsr);
enterPressed = 0;
}
}
else if (choice == D_OWN)
{
EEPROM_readAnything(MEM_START_L + sizeof(User), tmpUsr);
if ((tmpUsr.getLocation() == -1) || !(tmpUsr.getIsSet()))
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, " There is no ");
masterModeLCD.print(0, 1, " saved owner ");
delay(1000);
enterPressed = 0;
return;
}
byte tmpUid[UID_LENGTH] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
char blankName[MAX_NAME_LEN];
User delGuest(blankName, tmpUid, -1);
delGuest.setIsSet(false);
EEPROM_writeAnything((sizeof(User)) + MEM_START_L, delGuest);
}
else if (choice == D_GUEST)
{
String labels[MAX_GUESTS];
EEPROM_readAnything(MEM_START_L + (2 * sizeof(User)), tmpUsr);
Serial.println("read user from first mem spot");
Serial.println(tmpUsr.getName());
if ((tmpUsr.getLocation() == -1) || !(tmpUsr.getIsSet()))
{
Serial.println("no user in first guest spot");
masterModeLCD.clear();
masterModeLCD.print(0, 0, " There is no ");
masterModeLCD.print(0, 1, " saved guest ");
delay(1000);
enterPressed = 0;
return;
}
Serial.println("user in first guest spot");
masterModeLCD.clear();
masterModeLCD.print(0, 0, " Please choose ");
masterModeLCD.print(0, 1, " guest to delete");
enterPressed = 0;
Serial.println(database.getCount());
for (int i = 0; i < database.getCount(); i++)
{
labels[i] = database.getGuest(i).getName();
Serial.println(labels[i]);
}
Blynk.setProperty(V20, "labels", labels[0], labels[1], labels[2], labels[3], labels[4], labels[5], labels[6], labels[7]);
while (!enterPressed && !exitMaster)
{
Blynk.run();
}
if ( exitMaster )
{
masterModeLCD.clear();
masterLED.off();
enterPressed = 0;
return;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("choice = ");
lcd.print(choice);
delay(1000);
database.deleteGuest(lcd, choice);
enterPressed = 0;
Blynk.setProperty(V20, "labels", "Select Action and Press Confirm", "New Master", "New Owner", "New Guest", "Delete Owner", "Delete Guest");
}
enterPressed = 0;
}
void getBlynkName(User& usr)
{
char oldStr[MAX_NAME_LEN];
strcpy(oldStr, newStr);
String fn, ln;
int spaceIndex;
int count = 0;
while ( strcmp(newStr, oldStr) == 0 )
{
Blynk.run();
if ( count == 0 )
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Please enter a");
lcd.setCursor(0, 1);
lcd.print("name in blynk");
masterModeLCD.clear();
masterModeLCD.print(0, 0, " Please enter");
masterModeLCD.print(0, 1, "guest name below");
}
if ( count == 0 ) count++;
}
usr.setName(newStr);
}
BLYNK_WRITE(V0)
{
if ( masterMode )
{
String readStr = param.asString();
strcpy(newStr, readStr.c_str());
}
}
BLYNK_WRITE(V18)
{
armed = param.asInt();
if (armed && !masterEnabled)
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, " Scanning for");
masterModeLCD.print(0, 1, " tags now");
armed = true;
// scanTimer.enable(timerID); // Turn on
}
else
{
if (!masterEnabled)
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, " Stopping scan");
masterModeLCD.print(0, 1, " now");
}
// if (prevVal != param.asInt()) scanningTags = param.asInt(); prevVal = scanningTags;
if (!scanningTags && !masterEnabled) masterModeLCD.clear();
Blynk.virtualWrite(V32, 1);
}
}
//BLYNK_WRITE(V19)
//{
// armed = param.asInt();
// if (armed || scanningTags)
// {
// armed = true;
// Serial.println("armed = true");
// lcd.clear();
// lcd.setCursor(7, 1);
// lcd.print("Device");
// lcd.setCursor(8, 2);
// lcd.print("Armed");
// bridge1.virtualWrite(V24, 1);
// // scanTimer.enable(timerID); // Turn on
// }
// else
// {
// Serial.println("armed = false");
// armed = false;
// bridge1.virtualWrite(V24, 0);
// // scanTimer.disable(timerID); // Turn off
// }
//}
BLYNK_WRITE(V20)
{
choice = param.asInt();
Serial.print("choice = ");
Serial.println(choice);
}
BLYNK_WRITE(V22)
{
if (param.asInt()) enterPressed = param.asInt();
}
BLYNK_WRITE(V23)
{
if (param.asInt()) exitMaster = param.asInt();
}
BLYNK_WRITE(V32)
{
armed = param.asInt();
if (armed)
{
Serial.println("armed = true");
bridge1.virtualWrite(V24, 1);
timer.deleteTimer(timerID);
timerID = timer.setInterval(4001L, scanForTags);
}
else
{
Serial.println("armed = false");
armed = false;
bridge1.virtualWrite(V24, 0);
timer.deleteTimer(timerID); // Turn off
}
if (armed && !masterEnabled)
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, " Scanning for");
masterModeLCD.print(0, 1, " tags now");
armed = true;
// scanTimer.enable(timerID); // Turn on
}
else
{
if (!masterEnabled)
{
masterModeLCD.clear();
masterModeLCD.print(0, 0, " Stopping scan");
masterModeLCD.print(0, 1, " now");
}
// if (prevVal != param.asInt()) scanningTags = param.asInt(); prevVal = scanningTags;
if (!armed && !masterEnabled) masterModeLCD.clear();
}
}
BLYNK_CONNECTED() {
bridge1.setAuthToken(robotAuth); // Place the AuthToken of the second hardware here
bridge2.setAuthToken(robotAuth);
}