6S Power Module
Project repo: GitHub - UWARG/efs-can-power-module: WARG 6s power module firmware with DroneCAN interface supported
Table of Contents
- 1 Specifications (from the EE Team)
- 2 Tasks Break Down:
- 2.1 Action Items
- 2.2 ย Milestones
- 3 Open Questions
- 4 ย Reference materials
- 4.1 Relevant protocols
- 4.2 Project Resources
- 4.2.1 Analog-to-Digital Converter (ADC) Explained
- 4.2.1.1 Reference Voltage
- 4.2.1.2 Counting and Resolution
- 4.2.2 Battery Monitoring Circuit
- 4.2.2.1 Addressing
- 4.2.2.2 Selecting the cell for the VCOUT pin
- 4.2.2.3 Reference voltage selection
- 4.2.2.4 Cell Voltage Monitoring
- 4.2.2.5 BMC Temperature monitoring
- 4.2.3 Up-to-date electrical schematics from the EE team
- 4.2.1 Analog-to-Digital Converter (ADC) Explained
- 4.3 Receiving incoming messages (Polling/Interrupt/DMA)
Specifications (from the EE Team)
Overall Hardware Architecture
Taken from https://uwarg-docs.atlassian.net/wiki/x/AoCsmQ
Background
The drone uses a battery pack containing 12 cells, where 2 groups of 6 cells are each connected in series (hence 6S
).
Each group of 6 cells is connected to a battery monitoring circuit (shortened as BMC later).
This circuit measures:
The voltage of each cell
The current delivered by the group
This is done by forcing the battery to deliver current through a resistor with a tiny resistance. This resistor, called a shunt/shunt resistor, follows Ohmโs law:
V=IR
This implies that
I=V/R
, which means that the current passing through a shunt is equal to its voltage (which can be measured easily), divided by its resistance (which is a known constant).
And it sends:
We are not exactly sure of everything yet.
Battery-related information relating to the voltages and currents
The voltage and current information are sent as 2 analog signals, which our microcontroller converts to digital ones via an Analog-to-Digital Converter (ADC).
Some other information is sent via the I2C protocol
Description
MCU (STM32xX)
in the top right is the microcontroller that we are writing the code toIts job is to translate the messages it receives from the
BQ76925 6s LiPo Battery Monitor
boards and send the corresponding messages to the flight controller (FC) using the CAN protocol
Specific Hardware Information
Taken from https://uwarg-docs.atlassian.net/wiki/x/HYBXq
The ports we are interested in:
PA9:
SCL_1
, Serial Clock line for I2C 1, to configure BMC 1PA10:
SDA_1
, Serial Data line for I2C 1, to configure BMC 1PA7:
SCL_2
, Serial Clock line for I2C 2, to configure BMC 2PB4:
SDA_2
, Serial Data line for I2C 2, to configure BMC 2PA12:
CAN_TX
, Transmit line for CANPA11:
CAN_RX
, Receive line for CANPA3:
OVERCURRENT
, receives 5.5 V when an overcurrent occurs, and 0 V otherwisePA4:
VIOUT_FILT
, receives 0.25-1.25 V (REF_SEL=0) / 0.5-2.5 V (REF_SEL=1), representing the cell current for cells 1-6, as measured by a 1-milliohm shuntPA5:
VCOUT1_FILT
, receives 1.47-1.53 V (REF_SEL=0) / 2.94-3.06 V (REF_SEL=1), representing the cell voltages for cells 1-6PB0:
ADC1_FILT
, receivesVREF
, the ADC reference voltagePB1:
VCOUT2_FILT
, receives 1.47-1.53 V (REF_SEL=0) / 2.94-3.06 V (REF_SEL=1), representing the cell voltages for cells 7-12PA2:
ADC2_FILT
, receivesVREF
, the ADC reference voltage
ย Current Roadblocks
Libcanard has a high learning curve. Neither the DroneCAN website nor the Libcanard repo has beginner-friendly tutorials. YouTube videos also wonโt help directly
Tasks Break Down:
Action Items
ย Milestones
Open Questions
How should the MCU beacon itself to the FC (i.e. so that the FC is aware that the MCU on the power module is there)?
What should be sent over CAN? Possible options:
ย Reference materials
Relevant protocols
I2C: I2C - Inter-Integrated Circuit
I2C is all about registers (i.e. memory that can be accessed by an address)
Each I2C peripheral has its own register map (i.e. what the registers are used for, such as storing the voltage of a cell)
To read data from a peripheral, you send an address to it, and it will respond with data
To write data to a peripheral, you tell it which address to write to, and what data to write
CAN:
A general description of CAN: https://uwarg-docs.atlassian.net/wiki/x/BgDPlw
DroneCAN: a protocol built on top of CAN to communicate information between drone parts and the FC: DroneCAN
Libcanard: an implementation of DroneCAN for low-end microcontrollers. An example code on how to use it: libcanard/examples/SimpleNode/simple_node.c at master ยท dronecan/libcanard
EFS-Canard: a portable WARG version of the Libcanard library
AP-Periph has some example code on how to send DroneCAN messages when you have a specific type of device (e.g. a battery)
A helpful presentation on CAN: https://docs.google.com/presentation/d/12i6TiUuXQw5mO2u3pq8DMXTD1bCRe8rJtzVZRk6pDz0/edit?usp=sharing
A helpful document on CAN applications: https://uwarg-docs.atlassian.net/wiki/x/AwA8q
Project Resources
Analog-to-Digital Converter (ADC) Explained
There are many physical quantitles in the world that we may want to measure, such as voltage, current, or temperature. These are analog quantities, which means that can change continuously and have infinitely many values (*).
In WARG EFS, we work with microcontrollers quite regularly. They use digital signals to work, which means it works with a finite set of numbers; in particular, they use something like 0 V to represent a logic โ0', and 5 V to represent a logic โ1โ. By doing math with these โ0โ and '1โ signals, we can program the microcontrollers to do anything we want.
An Analog-to-Digital Converter (ADC)'s job is to connect between these two worlds.
Specifically, it converts an analog voltage into a digital signal that the microcontroller can understand.
Reference Voltage
Thereโs just one issue: voltages have a basically infinite range, but our ADC has a finite range. Therefore, we have to tell the ADC what voltage range it should expect. By convention, the lowest voltage an ADC can understand is usually 0 V.
On the other hand, you can specify the highest voltage it should expect.
This is the so-called ADC reference voltage.
Counting and Resolution
Now our ADC is ready to do its job. To make its output easy to understand, the output of an ADC is directly proportional to its voltage input.
For example, an ADC may be told to sense an input voltage from 0-8 V into a natural number from 0 to 31. This would mean that an input of 4.25 V will correspond to a number of around 16.
To put this into jargon, since there are 32 numbers between 0 and 31, and 32 is 2 to the 5th power, we say that the ADCโs resolution is 5 bits, and it counted a value of 16.
An ADCโs resolution is the number of bits that are used to represent its outputs,
and its count is the number itโs currently giving.
Battery Monitoring Circuit
Datasheet: BQ76925
Addressing
All I2C addresses are calculated using the formula
ADDRESS = 0x20 + REG_ADDR
Where ADDRESS
is the real address to read/write to, and REG_ADDR
is the register address mentioned on the datasheet, from 0x00
to 0x1F
.
Remember this distinction between the real and register addresses. All I2C addresses you see after this point will be register addresses.
Source: Datasheet, 8.5.1.1 I2C Addressing
Selecting the cell for the VCOUT
pin
To select the cell to measure the voltage of:
// Write to the register address:
REG_ADDR = 0x01
// With data:
DATA = 0x10 + CELL
Where CELL
is the cell number. CELL=0x0
refers to cell 1, CELL=0x1
refers to cell 2, and so on, up to CELL=0x5
referring to cell 6.
Source: Datasheet, 8.6.1 Register Descriptions (Tables 6 to 8)
Reference voltage selection
// Write to the register address:
REG_ADDR = 0x04
// With data:
DATA = REF_SEL
Where REF_SEL
can be set to 0
or 1
, with the following effects on the BMC pins:
Table 14. Reference Voltage Selection
REF_SEL | VREF (V) | VCOUT Gain (V) | VIOUT Voltage Range (V) |
---|---|---|---|
0 | 1.5 | 0.3 | 0.25 - 1.25 |
1 | 3.0 | 0.6 | 0.5 - 2.5 |
Source: Datasheet, 8.6.1 Register Descriptions (Tables 13 and 14)
Cell Voltage Monitoring
// The voltage of the currently selected cell, VCn,
// is calculated with the following formula:
VCn = ((VCOUT * GC_VREF + OC_VCOUT) / G_VCOUT) * (1 + GC_VCOUT)
// Where:
VCOUT = ADC_count / Full_scale_count * VREF_NOMINAL // This is the voltage of the VCOUT pin, as measured by the MCU
GC_VCOUT = ((VCn_GC_4 << 4) + VCn_GAIN_CORR) * 1E-3
OC_VCOUT = ((VCn_OC_4 << 4) + VCn_OFFSET_CORR) * 1E-3
GC_VREF = (1 + ((VREF_GC_4 << 4) + VREF_GAIN_CORR) * 1E-3)
+ (((VREF_OC_5 << 5) + (VREF_OC_4 << 4) + VREF_OFFSET_CORR) * 1E-3)/VREF_NOMINAL
Several values can be accessed through the I2C interface:
VREF_OC_5
I2C register address:
0x1b
Data bit location:
2
VREF_OC_4
I2C register address:
0x1b
Data bit location:
1
VREF_GC_4
I2C register address:
0x1b
Data bit location:
0
Source: Datasheet, 8.3.2.2 Cell Voltage Monitoring
BMC Temperature monitoring
The internal temperature of the battery management circuit can be monitored. To do that, configure the VCOUT
pin to output that temperature:
// Write to the register address:
REG_ADDR = 0x01
// With data:
DATA = 0x16
Then, the temperature can be deduced as follows:
// TEMP: temperature (degrees C)
// V: voltage measured at the VCOUT pin (mV)
TEMP = 5/22 * (V - 1090)
Note that TEMP
has an uncertainty of plus/minus 7/22 โ 0.227 ยฐC.
Also note that TEMP
will be between -25 to 85 ยฐC in normal operating conditions, which corresponds to 980 to 1464 mV.
These are visualized in the Desmos graph below.
Sources: Datasheet, 8.3.2.5.1 Internal Temperature Monitoring;
Datasheet, 7.12 Internal Temperature Measurement
Up-to-date electrical schematics from the EE team
Project 6s Power Module (Ask the EE team for access)
Oftentimes youโll want to connect to the board to download a program. Hereโs how youโll find how to wire your connector, in case you forgot:
Receiving incoming messages (Polling/Interrupt/DMA)
We are going to receive messages from an external device (the BMC), but we canโt predict when we will receive them. There are 3 solutions to this:
Polling: repeatedly checking whether a message was received using a loop. If a message gets detected, it gets processed, then the loop continues. This is a purely software solution.
Advantages:
Very easy to implement
You donโt need to worry about race conditions (when multiple pieces of code unintentionally access and modify some variable at the same time)
Disadvantages:
Extremely inefficient. The loop eats up most of the microcontrollerโs computational resources, which it needs for many other tasks.
Interrupt: when a message gets received, it triggers a hardware interrupt. This causes all other processes to stop. Then the message gets processed, and the other processes resume after that. STM32 microcontrollers support many internal interrupts (for common events like receiving an I2C message), and external interrupts (triggered by a GPIO pin).
Advantages:
More efficient than polling
Disadvantages:
You need to be careful about race conditions
Still needs the microcontroller for data reception
Direct Memory Access (DMA): Similar to an interrupt, except the peripheral writes its message directly to the microcontrollerโs memory. Then it signals the microcontroller that a new message came.
Advantages:
Most efficient for large messages
Disadvantages:
You need to be careful about race conditions
Less efficient than regular interrupts for small messages
ย