Skip to content

Commit

Permalink
Mennekes lock revamp
Browse files Browse the repository at this point in the history
  • Loading branch information
lincomatic committed Dec 2, 2021
1 parent 5dde798 commit 2b53190
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 42 deletions.
17 changes: 17 additions & 0 deletions firmware/open_evse/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
Change Log

20211201 SCL V8.1.0a
- added ECVF_TIMER_ON so we don't have to poll to test if delay timer is on
- revamp MENNEKES_LOCK
-> auto mode: locked when EVSE connected, unlocked when disconnected
-> to implement this, need to get rid of states were pilot = N12, because
we can't detect connection state
-> don't ever set pilot to N12, even in fault states. only set to N12
in EVSE_STATE_DISABLED
-> always automatically unlocks in EVSE_STATE_DISABLED, even if
in manual mode
-> add recoverable parameter to HardFault()
-> add volatile manual mode - when enabled, Mennekes lock is under full manual
control
-> add S5/G5 RAPI commands to set/fetch Mennekes settings
-> ECVF_MENNEKES_MANUAL also reflects auto/manual mode
- RAPIVER 5.2.0
- usurped ECVF_AMMETER_CAL with ECVF_MENNEKES_MANUAL, so the code is currently turned off
20211201 SCL V8.0.0d
- more refinements to CGMI - POST stuck relay check
20211128 SCL V8.0.0c
Expand Down
31 changes: 16 additions & 15 deletions firmware/open_evse/J1772EvseController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,6 @@ void J1772EVSEController::HardFault(int8_t recoverable)
#ifdef RAPI
RapiSendEvseState();
#endif
#ifdef MENNEKES_LOCK
m_MennekesLock.Unlock();
#endif // MENNEKES_LOCK
while (1) {
ProcessInputs(); // spin forever or until user resets via menu
// if pilot not in N12 state, we can recover from the hard fault when EV
Expand Down Expand Up @@ -541,6 +538,10 @@ void J1772EVSEController::Disable()
m_EvseState = EVSE_STATE_DISABLED;
// panic stop so we won't wait for EV to open its contacts first
chargingOff();
#ifdef MENNEKES_LOCK
if (!MennekesIsManual()) m_MennekesLock.Unlock(1);
#endif // MENNEKES_LOCK

g_OBD.Update(OBD_UPD_FORCE);
#ifdef RAPI
RapiSendEvseState();
Expand Down Expand Up @@ -1193,8 +1194,18 @@ void J1772EVSEController::ReadPilot(uint16_t *plow,uint16_t *phigh)
else ClrEvConnectedPrev();

// can determine connected state only if not -12VDC
if (ph >= m_ThreshData.m_ThreshAB) ClrEvConnected();
else SetEvConnected();
if (ph >= m_ThreshData.m_ThreshAB) {
ClrEvConnected();
#ifdef MENNEKES_LOCK
if (!MennekesIsManual()) m_MennekesLock.Unlock(0);
#endif // MENNEKES_LOCK
}
else {
SetEvConnected();
#ifdef MENNEKES_LOCK
if (!MennekesIsManual()) m_MennekesLock.Lock(0);
#endif // MENNEKES_LOCK
}
}

if (plow) {
Expand Down Expand Up @@ -1623,16 +1634,6 @@ if (TempChkEnabled()) {

// state transition
if (forcetransition || (m_EvseState != prevevsestate)) {
#ifdef MENNEKES_LOCK
if (m_EvseState == MENNEKES_LOCK_STATE) {
m_MennekesLock.Lock();
}
else {
m_MennekesLock.Unlock();
}
#endif // MENNEKES_LOCK


if (m_EvseState == EVSE_STATE_A) { // EV not connected
chargingOff(); // turn off charging current
m_Pilot.SetState(PILOT_STATE_P12);
Expand Down
13 changes: 11 additions & 2 deletions firmware/open_evse/J1772EvseController.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
* This file is part of Open EVSE.
*
* Copyright (c) 2011-2019 Sam C. Lin
* Copyright (c) 2011-2021 Sam C. Lin
*
* Open EVSE is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -389,7 +389,7 @@ class J1772EVSEController {
uint8_t ReadACPins();
#endif // ADVPWR

void HardFault(uint8_t recoverable);
void HardFault(int8_t recoverable);

void SetLimitSleep(int8_t tf) {
if (tf) setVFlags(ECVF_LIMIT_SLEEP);
Expand Down Expand Up @@ -572,6 +572,15 @@ int GetHearbeatTrigger();
void SetMV(uint32_t mv) { m_Voltage = mv; }
#endif
int32_t GetVoltage() { return m_Voltage; }
#ifdef MENNEKES_LOCK
void SetMennekesManual() { m_wVFlags |= ECVF_MENNEKES_MANUAL; }
void ClrMennekesManual() { m_wVFlags &= ~ECVF_MENNEKES_MANUAL; }
int8_t MennekesIsManual() { return (m_wVFlags & ECVF_MENNEKES_MANUAL) ? 1 : 0; }
int8_t MennekesIsLocked() { return m_MennekesLock.IsLocked(); }
void LockMennekes() { m_MennekesLock.Lock(1); }
void UnlockMennekes() { m_MennekesLock.Unlock(1); }
#endif // MENNEKES_LOCK

};

#ifdef FT_ENDURANCE
Expand Down
34 changes: 20 additions & 14 deletions firmware/open_evse/MennekesLock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
* Open EVSE Firmware
*
* Copyright (c) 2013-2014 Sam C. Lin <lincomatic@gmail.com>
* Copyright (c) 2013-2021 Sam C. Lin <lincomatic@gmail.com>
*
* This file is part of Open EVSE.
Expand Down Expand Up @@ -30,25 +30,31 @@ void MennekesLock::Init()
pinA.init(MENNEKES_LOCK_PINA_REG,MENNEKES_LOCK_PINA_IDX,DigitalPin::OUT);
pinB.init(MENNEKES_LOCK_PINB_REG,MENNEKES_LOCK_PINB_IDX,DigitalPin::OUT);

Unlock();
Unlock(1);
}

void MennekesLock::Lock()
void MennekesLock::Lock(int8_t force)
{
pinA.write(1);
pinB.write(0);
delay(300);
pinA.write(0);
pinB.write(0);
if (force || !isLocked) {
pinA.write(1);
pinB.write(0);
delay(300);
pinA.write(0);
pinB.write(0);
isLocked = 1;
}
}

void MennekesLock::Unlock()
void MennekesLock::Unlock(int8_t force)
{
pinA.write(0);
pinB.write(1);
delay(300);
pinA.write(0);
pinB.write(0);
if (force || isLocked) {
pinA.write(0);
pinB.write(1);
delay(300);
pinA.write(0);
pinB.write(0);
isLocked = 0;
}
}

#endif // MENNEKES_LOCK
8 changes: 5 additions & 3 deletions firmware/open_evse/MennekesLock.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
* Open EVSE Firmware
*
* Copyright (c) 2016 Sam C. Lin <lincomatic@gmail.com>
* Copyright (c) 2013-2021 Sam C. Lin <lincomatic@gmail.com>
*
* This file is part of Open EVSE.
Expand All @@ -24,11 +24,13 @@
#pragma once

class MennekesLock {
int8_t isLocked;
DigitalPin pinA;
DigitalPin pinB;
public:
MennekesLock() {}
void Init();
void Lock();
void Unlock();
void Lock(int8_t force);
void Unlock(int8_t force);
int8_t IsLocked() { return isLocked; }
};
6 changes: 2 additions & 4 deletions firmware/open_evse/open_evse.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#define clrBits(flags,bits) (flags &= ~(bits))

#ifndef VERSION
#define VERSION "D8.0.0d"
#define VERSION "D8.1.0a"
#endif // !VERSION

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

// support Mennekes (IEC 62196) type 2 locking pin
//#define MENNEKES_LOCK
#define MENNEKES_LOCK

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

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

//D11 - MOSI
#define MENNEKES_LOCK_PINA_REG &PINB
Expand Down
2 changes: 1 addition & 1 deletion firmware/open_evse/open_evse.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
* Open EVSE Firmware
*
* Copyright (c) 2011-2019 Sam C. Lin
* Copyright (c) 2011-2021 Sam C. Lin
* Copyright (c) 2011-2014 Chris Howell <chris1howell@msn.com>
* timer code Copyright (c) 2013 Kevin L <goldserve1@hotmail.com>
* portions Copyright (c) 2014-2015 Nick Sayer <nsayer@kfu.com>
Expand Down
33 changes: 32 additions & 1 deletion firmware/open_evse/rapi_proc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
* Open EVSE Firmware
*
* Copyright (c) 2013-2019 Sam C. Lin <lincomatic@gmail.com>
* Copyright (c) 2013-2021 Sam C. Lin <lincomatic@gmail.com>
*
* This file is part of Open EVSE.
Expand Down Expand Up @@ -420,6 +420,29 @@ int EvseRapiProcessor::processCmd()
}
break;
#endif // AUTH_LOCK && !AUTH_LOCK_REG
#ifdef MENNEKES_LOCK
case '5': // mennekes setting
if (tokenCnt == 2) {
rc = 0;
switch(*tokens[1]) {
case '0':
g_EvseController.UnlockMennekes();
break;
case '1':
g_EvseController.LockMennekes();
break;
case 'A':
g_EvseController.ClrMennekesManual();
break;
case 'M':
g_EvseController.SetMennekesManual();
break;
default:
rc = 1;
}
}
break;
#endif // MENNEKES_LOCK
#ifdef AMMETER
case 'A':
if (tokenCnt == 3) {
Expand Down Expand Up @@ -599,6 +622,14 @@ int EvseRapiProcessor::processCmd()
rc = 0;
break;
#endif // AUTH_LOCK && !AUTH_LOCK_REG
#ifdef MENNEKES_LOCK
case '5': // get mennekes setting
sprintf(buffer,"%d %c",g_EvseController.MennekesIsLocked(),
g_EvseController.MennekesIsManual() ? 'M' : 'A');
bufCnt = 1; // flag response text output
rc = 0;
break;
#endif // MENNEKES_LOCK
#ifdef AMMETER
case 'A':
u1.i = g_EvseController.GetCurrentScaleFactor();
Expand Down
20 changes: 18 additions & 2 deletions firmware/open_evse/rapi_proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/*
* Open EVSE Firmware
*
* Copyright (c) 2013-2019 Sam C. Lin <lincomatic@gmail.com>
* Copyright (c) 2013-2021 Sam C. Lin <lincomatic@gmail.com>
*
* This file is part of Open EVSE.
Expand Down Expand Up @@ -166,6 +166,12 @@ S4 0|1 - set auth lock (needs AUTH_LOCK defined and AUTH_LOCK_REG undefined)
1 = locked - EVSE won't charge until unlocked
when auth lock is on, will not transition to State C and a lock icon is
displayed in States A & B.
S5 A|M|0|1 - Mennekes lock setting
A = enable automatic mode - locked when connected, unlocked otherwise
M = enable manual control mode
0 = unlock (valid only in manual mode)
1 = lock (valid only in manual mode)
n.b. requires MENNEKES_LOCK. manual mode is volatile - always boots in automatic mode
SA currentscalefactor currentoffset - set ammeter settings
SC amps [V|M]- set current capacity
response:
Expand Down Expand Up @@ -230,6 +236,16 @@ G4 - get auth lock (needs AUTH_LOCK defined and AUTH_LOCK_REG undefined)
response: $OK lockstate
lockstate = 0=unlocked, =1=locked
$G4^57
G5 - get Mennekes settings
response: $OK state mode
state: 0 = unlocked
1 = locked
mode: A = automatic mode - locked when connected, unlocked otherwise
M = manual control mode
Note: lock mode is also indicated by ECVF_MENNEKES_MANUAL
n.b. requires MENNEKES_LOCK
GA - get ammeter settings
response: $OK currentscalefactor currentoffset
$GA^22
Expand Down Expand Up @@ -342,7 +358,7 @@ Z0 closems holdpwm

#ifdef RAPI

#define RAPIVER "5.1.4"
#define RAPIVER "5.2.0"

#define WIFI_MODE_AP 0
#define WIFI_MODE_CLIENT 1
Expand Down

0 comments on commit 2b53190

Please sign in to comment.