Version 1.2.0:

- Ticker increments clockCnt on exit (first hook call with clockCnt=0)

- Protocol startup phase closer to original:
  - id155[0] set to 0xFF on Init
  - Transition from Init to Ready after 100 ms
  - 3MW timing changed to 200 ms
  - id155[3] update coupled to 3MW switch

- Added API functions to query charger infos:
  - int getChargerTemperature();
  - float getDCConverterCurrent();
  - bool isPluggedIn();
  - bool isSwitchedOn();
This commit is contained in:
Michael Balzer 2017-07-29 11:09:14 +02:00
parent 6f2585c865
commit ac5241a61d
7 changed files with 85 additions and 16 deletions

15
API.md
View file

@ -97,6 +97,21 @@ Note: all control functions validate their parameters. If you pass any value out
| `TWIZY_SERV_STOP` | Set SERV + STOP indicator + beep | | `TWIZY_SERV_STOP` | Set SERV + STOP indicator + beep |
## Info access
- `int getChargerTemperature()` -- Get internal charger temperature
- result: -40 .. 100 (°C, resolution 1 °C)
- Hint: use this to protect the charger against over temperature by reducing the charge current
- `float getDCConverterCurrent()` -- Get DC/DC converter current level
- result: 0 .. 51 (A, resolution 1/5 A)
- `bool isPluggedIn()` -- Get power grid connection status
- result: true = 230V detected
- `bool isSwitchedOn()` -- Get key switch status
- result: true = key turned
## User callback registration ## User callback registration

View file

@ -1,5 +1,19 @@
# History # History
## Version 1.2.0 (2017-07-29)
- Ticker increments clockCnt on exit (first hook call with clockCnt=0)
- Protocol startup phase closer to original:
- id155[0] set to 0xFF on Init
- Transition from Init to Ready after 100 ms
- 3MW timing changed to 200 ms
- id155[3] update coupled to 3MW switch
- Added API functions to query charger infos:
- int getChargerTemperature();
- float getDCConverterCurrent();
- bool isPluggedIn();
- bool isSwitchedOn();
## Version: 1.1.0 (2017-06-20) ## Version: 1.1.0 (2017-06-20)

View file

@ -76,8 +76,8 @@ unsigned long error = TWIZY_OK;
// //
void bmsEnterState(TwizyState currentState, TwizyState newState) { void bmsEnterState(TwizyState currentState, TwizyState newState) {
// lower soc to prevent immediate charge stop: // lower SOC at switch-on to prevent immediate charge stop:
if (newState == Init) { if (currentState == Init && newState == Ready) {
if (soc > 99) { if (soc > 99) {
soc -= 1; soc -= 1;
twizy.setSOC(soc); twizy.setSOC(soc);

View file

@ -83,7 +83,7 @@ void bmsEnterState(TwizyState currentState, TwizyState newState) {
// The charger will not start charging at SOC=100%, so lower a too // The charger will not start charging at SOC=100%, so lower a too
// high SOC on wakeup to enable topping-off charges: // high SOC on wakeup to enable topping-off charges:
if (newState == Init) { if (currentState == Init && newState == Ready) {
if (soc > 99) { if (soc > 99) {
soc -= 1; soc -= 1;
twizy.setSOC(soc); twizy.setSOC(soc);

Binary file not shown.

View file

@ -28,6 +28,11 @@ setCurrent KEYWORD2
setCurrentQA KEYWORD2 setCurrentQA KEYWORD2
setError KEYWORD2 setError KEYWORD2
getChargerTemperature KEYWORD2
getDCConverterCurrent KEYWORD2
isPluggedIn KEYWORD2
isSwitchedOn KEYWORD2
attachEnterState KEYWORD2 attachEnterState KEYWORD2
attachCheckState KEYWORD2 attachCheckState KEYWORD2
attachProcessCanMsg KEYWORD2 attachProcessCanMsg KEYWORD2

View file

@ -38,7 +38,7 @@
#ifndef _TwizyVirtualBMS_h #ifndef _TwizyVirtualBMS_h
#define _TwizyVirtualBMS_h #define _TwizyVirtualBMS_h
#define TWIZY_VBMS_VERSION "V1.1.0 (2017-06-20)" #define TWIZY_VBMS_VERSION "V1.2.0 (2017-07-29)"
#ifndef TWIZY_TAG #ifndef TWIZY_TAG
#define TWIZY_TAG "twizy." #define TWIZY_TAG "twizy."
@ -207,6 +207,11 @@ public:
bool setTemperature(int tempMin, int tempMax, bool deriveModules); bool setTemperature(int tempMin, int tempMax, bool deriveModules);
bool setError(unsigned long error); bool setError(unsigned long error);
int getChargerTemperature();
float getDCConverterCurrent();
bool isPluggedIn();
bool isSwitchedOn();
// State access: // State access:
TwizyState state() { TwizyState state() {
return twizyState; return twizyState;
@ -365,7 +370,7 @@ bool TwizyVirtualBMS::setCurrent(float amps) {
} }
// Set battery pack current level (native 1/4 A resolution) // Set battery pack current level (native 1/4 A resolution)
// milliamps: -2000 .. +2000 (positive = charge, negative = discharge) // quarterAmps: -2000 .. +2000 (positive = charge, negative = discharge)
bool TwizyVirtualBMS::setCurrentQA(long quarterAmps) { bool TwizyVirtualBMS::setCurrentQA(long quarterAmps) {
CHECKLIMIT(quarterAmps, -2000L, 2000L); CHECKLIMIT(quarterAmps, -2000L, 2000L);
unsigned int level = 2000 + quarterAmps; unsigned int level = 2000 + quarterAmps;
@ -525,6 +530,26 @@ bool TwizyVirtualBMS::setError(unsigned long error) {
} }
// Get charger temperature
int TwizyVirtualBMS::getChargerTemperature() {
return (int) id597[7] - 40;
}
// Get DC converter current
float TwizyVirtualBMS::getDCConverterCurrent() {
return (float) id597[2] / 5;
}
// Get plugin status
bool TwizyVirtualBMS::isPluggedIn() {
return ((id597[0] & 0x20) != 0);
}
// Get key switch status
bool TwizyVirtualBMS::isSwitchedOn() {
return ((id597[1] & 0x10) != 0);
}
// ----------------------------------------------------- // -----------------------------------------------------
// Twizy CAN interface // Twizy CAN interface
@ -667,9 +692,6 @@ bool TwizyVirtualBMS::sendMsg(INT32U id, INT8U len, INT8U *buf) {
void TwizyVirtualBMS::ticker() { void TwizyVirtualBMS::ticker() {
if (++clockCnt == 3000)
clockCnt = 0;
// Note: currently we turn off all CAN sends in state Error, // Note: currently we turn off all CAN sends in state Error,
// as that reliably lets the SEVCON and charger switch off. // as that reliably lets the SEVCON and charger switch off.
// It may be an option to only turn off ID 554 (or all 55x) // It may be an option to only turn off ID 554 (or all 55x)
@ -715,18 +737,19 @@ void TwizyVirtualBMS::ticker() {
// //
// Create 3MW pulse cycle // Create 3MW pulse cycle
// (high 150ms → low 150ms → high) // (high 200ms → low 200ms → high)
// //
if (counter3MW > 0) { if (counter3MW > 0) {
--counter3MW; --counter3MW;
// 3MW low after 150 ms: // 3MW low after 200 ms:
if (counter3MW == 15) { if (counter3MW == 20) {
digitalWrite(TWIZY_3MW_CONTROL_PIN, 0); digitalWrite(TWIZY_3MW_CONTROL_PIN, 0);
} }
// 3MW high after 300 ms (pulse finished): // 3MW high after 400 ms (pulse finished):
else if (counter3MW == 0) { else if (counter3MW == 0) {
digitalWrite(TWIZY_3MW_CONTROL_PIN, 1); digitalWrite(TWIZY_3MW_CONTROL_PIN, 1);
id155[3] = 0x54;
} }
} }
@ -739,6 +762,10 @@ void TwizyVirtualBMS::ticker() {
// Transition to Ready? // Transition to Ready?
case Init: case Init:
// …from Init after first 100 ms:
if (clockCnt < 9) {
break;
}
case StopDrive: case StopDrive:
case StopCharge: case StopCharge:
case StopTrickle: case StopTrickle:
@ -791,6 +818,14 @@ void TwizyVirtualBMS::ticker() {
if (bmsTicker) { if (bmsTicker) {
(*bmsTicker)(clockCnt); (*bmsTicker)(clockCnt);
} }
//
// Cyclic clock counter
//
if (++clockCnt == 3000)
clockCnt = 0;
} }
@ -877,6 +912,7 @@ void TwizyVirtualBMS::enterState(TwizyState newState) {
case Off: case Off:
case Init: case Init:
id155[0] = 0xFF;
id155[3] = 0x94; id155[3] = 0x94;
id424[0] = 0x00; id424[0] = 0x00;
id425[0] = 0x1D; id425[0] = 0x1D;
@ -895,11 +931,10 @@ void TwizyVirtualBMS::enterState(TwizyState newState) {
break; break;
case Ready: case Ready:
// restore minimum charge current level: // restore minimum charge current level after stop/init:
if (id155[0] == 0) { if (id155[0] == 0 || id155[0] == 0xFF) {
id155[0] = 1; id155[0] = 1;
} }
id155[3] = 0x54;
// keep stop charge request if set: // keep stop charge request if set:
if (id424[0] != 0x12) { if (id424[0] != 0x12) {
id424[0] = 0x11; id424[0] = 0x11;
@ -909,7 +944,7 @@ void TwizyVirtualBMS::enterState(TwizyState newState) {
if (digitalRead(TWIZY_3MW_CONTROL_PIN) == 0) { if (digitalRead(TWIZY_3MW_CONTROL_PIN) == 0) {
// ...start 3MW pulse cycle: // ...start 3MW pulse cycle:
digitalWrite(TWIZY_3MW_CONTROL_PIN, 1); digitalWrite(TWIZY_3MW_CONTROL_PIN, 1);
counter3MW = 30; counter3MW = 40;
} }
break; break;