Skip to content

Commit

Permalink
Add option to use one RFID card to unlock/lock the EVSE
Browse files Browse the repository at this point in the history
  • Loading branch information
mstegen authored and bobosch committed Nov 2, 2021
1 parent 1f0bc9f commit 1eec945
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 13 deletions.
50 changes: 41 additions & 9 deletions SmartEVSE2.X/EVSE.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const char StrEnabled[] = "Enabled";
const char StrExitMenu[] = "MENU";
const char StrMainsAll[] = "All"; // Everything
const char StrMainsHomeEVSE[] = "Home+EVSE";
const char StrRFIDReader[5][10] = {"Disabled", "Enabled", "Learn", "Delete", "DeleteAll"};
const char StrRFIDReader[6][10] = {"Disabled", "EnableAll", "EnableOne", "Learn", "Delete", "DeleteAll"};
const char StrStateName[9][10] = {"A", "B", "C", "D", "COMM_B", "COMM_B_OK", "COMM_C", "COMM_C_OK", "Activate"};

// Global data
Expand Down Expand Up @@ -231,6 +231,7 @@ unsigned char idx = 0, idx2 = 0, ISRFLAG = 0, ISR2FLAG = 0, ISRTXFLAG = 0, ISRTX
unsigned char menu = 0;
unsigned int locktimer = 0, unlocktimer = 0; // solenoid timers
unsigned char lock1 = 0, lock2 = 1;
unsigned char UnlockCable = 0, LockCable = 0;
unsigned long Timer = 0; // mS counter
unsigned long ModbusTimer;
unsigned char BacklightTimer = 0; // Backlight timer (sec)
Expand Down Expand Up @@ -329,7 +330,8 @@ void interrupt high_isr(void)
{
if (Lock) // Cable lock enabled?
{
if (Error || (State != STATE_C)) {
// Unlock Cable
if (UnlockCable) {
if (unlocktimer < 600) { // 600ms pulse
SOLENOID_UNLOCK;
} else SOLENOID_OFF;
Expand All @@ -340,7 +342,8 @@ void interrupt high_isr(void)
} else unlocktimer = 700;
}
locktimer = 0;
} else { // State C
// Lock Cable
} else if (LockCable) {
if (locktimer < 600) { // 600ms pulse
SOLENOID_LOCK;
} else SOLENOID_OFF;
Expand Down Expand Up @@ -446,8 +449,10 @@ void validate_settings(void) {
}
}

// RFID reader set to Enable One card, the EVSE is disabled by default
if (RFIDReader == 2) Access_bit = 0;
// Enable access if no access switch used
if (Switch != 1 && Switch != 2) Access_bit = 1;
else if (Switch != 1 && Switch != 2) Access_bit = 1;
// Sensorbox v2 has always address 0x0A
if (MainsMeter == EM_SENSORBOX) MainsMeterAddress = 0x0A;
// Disable modbus reception on normal mode
Expand All @@ -458,7 +463,7 @@ void validate_settings(void) {
if (Lock == 1) { lock1=0; lock2=1; }
else if (Lock == 2) { lock1=1; lock2=0; }
// Erase all RFID cards from ram + eeprom if set to EraseAll
if (RFIDReader == 4) {
if (RFIDReader == 5) {
DeleteAllRFID();
}
// Default to modbus input registers
Expand Down Expand Up @@ -1124,7 +1129,7 @@ unsigned char getMenuItems (void) {
MenuItems[m++] = MENU_MAX; // Max Charge current (A)
MenuItems[m++] = MENU_SWITCH; // External Switch on SW (0:Disable / 1:Access / 2:Smart-Solar)
MenuItems[m++] = MENU_RCMON; // Residual Current Monitor on RCM (0:Disable / 1:Enable)
MenuItems[m++] = MENU_RFIDREADER; // RFID Reader connected to SW (0:Disable / 1:Enable / 2:Learn / 3:Delete / 4:Delate All)
MenuItems[m++] = MENU_RFIDREADER; // RFID Reader connected to SW (0:Disable / 1:EnableAll / 2:EnableOne / 3:Learn / 4:Delete / 5:Delete All)
if (Mode) { // ? Smart or Solar mode?
if (LoadBl < 2) { // - ? Load Balancing Disabled/Master?
MenuItems[m++] = MENU_MAINSMETER; // - - Type of Mains electric meter (0: Disabled / Constants EM_*)
Expand Down Expand Up @@ -1672,7 +1677,7 @@ void RS232cli(void) {
}
break;
case MENU_RFIDREADER:
for(i = 0; i < 5; i++) {
for(i = 0; i < 6; i++) {
if (strcmp(U2buffer, StrRFIDReader[i]) == 0) {
RFIDReader = i;
write_settings();
Expand Down Expand Up @@ -1796,7 +1801,7 @@ void RS232cli(void) {
break;
case MENU_RFIDREADER:
printf("RFID reader is set to: %s\nEnter new RFID reader mode (%s", getMenuItemOption(menu), StrRFIDReader[0]);
for(i = 1; i < 5; i++) {
for(i = 1; i < 6; i++) {
printf("/%s", StrRFIDReader[i]);
}
printf("): ");
Expand Down Expand Up @@ -2013,7 +2018,7 @@ void UpdateCurrentData(void) {
void main(void) {
unsigned char x, leftbutton, RB2low = 0;
unsigned char pilot, count = 0, timeout = 5;
unsigned char DiodeCheck = 0, ActivationMode = 0, ActivationTimer = 0;
unsigned char DiodeCheck = 0, ActivationMode = 0, ActivationTimer = 0, AccessTimer = 0;
unsigned char Broadcast = 1, RB2count = 0, RB2last = 1;
signed long CM[3]={0, 0, 0};
signed long PV[3]={0, 0, 0};
Expand Down Expand Up @@ -2187,6 +2192,20 @@ void main(void) {
}
}

// One RFID card can Lock/Unlock the charging socket (like a public charging station)
if (RFIDReader == 2) {
if (Access_bit == 0) UnlockCable = 1;
else UnlockCable = 0;
// The charging socket is unlocked when charging stops.
} else {
if (State != STATE_C) UnlockCable = 1;
else UnlockCable = 0;
}
// If the cable is connected to the EV, the cable will be locked.
if (State == STATE_B || State == STATE_C) LockCable = 1;
else LockCable = 0;


// ############### EVSE State A #################

if (State == STATE_A || State == STATE_COMM_B)
Expand All @@ -2200,6 +2219,10 @@ void main(void) {

if (pilot == PILOT_12V) { // Check if we are disconnected, or forced to State A, but still connected to the EV

// If the RFID reader is set to EnableOne mode, and the Charging cable is disconnected
// We start a timer to re-lock the EVSE (and unlock the cable) after 60 seconds.
if (RFIDReader == 2 && AccessTimer == 0 && Access_bit == 1) AccessTimer = RFIDLOCKTIME;

if (State == STATE_COMM_B) setState(STATE_A); // reset state, incase we were stuck in STATE_COMM_B
Error &= ~NO_SUN;
Error &= ~LESS_6A;
Expand Down Expand Up @@ -2232,6 +2255,7 @@ void main(void) {
setState(STATE_B); // switch to State B
ActivationMode = 30; // Activation mode is triggered if state C is not entered in 30 seconds.
BacklightTimer = BACKLIGHT; // Backlight ON
AccessTimer = 0;
}
}
} else {
Expand All @@ -2245,6 +2269,7 @@ void main(void) {
setState(STATE_B);
ActivationMode = 30; // Activation mode is triggered if state C is not entered in 30 seconds.
BacklightTimer = BACKLIGHT; // Backlight ON
AccessTimer = 0;
}

// ############### EVSE State B #################
Expand Down Expand Up @@ -2430,6 +2455,13 @@ void main(void) {

if (ChargeDelay) ChargeDelay--; // Decrease Charge Delay counter

if (AccessTimer && State == STATE_A) {
if (--AccessTimer == 0) {
Access_bit = 0; // re-lock EVSE
BacklightTimer = BACKLIGHT; // Backlight ON
}
} else AccessTimer = 0; // Not in state A, then disable timer

if ((TempEVSE < 55) && (Error & TEMP_HIGH)) // Temperature below limit?
{
Error &= ~TEMP_HIGH; // clear Error
Expand Down
3 changes: 2 additions & 1 deletion SmartEVSE2.X/EVSE.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#define RC_MON 0 // Residual Current Monitoring on IO3. Disabled=0, RCM14=1
#define CHARGEDELAY 60 // Seconds to wait after overcurrent, before trying again
#define BACKLIGHT 60 // Seconds delay for the LCD backlight to turn off.
#define RFIDLOCKTIME 60 // Seconds delay for the EVSE to lock again (RFIDreader = EnableOne)
#define START_CURRENT 4 // Start charging when surplus current on one phase exceeds 4A (Solar)
#define STOP_TIME 10 // Stop charging after 10 minutes at MIN charge current (Solar)
#define IMPORT_CURRENT 0 // Allow the use of grid power when solar charging (Amps)
Expand Down Expand Up @@ -360,7 +361,7 @@ const struct {
{"LOADBL", "LOAD BAL", "Set Load Balancing mode for 2-8 SmartEVSEs", 0, NR_EVSES, LOADBL},
{"SW", "SWITCH", "Switch function control on pin SW", 0, 4, SWITCH},
{"RCMON", "RCMON", "Residual Current Monitor on pin RCM", 0, 1, RC_MON},
{"RFID", "RFID", "Use RFID reader, learn/remove cards", 0, 4, RFID_READER},
{"RFID", "RFID", "Use RFID reader, learn/remove cards", 0, 5, RFID_READER},
{"EVEM", "EV METER", "Type of EV electric meter", 0, EM_CUSTOM, EV_METER},
{"EVAD", "EV ADDR", "Address of EV electric meter", MIN_METER_ADDRESS, MAX_METER_ADDRESS, EV_METER_ADDRESS},

Expand Down
23 changes: 20 additions & 3 deletions SmartEVSE2.X/OneWire.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ unsigned char DeleteRFID(void) {
// printf("deleted %u ",offset);
// for (r=0; r<120; r++) printf("%02x",RFIDlist[r]);

WriteRFIDlist();
return 1;
}

Expand All @@ -249,12 +250,13 @@ void DeleteAllRFID(void) {

void CheckRFID(void) {
unsigned char x;
static unsigned char cardoffset = 0;

// When RFID is enabled, a OneWire RFID reader is expected on the SW input
if (RFIDReader) { // RFID Reader set to Enabled, Learn or Delete
if (OneWireReadCardId() ) { // Read card ID
switch (RFIDReader) {
case 1: // Enabled
case 1: // EnableAll. All learned cards accepted for locking /unlocking
x = MatchRFID();
if (x && !RFIDstatus) {
//printf("RFID card found!\n");
Expand All @@ -267,7 +269,22 @@ void CheckRFID(void) {
} else if (!x) RFIDstatus = 7; // invalid card
BacklightTimer = BACKLIGHT;
break;
case 2: // Learn Card
case 2: // EnableOne. Only the card that unlocks, can re-lock the EVSE
x = MatchRFID();
if (x && !RFIDstatus) {
//printf("RFID card found!\n");
if (!Access_bit) {
cardoffset = x; // store cardoffset from current card
Access_bit = 1; // Access On
} else if (cardoffset == x) {
Access_bit = 0; // Access Off
setState(STATE_A); // Switch back to state A
}
RFIDstatus = 1;
} else if (!x) RFIDstatus = 7; // invalid card
BacklightTimer = BACKLIGHT;
break;
case 3: // Learn Card
x = StoreRFID();
if (x == 1) {
printf("\nRFID card stored!");
Expand All @@ -280,7 +297,7 @@ void CheckRFID(void) {
RFIDstatus = 6;
}
break;
case 3: // Delete Card
case 4: // Delete Card
x = DeleteRFID();
if (x) {
printf("\nRFID card deleted!");
Expand Down

0 comments on commit 1eec945

Please sign in to comment.