Skip to content

Commit

Permalink
Twizy-ChargeThrottle V1.0 (initial release)
Browse files Browse the repository at this point in the history
  • Loading branch information
dexterbg committed May 15, 2019
1 parent 90f6cff commit ad47994
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
assets
*.html
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# TwizyChargeThrottle

This is a very simple tool to limit the Twizy charge current if you don't have an OVMS.

It can currently only limit the charge current to a fixed level (defined in the config file).

The Arduino needs to be connected to the Twizy CAN bus during the charge process to be able
to actively overwrite the charge current control frames.

Note: using an interrupt capable CAN shield is highly recommended.


## Info

Author: Michael Balzer <dexter@dexters-web.de>

Libraries used:
- MCP_CAN: https://github.com/coryjfowler/MCP_CAN_lib

This is free software under GNU Lesser General Public License (LGPL)
https://www.gnu.org/licenses/lgpl.html
147 changes: 147 additions & 0 deletions TwizyChargeThrottle/TwizyChargeThrottle.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/**
* ==========================================================================
* Twizy charge current throttle
* ==========================================================================
*
* Author: Michael Balzer <dexter@dexters-web.de>
*
* Libraries used:
* - MCP_CAN: https://github.com/coryjfowler/MCP_CAN_lib
*
* License:
* This is free software under GNU Lesser General Public License (LGPL)
* https://www.gnu.org/licenses/lgpl.html
*
*/
#define TWIZY_CT_VERSION "V1.0 (2019-05-10)"

#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include "TwizyChargeThrottle_config.h"

// CAN interface:
MCP_CAN CAN(TWIZY_CAN_CS_PIN);

// CAN msg buffer:
unsigned long msgId;
byte msgLen;
byte msgBuf[8];

// Operation mode:
bool charging = false;

// Current level:
byte level = 0;


#if TWIZY_CAN_IRQ_PIN > 0
volatile bool msgReceived = false;
void canISR() {
msgReceived = true;
}
#endif


void setup() {

Serial.begin(SERIAL_SPEED);
Serial.println(F("TwizyChargeThrottle " TWIZY_CT_VERSION));

// Init CAN interface:

#if TWIZY_CAN_IRQ_PIN > 0
pinMode(TWIZY_CAN_IRQ_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(TWIZY_CAN_IRQ_PIN), canISR, FALLING);
#endif

while (CAN.begin(MCP_STDEXT, CAN_500KBPS, TWIZY_CAN_MCP_FREQ) != CAN_OK) {
Serial.println(F("Setup: waiting for CAN connection..."));
delay(1000);
}

// Set ID filters:

CAN.init_Mask(0, 0, 0x07FF0000);
CAN.init_Filt(0, 0, 0x01550000); // BMS → BMS: current control
CAN.init_Filt(1, 0, 0x05970000); // CHG → BMS: operation mode

CAN.init_Mask(1, 0, 0x07FF0000);
CAN.init_Filt(2, 0, 0x00000000);
CAN.init_Filt(3, 0, 0x00000000);
CAN.init_Filt(4, 0, 0x00000000);
CAN.init_Filt(5, 0, 0x00000000);

CAN.setMode(MCP_NORMAL);

Serial.println(F("Setup done."));

Serial.print(F("Throttling configured to current level: "));
Serial.println((char)('0' + TWIZY_CHARGE_THROTTLE));
}


void loop() {
while (true) {

#if TWIZY_CAN_IRQ_PIN > 0
// Wait for interrupt signal:
while (!msgReceived);
msgReceived = false;
#endif

// Process CAN read buffer:
while (CAN.readMsgBuf(&msgId, &msgLen, msgBuf) == CAN_OK)
{
if (msgId == 0x597)
{
// ID 0x597: operation mode

bool _charging = ((msgBuf[1] & 0x60) == 0x20);

#if TWIZY_DEBUG > 0
if (_charging && !charging)
Serial.println(F("Charge START"));
else if (!_charging && charging)
Serial.println(F("Charge STOP"));
#endif

charging = _charging;
level = 0;
}
else if (charging)
{
// ID 0x155: charge current control

byte _level = msgBuf[0];

if (_level == 0xFF)
continue; // init phase, skip

if (_level > TWIZY_CHARGE_THROTTLE)
{
// overwrite:
msgBuf[0] = TWIZY_CHARGE_THROTTLE;
CAN.sendMsgBuf(0x155, 0, 8, msgBuf);
}

#if TWIZY_DEBUG > 1
if (_level != level)
{
Serial.print(F("Level "));
if (_level > TWIZY_CHARGE_THROTTLE) {
Serial.print((char)('0' + _level));
Serial.print('>');
Serial.println((char)('0' + TWIZY_CHARGE_THROTTLE));
} else {
Serial.println((char)('0' + _level));
}
}
#endif

level = _level;
}
}

} // while (true)
}

36 changes: 36 additions & 0 deletions TwizyChargeThrottle/TwizyChargeThrottle_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* ==========================================================================
* Twizy charge current throttle
* ==========================================================================
*/
#ifndef _TwizyChargeThrottle_config_h
#define _TwizyChargeThrottle_config_h

// Set the charge current throttle level here:
// 6 = 30 A = 2,1 kW
// 5 = 25 A = 1,7 kW
// 4 = 20 A = 1,4 kW
// 3 = 15 A = 1,0 kW
// 2 = 10 A = 0,7 kW
// 1 = 5 A = 0,4 kW
#define TWIZY_CHARGE_THROTTLE 5

// Serial debug output level:
// 1 = show charge start/stop
// 2 = show current level changes
#define TWIZY_DEBUG 2

// Serial interface baud rate:
#define SERIAL_SPEED 115200

// Set your CAN MCP clock frequency here:
#define TWIZY_CAN_MCP_FREQ MCP_16MHZ

// Set your CAN CS pin number here:
#define TWIZY_CAN_CS_PIN SS

// Set your CAN IRQ pin here (0 = no IRQ):
#define TWIZY_CAN_IRQ_PIN 2

#endif // _TwizyChargeThrottle_config_h

0 comments on commit ad47994

Please sign in to comment.