From 84c84590ab2355a3ba88e7320580ba8fa1cfb939 Mon Sep 17 00:00:00 2001 From: Michael Balzer Date: Wed, 28 Jun 2017 00:31:39 +0200 Subject: [PATCH] Version: 1.1.0 - Added support for Timer2 & Timer3 (see config header) - Added `setCurrentQA()` API call (native=fast 1/4 A resolution) --- API.md | 4 ++ HISTORY.md | 6 ++ README.md | 5 +- examples/SimpleBMS/TwizyVirtualBMS_config.h | 11 +++- examples/Template/TwizyVirtualBMS_config.h | 11 +++- keywords.txt | 1 + library.properties | 2 +- src/TwizyVirtualBMS.h | 64 ++++++++++++++++++--- src/TwizyVirtualBMS_config.h | 11 +++- 9 files changed, 101 insertions(+), 14 deletions(-) diff --git a/API.md b/API.md index ad225ec..5b13dce 100644 --- a/API.md +++ b/API.md @@ -48,6 +48,10 @@ Note: all control functions validate their parameters. If you pass any value out - `bool setCurrent(float amps)` -- Set momentary battery pack current level - amps: -500 .. +500 (A, positive = charge, negative = discharge) + - `bool setCurrentQA(long quarterAmps)` -- Set momentary battery pack current level + - quarterAmps: -2000 .. +2000 (1/4 A, positive = charge, negative = discharge) + - This is the native BMS current resolution, so no float/division necessary + - `bool setSOC(float soc)` -- Set state of charge - soc: 0.00 .. 100.00 (%) - Note: the charger will not start charging at SOC=100% diff --git a/HISTORY.md b/HISTORY.md index cc910cd..b16ae09 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,12 @@ # History +## Version: 1.1.0 (2017-06-20) + +- Added support for Timer2 & Timer3 (see config header) +- Added `setCurrentQA()` API call (native=fast 1/4 A resolution) + + ## Version: 1.0.0 (2017-06-17) - Conversion to Arduino library diff --git a/README.md b/README.md index c28e971..6630586 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,10 @@ To download, click the DOWNLOADS button in the top right corner, download the ZI You will also need these libraries: - [MCP_CAN_lib by Cory Fowler](https://github.com/coryjfowler/MCP_CAN_lib) - - [TimerOne by Paul Stoffregen](https://github.com/PaulStoffregen/TimerOne) + - …and one of… + - [TimerOne by Paul Stoffregen](https://github.com/PaulStoffregen/TimerOne) + - [FlexiTimer2 by Paul Stoffregen](https://github.com/PaulStoffregen/FlexiTimer2) + - [TimerThree by Paul Stoffregen](https://github.com/PaulStoffregen/TimerThree) To get the smallest possible ROM & RAM footprint, set `TWIZY_DEBUG_LEVEL` to 0 and `DEBUG_MODE` of the MCP_CAN library to 0. This reduces the core memory usage of the VirtualBMS library to (currently) 8338 bytes ROM and 403 bytes RAM. diff --git a/examples/SimpleBMS/TwizyVirtualBMS_config.h b/examples/SimpleBMS/TwizyVirtualBMS_config.h index 3592156..5953d8a 100644 --- a/examples/SimpleBMS/TwizyVirtualBMS_config.h +++ b/examples/SimpleBMS/TwizyVirtualBMS_config.h @@ -20,13 +20,22 @@ // You may need to lower this if your Arduino is too slow. #define TWIZY_CAN_CLOCK_US 10000 +// VirtualBMS can use Timer1 (16 bit), Timer2 (8 bit) or Timer3 (16bit) +// Select Timer2/3 if you need Timer1 for e.g. AltSoftSerial +#define TWIZY_USE_TIMER 1 + +// Timer2: precise resolutions depend on CPU type & clock frequency +// i.e. Arduino Nano 16 MHz: 1000 = 1 ms / 2000 = 0.5 ms / 5000 = 0.2 ms / 10000 = 0.1 ms +// Use lowest resolution possible to minimize side effects on AltSoftSerial +#define TWIZY_TIMER2_RESOLUTION 1000 + // Set your MCP clock frequency here: #define TWIZY_CAN_MCP_FREQ MCP_16MHZ // Set your SPI CS pin number here: #define TWIZY_CAN_CS_PIN 10 -// If you've connected the CAN module's IRQ pin: +// Uncomment if you've connected the CAN module's IRQ pin: //#define TWIZY_CAN_IRQ_PIN 2 // Set your 3MW (ECU_OK) control pin here: diff --git a/examples/Template/TwizyVirtualBMS_config.h b/examples/Template/TwizyVirtualBMS_config.h index 3592156..5953d8a 100644 --- a/examples/Template/TwizyVirtualBMS_config.h +++ b/examples/Template/TwizyVirtualBMS_config.h @@ -20,13 +20,22 @@ // You may need to lower this if your Arduino is too slow. #define TWIZY_CAN_CLOCK_US 10000 +// VirtualBMS can use Timer1 (16 bit), Timer2 (8 bit) or Timer3 (16bit) +// Select Timer2/3 if you need Timer1 for e.g. AltSoftSerial +#define TWIZY_USE_TIMER 1 + +// Timer2: precise resolutions depend on CPU type & clock frequency +// i.e. Arduino Nano 16 MHz: 1000 = 1 ms / 2000 = 0.5 ms / 5000 = 0.2 ms / 10000 = 0.1 ms +// Use lowest resolution possible to minimize side effects on AltSoftSerial +#define TWIZY_TIMER2_RESOLUTION 1000 + // Set your MCP clock frequency here: #define TWIZY_CAN_MCP_FREQ MCP_16MHZ // Set your SPI CS pin number here: #define TWIZY_CAN_CS_PIN 10 -// If you've connected the CAN module's IRQ pin: +// Uncomment if you've connected the CAN module's IRQ pin: //#define TWIZY_CAN_IRQ_PIN 2 // Set your 3MW (ECU_OK) control pin here: diff --git a/keywords.txt b/keywords.txt index a8357d7..f66a4ff 100644 --- a/keywords.txt +++ b/keywords.txt @@ -25,6 +25,7 @@ setSOC KEYWORD2 setTemperature KEYWORD2 setVoltage KEYWORD2 setCurrent KEYWORD2 +setCurrentQA KEYWORD2 setError KEYWORD2 attachEnterState KEYWORD2 diff --git a/library.properties b/library.properties index b59c6c9..db96587 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Twizy Virtual BMS -version=1.0.0 +version=1.1.0 author=Michael Balzer maintainer=Michael Balzer sentence=Emulation of Renault Twizy BMS (battery management system) diff --git a/src/TwizyVirtualBMS.h b/src/TwizyVirtualBMS.h index 5fea5d0..61caead 100644 --- a/src/TwizyVirtualBMS.h +++ b/src/TwizyVirtualBMS.h @@ -21,7 +21,10 @@ * * Libraries used: * - MCP_CAN: https://github.com/coryjfowler/MCP_CAN_lib + * …plus one of… * - TimerOne: https://github.com/PaulStoffregen/TimerOne + * - FlexiTimer2: https://github.com/PaulStoffregen/FlexiTimer2 + * - TimerThree: https://github.com/PaulStoffregen/TimerThree * * Licenses: * This is free software and information under the following licenses: @@ -35,24 +38,37 @@ #ifndef _TwizyVirtualBMS_h #define _TwizyVirtualBMS_h +#define TWIZY_VBMS_VERSION "V1.1.0 (2017-06-20)" + +#ifndef TWIZY_TAG +#define TWIZY_TAG "twizy." +#endif + #include #include #include #include + +#ifndef TWIZY_USE_TIMER +#define TWIZY_USE_TIMER 1 +#endif + +#if TWIZY_USE_TIMER == 1 #include +#elif TWIZY_USE_TIMER == 2 +#include +#elif TWIZY_USE_TIMER == 3 +#include +#else +#error "TWIZY_USE_TIMER invalid, please set to 1, 2 or 3!" +#endif #ifndef _TwizyVirtualBMS_config_h #warning "Fallback to default TwizyVirtualBMS_config.h -- you should copy this into your sketch folder" #include "TwizyVirtualBMS_config.h" #endif -#define TWIZY_VBMS_VERSION "V1.0.0 (2017-06-17)" - -#ifndef TWIZY_TAG -#define TWIZY_TAG "twizy." -#endif - // ========================================================================== // TYPES AND CONSTANTS @@ -78,7 +94,7 @@ enum TwizyState { // Twizy state names: #if TWIZY_DEBUG_LEVEL >= 1 -const char PROGMEM twizyStateName[13][13] = { +const char twizyStateName[13][13] PROGMEM = { "Off", "Init", "Error", @@ -181,6 +197,7 @@ public: // Model access: bool setChargeCurrent(int amps); bool setCurrent(float amps); + bool setCurrentQA(long quarterAmps); bool setSOC(float soc); bool setPowerLimits(unsigned int drive, unsigned int recup); bool setSOH(int soh); @@ -347,6 +364,16 @@ bool TwizyVirtualBMS::setCurrent(float amps) { return true; } +// Set battery pack current level (native 1/4 A resolution) +// milliamps: -2000 .. +2000 (positive = charge, negative = discharge) +bool TwizyVirtualBMS::setCurrentQA(long quarterAmps) { + CHECKLIMIT(quarterAmps, -2000L, 2000L); + unsigned int level = 2000 + quarterAmps; + id155[1] = (id155[1] & 0xf0) | ((level & 0x0f00) >> 8); + id155[2] = level & 0x00ff; + return true; +} + // Set battery pack SOC // soc: 0.00 .. 100.00 // Note: the charger will not start charging at SOC=100% @@ -962,8 +989,27 @@ void TwizyVirtualBMS::begin() { enterState(Off); - Timer1.initialize(TWIZY_CAN_CLOCK_US); - Timer1.attachInterrupt(twizyClockISR); + #if TWIZY_USE_TIMER == 1 + + // Use Timer1 (16 bit): + Timer1.initialize(TWIZY_CAN_CLOCK_US); + Timer1.attachInterrupt(twizyClockISR); + + #elif TWIZY_USE_TIMER == 2 + + // Use Timer2 (8 bit): derive count from resolution: + FlexiTimer2::set(TWIZY_CAN_CLOCK_US / (1000000UL / TWIZY_TIMER2_RESOLUTION), + 1.0 / TWIZY_TIMER2_RESOLUTION, + twizyClockISR); + FlexiTimer2::start(); + + #else + + // Use Timer3 (16 bit): + Timer3.initialize(TWIZY_CAN_CLOCK_US); + Timer3.attachInterrupt(twizyClockISR); + + #endif Serial.println(F(TWIZY_TAG "begin: done")); diff --git a/src/TwizyVirtualBMS_config.h b/src/TwizyVirtualBMS_config.h index 3592156..5953d8a 100644 --- a/src/TwizyVirtualBMS_config.h +++ b/src/TwizyVirtualBMS_config.h @@ -20,13 +20,22 @@ // You may need to lower this if your Arduino is too slow. #define TWIZY_CAN_CLOCK_US 10000 +// VirtualBMS can use Timer1 (16 bit), Timer2 (8 bit) or Timer3 (16bit) +// Select Timer2/3 if you need Timer1 for e.g. AltSoftSerial +#define TWIZY_USE_TIMER 1 + +// Timer2: precise resolutions depend on CPU type & clock frequency +// i.e. Arduino Nano 16 MHz: 1000 = 1 ms / 2000 = 0.5 ms / 5000 = 0.2 ms / 10000 = 0.1 ms +// Use lowest resolution possible to minimize side effects on AltSoftSerial +#define TWIZY_TIMER2_RESOLUTION 1000 + // Set your MCP clock frequency here: #define TWIZY_CAN_MCP_FREQ MCP_16MHZ // Set your SPI CS pin number here: #define TWIZY_CAN_CS_PIN 10 -// If you've connected the CAN module's IRQ pin: +// Uncomment if you've connected the CAN module's IRQ pin: //#define TWIZY_CAN_IRQ_PIN 2 // Set your 3MW (ECU_OK) control pin here: