Hint: begin with the "Template" example to get a standard usage template including all callbacks.
## Library inclusion
1. Create a TwizyVirtualBMS object (`twizy` is a good name for this)
2. Call `twizy.begin()` in your setup function
3. Call `twizy.looper()` in your main loop:
```c++
#include "TwizyVirtualBMS_config.h"
#include "TwizyVirtualBMS.h"
TwizyVirtualBMS twizy;
void setup() {
Serial.begin(115200);
twizy.begin();
}
void loop() {
twizy.looper();
}
```
## Twizy control functions
Note: all control functions validate their parameters. If you pass any value out of bounds, nothing will be changed, an error message will be generated on the serial port and the function will return `false`.
-`bool setChargeCurrent(int amps)` -- Set battery charge current level
- amps: 0 .. 35 A current level at battery
- will stop charge if set to 0 while charging
- Note: this has a 5 A resolution rounded downwards
- Note: 35 A will not be reached with current charger generation (max ~32 A)
| Current level | Power drawn from socket |
| ------------- | ----------------------- |
| 35 A | ~ 2.2 kW |
| 30 A | ~ 2.1 kW |
| 25 A | ~ 1.7 kW |
| 20 A | ~ 1.4 kW |
| 15 A | ~ 1.0 kW |
| 10 A | ~ 0.7 kW |
| 5 A | ~ 0.4 kW |
-`bool setCurrent(float amps)` -- Set momentary battery pack current level
Normal startup procedure involves the wakeup phase `Init` followed by `Ready`. Depending on the mode of operation requested, this will be followed by one of the `Start…` states with operation mode established resulting in the according `…ing` state.
The shutdown procedure begins with a transition from the `…ing` state to the according `Stop…` state, followed by `Ready` and finally `Off`.
Use the `Error` state to signal **severe problems** to the Twizy and cause an emergency shutdown. `Error` turns off CAN sends and drops the 3MW (ECU_OK) signal. SEVCON and charger will switch off all battery power immediately. To resolve the `Error` state from driving, the user needs to do a power cycle. When used during a charge, the charger will send the BMS into `Off` state, so the charge can simply be restarted by replugging the charger.
**Note**: to indicate **non-critical** problems, do not enter the `Error` state but instead only use `setError()`.
- Call `enterState(StopCharge)` to stop a running charge process. Note that `setChargeCurrent(0)` will do so as well.
- Call `enterState(Error)` to cause an emergency shutdown. Before doing this you should use `setError()` and (if possible) give the user some time to react when in state `Driving`.
- After any state transition, the user callback `EnterState` will be called.
## CAN interface access
To hook into the CAN receiver, use `attachProcessCanMsg()` (see above).
Standard filters will pass IDs `0x423`, `0x597` and `0x599`. Three free CAN filters can be used. The mask is fixed to match the whole ID, so you can filter at most three additional IDs at a time.
-`void setCanFilter(byte filterNum, unsigned int canId)` -- Set a free ID filter
- filterNum: 1 … 3
- canId: 11 bit CAN ID i.e. `0x196`
-`bool sendMsg(INT32U id, INT8U len, INT8U *buf)` -- Send a CAN message
- Note: will do three retries if TX buffers are full.
- Returns true if message has been sent, false on error.
- Retry and error counts are logged every 10 seconds if debug logging is enabled.
## Debug utils
-`void dumpId(FLASHSTRING *name, int len, byte *buf)` -- Dump a byte buffer in hex numbers
- name: must be a PROGMEM string, i.e. `dumpId(F("id123"), ...)`
-`void debugInfo()` -- Dump VirtualBMS status, include frame buffers if debug level >= 2
- this is automatically called every 10 seconds if debug level >= 1