mirror of
https://github.com/dexterbg/Twizy-ChargeThrottle.git
synced 2024-11-18 12:43:59 +00:00
Twizy-ChargeThrottle V1.0 (initial release)
This commit is contained in:
parent
90f6cff352
commit
ad479942b8
4 changed files with 206 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
assets
|
||||||
|
*.html
|
21
README.md
Normal file
21
README.md
Normal file
|
@ -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
TwizyChargeThrottle/TwizyChargeThrottle.ino
Normal file
147
TwizyChargeThrottle/TwizyChargeThrottle.ino
Normal file
|
@ -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
TwizyChargeThrottle/TwizyChargeThrottle_config.h
Normal file
36
TwizyChargeThrottle/TwizyChargeThrottle_config.h
Normal file
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue