I am currently working on a decently sized project using 4 custom classes, one of which needs to integrate blynk functions. The way I want it to work is as follows:
- rfid card is read using a function in my RF_Admin class to read a card’s uid and creates a user (one of my other custom classes).
- using BLYNK_WRITE(V0) and the textbox input widget, wait for the user to type in a name to go with the card’s uid.
- when a name is entered, that name is paired with the uid to make a new user
When I can get this part working it will be used in a function called RF_Admin::masterMode after the master tag is read to allow putting new users in the database.
The closest I’ve gotten is my attempt where I declare a String variable to hold blynk input string and the BLYNK_WRITE function in the RF_Admin.h file’s public space.
Here is the pertinent code in my project:
RF_Admin.h:
public:
//...
void getBlynkName(LiquidCrystal_I2C&, User&);
//...
// compare and search id's
bool cmpUID(LiquidCrystal_I2C&, byte*, byte*);
User lookupID(LiquidCrystal_I2C&, byte*);
//...
String newStr;
BLYNK_WRITE(V0)
{
newStr = param.asStr();
}
private:
User master;
User owner;
User guests[MAX_GUESTS];
int count;
};
RF_Admin.cpp:
void RF_Admin::getBlynkName(LiquidCrystal_I2C& lcd, User& usr)
{
String oldStr = newStr;
String fn, ln;
int spaceIndex;
int count = 0;
Blynk.config(AUTH);
bool blynkConnected = Blynk.connect();
while( (newStr == oldStr) )
{
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");
}
count++;
}
usr.setName(newStr);
}
//...
bool RF_Admin::cmpUID(LiquidCrystal_I2C& lcd, byte* uid1, byte* uid2)
{
for( byte x = 0; x < UID_LENGTH; x++ )
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("i=");
lcd.print(x);
lcd.print(" u1:");
lcd.print(uid1[x]);
lcd.setCursor(4,1);
lcd.print("u2:");
lcd.print(uid2[x]);
delay(600);
// check each byte of uid1 against uid2
if( uid1[x] != uid2[x] )
{
return false; // not the same card
}
}
return true;
}
User RF_Admin::lookupID(LiquidCrystal_I2C& lcd, byte* uid)
{
bool isMaster = true, isOwner = true, isGuest = false;
// check if master card
isMaster = cmpUID(lcd, uid, master.getUID());
if(isMaster) return getMaster();
// check if owner
isOwner = cmpUID(lcd, uid, owner.getUID());
if( isOwner ) return getOwner();
// check against each set guest id in guests array
for( int i = 0; (i < MAX_GUESTS) && (guests[i].getIsSet()); i++ )
{
isGuest = cmpUID(lcd, uid, getGuest(i).getUID());
if( isGuest ) return getGuest(i);
}
return User("new card", uid, 0);
}
User.h:
/* File: User.h
* Author: Michael
* Date: 1/19/2019
* This class contains User rfid information and an EEPROM mem locaiton to be used
* with an rfid user database. This class also contains functions used to manipulate
* and compare User information
*/
#ifndef USER_H
#define USER_H
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#define MAX_NAME_LEN 28
#define UID_LENGTH 10
#define TID_LENGTH 3
#define MEM_START_L 100
class User
{
public:
// ctors
User();
User(String, byte*, int);
// get/set functions
String getName() const { return name; }
void setName( String s ) { name = s; }
byte* getUID() const { return uid; }
void setUID(byte* u) { for( int i = 0; i < UID_LENGTH; i++ ) uid[i] = u[i]; }
int getLocation() const { return location; }
void setLocation(int l) { location = l; }
bool getIsSet() const { return isSet; }
void setIsSet(bool b) { isSet = b; }
// utility get functions for tid (first 3 bytes of uid)
byte getByte(byte x) const { return getUID()[x]; }
byte* getTID() const;
//overloaded '=' operator
User& operator=(const User&);
// overloaded '==' operator
friend bool operator==(const User&, const User&);
// overloaded '!=' operator
friend bool operator!=(const User& u1, const User& u2) { return !(u1 == u2); }
private:
String name;
byte uid[UID_LENGTH];
int location;
bool isSet;
};
#endif
Door_Unlocker_Pt4.ino:
#include <SparkFun_UHF_RFID_Reader.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <LiquidCrystal_I2C.h>
#include "Robot.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
int potVal, prevPotVal, buttonState;
int pot = A0;
int i = 0, j = 0;
int s[4] = {2, 0, 1, 3};
int curAngle, curI, rCount;
ClickButton btn(4, LOW, CLICKBTN_PULLUP);
Position curPos;
unsigned long t;
User tmpUsr;
BlynkWifiCommon Blynk(_blynkTransport);
char auth[] = "36xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxx";
char pass[] = "xxxxxxxxxxxx";
RF_Admin database;
Robot myRobot;
void setup()
{
database.init(lcd, nano, softSerial, 1000);
btn.Update();
lcd.init();
lcd.backlight();
myRobot.init(lcd, curPos);
Serial.begin(115200);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("sizeof(rfa):");
lcd.print(sizeof(RF_Admin));
lcd.clear();
lcd.setCursor(0,0);
lcd.print("step:2");
WiFi.begin(ssid, pass);
Blynk.config(auth);
}
void loop() {
Blynk.run();
btn.Update();
t = millis();
// every 6 seconds for 10 milliseconds start read for tags
if ( (t % 6000) < 10)
{
tmpUsr = database.readCard(lcd, nano);
// if( tmpUsr != User() ) database.printUsr(lcd, tmpUsr);
if( tmpUsr != User() ) database.getBlynkName(lcd, tmpUsr);
// if( tmpUsr == database.getMaster() ) database.masterMode(lcd, nano, btn);
// if( tmpUsr == database.getOwner() )
// {
// myRobot.goToFinal(curPos, lcd);
// myRobot.goToHome(curPos, lcd);
// }
}
if (btn.clicks == -5) myRobot.startTeachMode(btn, lcd, curPos, pot);
}
What I end up with is blynk connected (i think) to the server, but when I enter a name in blynk it doesn’t do anything in the program. I think this has something to do with the blynk_write(v0) function being defined in the header file instead of the cpp file where the blynk.run() function is. I am using the BlynkWifiCommon Blynk(_blynkTransport); work-around to allow for multiple includes of the same library. Any help would be much appreciated. And please forgive me if I formatted the code wrong as this is my first time posting code to a forum.