Skip to content

Commit 2b53190

Browse files
committed
Mennekes lock revamp
1 parent 5dde798 commit 2b53190

File tree

9 files changed

+122
-42
lines changed

9 files changed

+122
-42
lines changed

firmware/open_evse/CHANGELOG

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
Change Log
22

3+
20211201 SCL V8.1.0a
4+
- added ECVF_TIMER_ON so we don't have to poll to test if delay timer is on
5+
- revamp MENNEKES_LOCK
6+
-> auto mode: locked when EVSE connected, unlocked when disconnected
7+
-> to implement this, need to get rid of states were pilot = N12, because
8+
we can't detect connection state
9+
-> don't ever set pilot to N12, even in fault states. only set to N12
10+
in EVSE_STATE_DISABLED
11+
-> always automatically unlocks in EVSE_STATE_DISABLED, even if
12+
in manual mode
13+
-> add recoverable parameter to HardFault()
14+
-> add volatile manual mode - when enabled, Mennekes lock is under full manual
15+
control
16+
-> add S5/G5 RAPI commands to set/fetch Mennekes settings
17+
-> ECVF_MENNEKES_MANUAL also reflects auto/manual mode
18+
- RAPIVER 5.2.0
19+
- usurped ECVF_AMMETER_CAL with ECVF_MENNEKES_MANUAL, so the code is currently turned off
320
20211201 SCL V8.0.0d
421
- more refinements to CGMI - POST stuck relay check
522
20211128 SCL V8.0.0c

firmware/open_evse/J1772EvseController.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,6 @@ void J1772EVSEController::HardFault(int8_t recoverable)
358358
#ifdef RAPI
359359
RapiSendEvseState();
360360
#endif
361-
#ifdef MENNEKES_LOCK
362-
m_MennekesLock.Unlock();
363-
#endif // MENNEKES_LOCK
364361
while (1) {
365362
ProcessInputs(); // spin forever or until user resets via menu
366363
// if pilot not in N12 state, we can recover from the hard fault when EV
@@ -541,6 +538,10 @@ void J1772EVSEController::Disable()
541538
m_EvseState = EVSE_STATE_DISABLED;
542539
// panic stop so we won't wait for EV to open its contacts first
543540
chargingOff();
541+
#ifdef MENNEKES_LOCK
542+
if (!MennekesIsManual()) m_MennekesLock.Unlock(1);
543+
#endif // MENNEKES_LOCK
544+
544545
g_OBD.Update(OBD_UPD_FORCE);
545546
#ifdef RAPI
546547
RapiSendEvseState();
@@ -1193,8 +1194,18 @@ void J1772EVSEController::ReadPilot(uint16_t *plow,uint16_t *phigh)
11931194
else ClrEvConnectedPrev();
11941195

11951196
// can determine connected state only if not -12VDC
1196-
if (ph >= m_ThreshData.m_ThreshAB) ClrEvConnected();
1197-
else SetEvConnected();
1197+
if (ph >= m_ThreshData.m_ThreshAB) {
1198+
ClrEvConnected();
1199+
#ifdef MENNEKES_LOCK
1200+
if (!MennekesIsManual()) m_MennekesLock.Unlock(0);
1201+
#endif // MENNEKES_LOCK
1202+
}
1203+
else {
1204+
SetEvConnected();
1205+
#ifdef MENNEKES_LOCK
1206+
if (!MennekesIsManual()) m_MennekesLock.Lock(0);
1207+
#endif // MENNEKES_LOCK
1208+
}
11981209
}
11991210

12001211
if (plow) {
@@ -1623,16 +1634,6 @@ if (TempChkEnabled()) {
16231634

16241635
// state transition
16251636
if (forcetransition || (m_EvseState != prevevsestate)) {
1626-
#ifdef MENNEKES_LOCK
1627-
if (m_EvseState == MENNEKES_LOCK_STATE) {
1628-
m_MennekesLock.Lock();
1629-
}
1630-
else {
1631-
m_MennekesLock.Unlock();
1632-
}
1633-
#endif // MENNEKES_LOCK
1634-
1635-
16361637
if (m_EvseState == EVSE_STATE_A) { // EV not connected
16371638
chargingOff(); // turn off charging current
16381639
m_Pilot.SetState(PILOT_STATE_P12);

firmware/open_evse/J1772EvseController.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* This file is part of Open EVSE.
44
*
5-
* Copyright (c) 2011-2019 Sam C. Lin
5+
* Copyright (c) 2011-2021 Sam C. Lin
66
*
77
* Open EVSE is free software; you can redistribute it and/or modify
88
* it under the terms of the GNU General Public License as published by
@@ -389,7 +389,7 @@ class J1772EVSEController {
389389
uint8_t ReadACPins();
390390
#endif // ADVPWR
391391

392-
void HardFault(uint8_t recoverable);
392+
void HardFault(int8_t recoverable);
393393

394394
void SetLimitSleep(int8_t tf) {
395395
if (tf) setVFlags(ECVF_LIMIT_SLEEP);
@@ -572,6 +572,15 @@ int GetHearbeatTrigger();
572572
void SetMV(uint32_t mv) { m_Voltage = mv; }
573573
#endif
574574
int32_t GetVoltage() { return m_Voltage; }
575+
#ifdef MENNEKES_LOCK
576+
void SetMennekesManual() { m_wVFlags |= ECVF_MENNEKES_MANUAL; }
577+
void ClrMennekesManual() { m_wVFlags &= ~ECVF_MENNEKES_MANUAL; }
578+
int8_t MennekesIsManual() { return (m_wVFlags & ECVF_MENNEKES_MANUAL) ? 1 : 0; }
579+
int8_t MennekesIsLocked() { return m_MennekesLock.IsLocked(); }
580+
void LockMennekes() { m_MennekesLock.Lock(1); }
581+
void UnlockMennekes() { m_MennekesLock.Unlock(1); }
582+
#endif // MENNEKES_LOCK
583+
575584
};
576585

577586
#ifdef FT_ENDURANCE

firmware/open_evse/MennekesLock.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Open EVSE Firmware
44
*
5-
* Copyright (c) 2013-2014 Sam C. Lin <[email protected]>
5+
* Copyright (c) 2013-2021 Sam C. Lin <[email protected]>
66
*
77
* This file is part of Open EVSE.
88
@@ -30,25 +30,31 @@ void MennekesLock::Init()
3030
pinA.init(MENNEKES_LOCK_PINA_REG,MENNEKES_LOCK_PINA_IDX,DigitalPin::OUT);
3131
pinB.init(MENNEKES_LOCK_PINB_REG,MENNEKES_LOCK_PINB_IDX,DigitalPin::OUT);
3232

33-
Unlock();
33+
Unlock(1);
3434
}
3535

36-
void MennekesLock::Lock()
36+
void MennekesLock::Lock(int8_t force)
3737
{
38-
pinA.write(1);
39-
pinB.write(0);
40-
delay(300);
41-
pinA.write(0);
42-
pinB.write(0);
38+
if (force || !isLocked) {
39+
pinA.write(1);
40+
pinB.write(0);
41+
delay(300);
42+
pinA.write(0);
43+
pinB.write(0);
44+
isLocked = 1;
45+
}
4346
}
4447

45-
void MennekesLock::Unlock()
48+
void MennekesLock::Unlock(int8_t force)
4649
{
47-
pinA.write(0);
48-
pinB.write(1);
49-
delay(300);
50-
pinA.write(0);
51-
pinB.write(0);
50+
if (force || isLocked) {
51+
pinA.write(0);
52+
pinB.write(1);
53+
delay(300);
54+
pinA.write(0);
55+
pinB.write(0);
56+
isLocked = 0;
57+
}
5258
}
5359

5460
#endif // MENNEKES_LOCK

firmware/open_evse/MennekesLock.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Open EVSE Firmware
44
*
5-
* Copyright (c) 2016 Sam C. Lin <[email protected]>
5+
* Copyright (c) 2013-2021 Sam C. Lin <[email protected]>
66
*
77
* This file is part of Open EVSE.
88
@@ -24,11 +24,13 @@
2424
#pragma once
2525

2626
class MennekesLock {
27+
int8_t isLocked;
2728
DigitalPin pinA;
2829
DigitalPin pinB;
2930
public:
3031
MennekesLock() {}
3132
void Init();
32-
void Lock();
33-
void Unlock();
33+
void Lock(int8_t force);
34+
void Unlock(int8_t force);
35+
int8_t IsLocked() { return isLocked; }
3436
};

firmware/open_evse/open_evse.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#define clrBits(flags,bits) (flags &= ~(bits))
4242

4343
#ifndef VERSION
44-
#define VERSION "D8.0.0d"
44+
#define VERSION "D8.1.0a"
4545
#endif // !VERSION
4646

4747
#include "Language_default.h" //Default language should always be included as bottom layer
@@ -130,7 +130,7 @@ extern AutoCurrentCapacityController g_ACCController;
130130
#define TIME_LIMIT
131131

132132
// support Mennekes (IEC 62196) type 2 locking pin
133-
//#define MENNEKES_LOCK
133+
#define MENNEKES_LOCK
134134

135135
// Support for Nick Sayer's OpenEVSE II board, which has alternate hardware for ground check/stuck relay check and a voltmeter for L1/L2.
136136
//#define OPENEVSE_2
@@ -486,8 +486,6 @@ extern AutoCurrentCapacityController g_ACCController;
486486

487487
#ifdef MENNEKES_LOCK
488488
// requires external 12V H-bridge driver such as Polulu 1451
489-
#define MENNEKES_LOCK_STATE EVSE_STATE_B // lock in State B
490-
//#define MENNEKES_LOCK_STATE EVSE_STATE_C // lock in State C
491489

492490
//D11 - MOSI
493491
#define MENNEKES_LOCK_PINA_REG &PINB

firmware/open_evse/open_evse.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Open EVSE Firmware
44
*
5-
* Copyright (c) 2011-2019 Sam C. Lin
5+
* Copyright (c) 2011-2021 Sam C. Lin
66
* Copyright (c) 2011-2014 Chris Howell <[email protected]>
77
* timer code Copyright (c) 2013 Kevin L <[email protected]>
88
* portions Copyright (c) 2014-2015 Nick Sayer <[email protected]>

firmware/open_evse/rapi_proc.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Open EVSE Firmware
44
*
5-
* Copyright (c) 2013-2019 Sam C. Lin <[email protected]>
5+
* Copyright (c) 2013-2021 Sam C. Lin <[email protected]>
66
*
77
* This file is part of Open EVSE.
88
@@ -420,6 +420,29 @@ int EvseRapiProcessor::processCmd()
420420
}
421421
break;
422422
#endif // AUTH_LOCK && !AUTH_LOCK_REG
423+
#ifdef MENNEKES_LOCK
424+
case '5': // mennekes setting
425+
if (tokenCnt == 2) {
426+
rc = 0;
427+
switch(*tokens[1]) {
428+
case '0':
429+
g_EvseController.UnlockMennekes();
430+
break;
431+
case '1':
432+
g_EvseController.LockMennekes();
433+
break;
434+
case 'A':
435+
g_EvseController.ClrMennekesManual();
436+
break;
437+
case 'M':
438+
g_EvseController.SetMennekesManual();
439+
break;
440+
default:
441+
rc = 1;
442+
}
443+
}
444+
break;
445+
#endif // MENNEKES_LOCK
423446
#ifdef AMMETER
424447
case 'A':
425448
if (tokenCnt == 3) {
@@ -599,6 +622,14 @@ int EvseRapiProcessor::processCmd()
599622
rc = 0;
600623
break;
601624
#endif // AUTH_LOCK && !AUTH_LOCK_REG
625+
#ifdef MENNEKES_LOCK
626+
case '5': // get mennekes setting
627+
sprintf(buffer,"%d %c",g_EvseController.MennekesIsLocked(),
628+
g_EvseController.MennekesIsManual() ? 'M' : 'A');
629+
bufCnt = 1; // flag response text output
630+
rc = 0;
631+
break;
632+
#endif // MENNEKES_LOCK
602633
#ifdef AMMETER
603634
case 'A':
604635
u1.i = g_EvseController.GetCurrentScaleFactor();

firmware/open_evse/rapi_proc.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Open EVSE Firmware
44
*
5-
* Copyright (c) 2013-2019 Sam C. Lin <[email protected]>
5+
* Copyright (c) 2013-2021 Sam C. Lin <[email protected]>
66
*
77
* This file is part of Open EVSE.
88
@@ -166,6 +166,12 @@ S4 0|1 - set auth lock (needs AUTH_LOCK defined and AUTH_LOCK_REG undefined)
166166
1 = locked - EVSE won't charge until unlocked
167167
when auth lock is on, will not transition to State C and a lock icon is
168168
displayed in States A & B.
169+
S5 A|M|0|1 - Mennekes lock setting
170+
A = enable automatic mode - locked when connected, unlocked otherwise
171+
M = enable manual control mode
172+
0 = unlock (valid only in manual mode)
173+
1 = lock (valid only in manual mode)
174+
n.b. requires MENNEKES_LOCK. manual mode is volatile - always boots in automatic mode
169175
SA currentscalefactor currentoffset - set ammeter settings
170176
SC amps [V|M]- set current capacity
171177
response:
@@ -230,6 +236,16 @@ G4 - get auth lock (needs AUTH_LOCK defined and AUTH_LOCK_REG undefined)
230236
response: $OK lockstate
231237
lockstate = 0=unlocked, =1=locked
232238
$G4^57
239+
240+
G5 - get Mennekes settings
241+
response: $OK state mode
242+
state: 0 = unlocked
243+
1 = locked
244+
mode: A = automatic mode - locked when connected, unlocked otherwise
245+
M = manual control mode
246+
Note: lock mode is also indicated by ECVF_MENNEKES_MANUAL
247+
n.b. requires MENNEKES_LOCK
248+
233249
GA - get ammeter settings
234250
response: $OK currentscalefactor currentoffset
235251
$GA^22
@@ -342,7 +358,7 @@ Z0 closems holdpwm
342358

343359
#ifdef RAPI
344360

345-
#define RAPIVER "5.1.4"
361+
#define RAPIVER "5.2.0"
346362

347363
#define WIFI_MODE_AP 0
348364
#define WIFI_MODE_CLIENT 1

0 commit comments

Comments
 (0)