6S Power Module
Project repo: GitHub - UWARG/efs-can-power-module: WARG 6s power module firmware with DroneCAN interface supported
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)
Current Roadblocks
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: https://github.com/dronecan/libcanard/blob/master/examples/SimpleNode/simple_node.c
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
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
Several values can be accessed through the I2C interface:
VCn_GC_4
, wheren
is the cell numberVC1_GC_4
I2C register address:
0x17
Data bit location:
6
VC2_GC_4
I2C register address:
0x17
Data bit location:
4
VC3_GC_4
I2C register address:
0x18
Data bit location:
6
VC4_GC_4
I2C register address:
0x18
Data bit location:
4
VC5_GC_4
I2C register address:
0x18
Data bit location:
2
VC6_GC_4
I2C register address:
0x18
Data bit location:
0
VCn_OFFSET_CORR
,
wheren
is the cell numberVC1_OFFSET_CORR
I2C register address:
0x11
Data bit locations:
7 to 4
VC2_OFFSET_CORR
I2C register address:
0x12
Data bit locations:
7 to 4
VC3_OFFSET_CORR
I2C register address:
0x13
Data bit locations:
7 to 4
VC4_OFFSET_CORR
I2C register address:
0x14
Data bit locations:
7 to 4
VC5_OFFSET_CORR
I2C register address:
0x15
Data bit locations:
7 to 4
VC6_OFFSET_CORR
I2C register address:
0x16
Data bit locations:
7 to 4
VCn_OC_4
, wheren
is the cell numberVC1_OC_4
I2C register address:
0x17
Data bit location:
7
VC2_OC_4
I2C register address:
0x17
Data bit location:
5
VC3_OC_4
I2C register address:
0x18
Data bit location:
7
VC4_OC_4
I2C register address:
0x18
Data bit location:
5
VC5_OC_4
I2C register address:
0x18
Data bit location:
3
VC6_OC_4
I2C register address:
0x18
Data bit location:
1
VCn_GAIN_CORR
,
wheren
is the cell numberVC1_GAIN_CORR
I2C register address:
0x11
Data bit locations:
3 to 0
VC2_GAIN_CORR
I2C register address:
0x12
Data bit locations:
3 to 0
VC3_GAIN_CORR
I2C register address:
0x13
Data bit locations:
3 to 0
VC4_GAIN_CORR
I2C register address:
0x14
Data bit locations:
3 to 0
VC5_GAIN_CORR
I2C register address:
0x15
Data bit locations:
3 to 0
VC6_GAIN_CORR
I2C register address:
0x16
Data bit locations:
3 to 0
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
Up-to-date electrical schematics from the EE team
Project 6s Power Module (Ask the EE team for access)
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