post image

I have recently made an Infomation display for a friend using an ESP32 driving a Nexiton HMI LCD display This is the first time i have used these displays and have been impressed with the results . These are serial based displays that have a HMI that is first designed on Nexiton’s IDE desktop software and then flashed to the display via micro SD card or Uart.

After Designing the HMI , testing it on the built Simulator and then coping it to micro SD card and then copying to the display. This didn’t take long at all but if you are like me who kept noticing my miskates and wanting to make constant changes i wanted another option. For my current application i did not want to have a micro SD card slot in the encloure or remove the LCD every time i wanted to change the HMI.

I looked in to the serial Route and but currently the nextion display (basic range) does not have a built in USB to serial convertor and only having a single UART you need disconnecting from MCU every time you want to program.

After a bit of research I came across this cool ESPNEXUPLOAD library that provided library that provides a web page upload and program facility . As good as it looks It wasn’t exactly what I was looking for .

My Solution

I tried expirementing to see if i could have a mode that would pass the ESP32 USB serial straight to the nexiton display if a gpio pin is shorted to ground so can be programmed directly from nexiton editor.

  
int lcd_prog_pin = 27; GPIO connected to ground will enable passthrough !

void setup() {
    Serial.begin(57600);
     Serial2.begin(57600);
    pinMode(lcd_prog_pin, INPUT_PULLUP);
}


void loop() {

 if (digitalRead(lcd_prog_pin) == LOW) {   IF PIN 27 is shorted to GND when serial passthrough will work !

    if (Serial.available()) {     // If anything comes in Serial (USB) 
            Serial2.write(Serial.read());   // read it and send it out Serial2 (NEXITON LCD)
        }

        if (Serial2.available()) {     // If anything comes in Serial2 (NEXITON LCD)
            Serial.write(Serial2.read());   // read it and send it out Serial (USB)
        }

   else
            {
              // ****dont do anything else if loop back is running put other tasks here****

             // myNex.NextionListen();  //Example it working along side EasyNextionLibrary
             }
}





Things to note

I have set baud rate to 57600 to aviod risk of the EXP32 boot messages causing issues if set to 115200. This is no way anywhere near the speed of programming via SD card but the NEXITON Editor is clever enough only to copy changes after the inital serial upload. In the furture i may try i higher baud rate.

I have found it does work better if the passthough jumper is set and Esp32 is then Reset. I also have got the display connected in the debugger simulator and seems to work ok.

Hope this is found useful !

post image

Unfortunately i haven’t had a lot of time for home projects recently with work and other commitments but with the current situation i had more free time and finally had to time to work on projects which i enjoy !

I have found myself sometimes using my TS100 soldering away from the bench and one day i was watching https://www.youtube.com/watch?v=8uGS11yuVyo where Adam Savage from Tested made a portable Ts100 Soldering Iron powered by a Dewalt power tool battery. This was a great project but i wanted something more compact without all the storage.

post image

Following on my previous (project / Guide) RFID login) , i have been working few improvements to the arduino software example.  The biggest change is now having a serial terminal based menu interface. Also a few security concerns have been addressed, this includes limiting the number of wrong tries. As with the previous version not for sercuity applications, for hobby use only.

 

Improvements

  1. Wrong RFID Card tries are limited to 3 without a reset option
  2. All configuration can be done via a serial terminal therefore no need to use Arduino IDE .
  3. All options are selected from a simple menu which requires a password to use.
  4. Password and two card IDs can be store.

EEPROM Stored Data

Number of failed tries , password and the two card Uids are all stored in the eeprom.  Although  there is no encryption currently,  each character of data is stored in a random location set by the user controlled Eeprom address array.  Providing this array of addresses is set in a random sequence it should make it difficult to work out the users password if the whole eeprom was dumped.

 

How to use

For wiring please see previous (project / Guide) RFID login).

The only Arduino library required is the Arduino library for MFRC522 .

1) Change the optional user setting: menu password and address array .

When compiled and copied to the arduino…

2) Set a serial term to 9600 and arduinos serial port.  (Arduino built in Term works ok)

3) Typing in Menu_password (Default = admin)  followed by a CRLF will show the menu

4) simply type a menu option followed by a CRLF and then follow instructions

 

 

Code

// RFID Login Ver 2.0 with menu Example By Luke (www.ls-homeprojects.co.uk)
// Free to use this code how you like but please link my site
// Modified example for Arduino library for MFRC522. 
// Credit to Miguel Balboa for provided a great library and examples ! https://github.com/miguelbalboa/rfid.
 
// Please note this is just a proof of concept Example and should not be used for security applications !
 

#include "Keyboard.h"
#include "HID.h"	 // This is required for this to work with window 10
#include <SPI.h>
#include <MFRC522.h>  //This is the only library addition to standard Arduino.
#include <EEPROM.h>


#define SS_PIN 10
#define RST_PIN 5
 
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
MFRC522::MIFARE_Key key; 

#define MAX_LINE 20
char line[MAX_LINE + 1];

int Menu_mode=0; // 0 =normal menu off , 1=menu , 2=enter password ,3=confirm password , 4=Save new card 1 , 5= Save new card, 8 =reset tries

//###############################################  settings ###############################################################

char* admin_pass = "admin";  //change this


int eeprom_loc[] = {10,40,22,33,244,66,5,2,3,55,9,7,31,77,84,20,44,8,99,16,4,12,221,79,68,35,91,52,39,32,22,144,155,167,189,149,88,24,29,59,19,78,15};
//Please modify this array to contain random squence of numbers 1 - 255 for epprom addresses to spread password chars 
//across the eeprom making it very difficult to work out if someone dumped the whole contents of eeprom. 

//##########################################################################################################################

String pass1 ;
boolean print_text = false;

int pass_start_loc = 2; // Password loc allow 20 char space for password
int card_1_start_loc = 22; 
int card_2_start_loc = 33;


long code1=0;  // holds card 1 after load from eeprom
long code2=0;  // holds card 1 after load from eeprom

int tries = 0;  // hold card failed tries , 3 max


// Init array that will store new NUID 
byte nuidPICC[3];

void setup() { 

Serial.begin(9600);
///while (!Serial) {
  //; // wait for serial port to connect. Needed for native USB port only
  //}


tries =   EEPROM.read(eeprom_loc[1]);         		//Read failed tries at startup 
code1 =  epprom_read(card_1_start_loc).toInt();		//load card 1 id from eeprom
code2 =  epprom_read(card_2_start_loc).toInt();		//load card 2 id from eeprom
delay(500);
Keyboard.begin();
delay(500);
  
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522 


}
 
void loop() {



menu(); // Run the serial Menu !




  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been read
  if ( ! rfid.PICC_ReadCardSerial())
    return;

//  Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  //Serial.println(rfid.PICC_GetTypeName(piccType));

  // Check is the PICC of Classic MIFARE type
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
   // Serial.println(F("Your tag is not of type MIFARE Classic."));
    return;
  }

  if (rfid.uid.uidByte[0] != nuidPICC[0] || 
    rfid.uid.uidByte[1] != nuidPICC[1] || 
    rfid.uid.uidByte[2] != nuidPICC[2] || 
    rfid.uid.uidByte[3] != nuidPICC[3] ) {
   // Serial.println(F("A new card has been detected."));

    // Store NUID into nuidPICC array
    for (byte i = 0; i < 4; i++) {
      nuidPICC[i] = rfid.uid.uidByte[i];
    }
   
   
// CONVERT UID into Unsigned int as easier to match up to a saved value.
 unsigned long UID_unsigned;
  UID_unsigned =  rfid.uid.uidByte[0] << 24;
  UID_unsigned += rfid.uid.uidByte[1] << 16;
  UID_unsigned += rfid.uid.uidByte[2] <<  8;
  UID_unsigned += rfid.uid.uidByte[3];



  String UID_string =  (String)UID_unsigned;
  long UID_LONG=(long)UID_unsigned;

 

  if (Menu_mode==4){    //store card 1  
	  Serial.println("card1 is:");
	  Serial.println(UID_LONG);
	  epprom_write(UID_string ,card_1_start_loc); 
      delay(2000);
	  }
  
    if (Menu_mode==5){	 //store card 2  
	  Serial.println("card2 is:");
	  Serial.println(UID_LONG);
	  epprom_write(UID_string ,card_2_start_loc); 
	  delay(2000);
  }
  
  
  
  
  if (tries < 3){   // check if its been less than three wrong cards !
  
  
  
if (UID_LONG == code1|| UID_LONG == code2) {  // IF Presented card = stored card 1 or 2  then... type password in !
delay(1000);
Keyboard.write(KEY_RETURN); 				// modify key sequence here for other logins other than windows 8/10 !
delay(1200);
Keyboard.print(epprom_read(pass_start_loc));  //keyboard type in your stored password

delay(400);
Keyboard.write(KEY_RETURN);

delay(400);

nuidPICC[0] = 0;						// Simple fix to allow the same card to work with this rc522 Example
}

else {
delay(1200);

Serial.println("wrong card !");
tries = tries + 1;
EEPROM.write(eeprom_loc[1], tries );     // write the failed no. of tries to eeprom
}


}

else

{

Serial.println("too many ties lockout , please reset");
    
}

}
else 
	
//Serial.println(F("Card read previously."));

  // Halt PICC
rfid.PICC_HaltA();

  // Stop encryption on PCD
rfid.PCD_StopCrypto1();


}




// reads serial port CR lines

boolean lineAvailable(int max_line,char *line){    
     int c;
     static int line_idx = 0;
      //line_idx = 0;
     static boolean eol = false;
     if (max_line <= 0)    // handle bad values for max_line
     {
       eol = true;
       if (max_line == 0)
         line[0] = '\0';
     }
     else                // valid max_line
     {
       if (Serial.available() > 0)
       {
         c = Serial.read();
         if (c != -1)  // got a char -- should always be true
         {
                       if (c == '\r' || c == '\n'){
                             eol = true;
                              
                                 // lcd.print(c);
                       }
                       else
                             line[line_idx++] = c;
                       if (line_idx >= max_line)
                             eol = true;
                       line[line_idx] = '\0';     // always terminate line, even if unfinished
                 }
                 if (eol)
                 {

                  
if (Menu_mode==2){   // mode is input new password 

  if (line_idx > 1){ // check serial line is not empty
	delay(400);

    pass1 = line; // store incoming serial line as password 

    
    Serial.println("please re enter password");
	
	//Serial.println("yourpassword is");
  //  Serial.println(line);
	
	
    line_idx = 0;           // reset for next line
	
    eol = false;            // get ready for another line
    delay(1000);
	
	
	
	Menu_mode=3;			// set mode to confirm password !
	return true;
  }
}



if (Menu_mode==3){  // mode is confirm password 
if (line_idx > 1){ // check serial line is not empty

//Serial.println("yourpassword is");
// Serial.println(line);



 if (pass1 == line){ // check new serial line is same as prev 

 delay(400);
Serial.println("passwords match !");

 //delay(1000);
epprom_write(line ,pass_start_loc);   //store new password 

   print_text = false;
}



else{
Serial.println("passwords dont match please try again");
Serial.println();
Serial.println();
Serial.println();
Serial.println("please enter new password:");
Menu_mode=2; //enable enter new password again
    
}
}
}


                  
line_idx = 0;           // reset for next line
eol = false;             // get ready for another line
return true;
 }
 else
return false;
       }
     }
 

}








void epprom_write(String data ,int strt_loc ) {
	if (Menu_mode > 2) {  

int loc = 0;
int i;
int en = 0;
en = data.length()  + strt_loc;  // address for null to terminate data in eeprom 

for (i = 0; i < data.length() ; i++){

loc = eeprom_loc[i + strt_loc]; 
delay(200);
EEPROM.write(loc, data[i]);  //write char
}
delay(400);
EEPROM.write(eeprom_loc[en], 0x00); // terminate data
Serial.println();
Serial.println("Save complete");
Serial.println();
delay(900);
Menu_mode = 0;   	//Exit menu system
return;
}
}







String epprom_read(int strt_loc ) {
char text_p [30];
int loc = 0;
int i;
int da = 0;
int daidx = 0;


for (i=0; i  < 254; i++){ 
	
loc = eeprom_loc[i + strt_loc];  // read from start loc to end of eeprom 
da = EEPROM.read(loc);

if (daidx > 20){   // Simple fix to return 0 if more than 20 chars or a blank eeprom with no null spacing. 
return "0";
  
}


if (da == 0 ){                  // if read null then its the end of word
text_p[daidx] =  '\0' ;			// terminate string
return text_p ;					// return complete string
}

else

{
text_p[daidx] = char(da);     // convert byte to char and then add to string
daidx = daidx + 1;
}
}

//Serial.println(text_p);
}








void menu(){


if (lineAvailable(MAX_LINE,line))    //If new serial port line arrives 
{

  if (strcmp (line, "prom") == 0)
   {

Serial.println(epprom_read(pass_start_loc));
delay(400);
Serial.println(epprom_read(card_1_start_loc));
}

      

if (Menu_mode==0) { 

if (print_text == false){
Serial.println("please enter admin password to login:");
print_text = true;
}
}



if (strcmp (line, admin_pass) == 0)    //if admin pass is typed in
  {
 Serial.println("welcome to RFID menu by www.ls-homeprojects.co.uk");
  print_text = false;

 
  Menu_mode = 1; //enable menu 
  
  line[0] = 0;  // clear serial buffer so cmd is only executed once
  }




//menu
if (Menu_mode==1){
  if (print_text == false){     //only print once !

    
Serial.println();
Serial.println("please type an option followed by enter");
Serial.println();
Serial.println("[1] Reset too many rfid tries");
Serial.println("[2] Set new password");
Serial.println("[3] Pair card 1");
Serial.println("[4] Pair card 2");
Serial.println("[x] Exit");
print_text = true;
  }



if (strcmp (line, "1") == 0)
   {

  
  Menu_mode=0; //exit menu
  tries = 0;   //reset tries
  EEPROM.write(eeprom_loc[1], 0 );  //reset tries in eeprom
  
  Serial.print("reset done!");
  line[0] = 0;  // clear serial buffer so cmd is only executed once
  

  return;
   }


if (strcmp (line, "2") == 0)
   {
  
	Serial.println();
    Serial.println("please enter new password:");
    Menu_mode=2; //enable enter pass mode 
    line[0] = 0;  // clear serial buffer so cmd is only executed once

   }
   

  if (strcmp (line, "3") == 0)
   {
	Serial.println();
    Serial.println("please scan new card 1:");
     Menu_mode=4; //enable record card 1
     line[0] = 0;  // clear serial buffer so cmd is only executed once
   }
   
  
   if (strcmp (line, "4") == 0)
   {
	Serial.println();
    Serial.println("please scan new card 2:");
     Menu_mode=5; //enable record card 2
     line[0] = 0;  // clear serial buffer so cmd is only executed once
   }
  
  
   if (strcmp (line, "x") == 0)
   {
	   Menu_mode=0; //Exit menu !
     line[0] = 0;  // clear serial buffer so cmd is only executed once
   } 
}
}  
}






 

 

 

 

 

 

post image

I wanted a simple way of quickly logging on to my computer without having to typing my password in and did not want to have no security either.

There are various products on the market that would solve this problem from fingerprint readers to proximity dongles but i decided to see what i could knock up with parts i mainly already had.

Looking in my micro stuff i had a RC522 RFID tag reader 3.3v :

Also an 3.3v arduino Leonardo clone aswell based on a sparkfun pro micro which also can act as a USB device such as a keyboard. This is useful as if a 5v arduino was used a level shifter would be required due to the RC522 not being 5v torrent.

1 2