Generic Battery + Arduino = Happy Solo

Joined
May 9, 2017
Messages
149
Reaction score
60
Age
49
I am not sure if this has been discussed before....
The APM/Pixhawk had a voltage/current sensor module which monitored voltage and current via analog inputs. Would it be possible to connect this to a generic battery and use an arduino to monitor the voltage and current? Then in turn the arduino act as a Solo Battery BMS and answers I2C request from the Solo? Keeping the Solo happy and able to land when the voltage got low?

Is this monitoring code via the analogy inputs extractable from the APM code?

If this arduino was really clever it could stay with the battery and keep track of the battery capacity through charging and discharging as well?

Sorry if this has been discussed before but I will be running out of batteries soon and have other batteries, the APM sensor along with various arduinos.
 
  • Like
Reactions: Derriell
Another question is...
What is the minimum information the Solo needs to fly and return home on low battery?

Since each cell is under 5v the balance plug could be connected to 4 arduino analog inputs to read their voltages, summed and this made available via I2C requests?

Just thinking out loud for a basic option to use a generic battery and still have the Solo return on low voltage....
 
Not on a solo. The pins for the analog battery monitors are not available in the carrier board anywhere.
 
I wasn't looking at connecting anything new to the Solo. I was looking at having an arduino board that connected to the Solo's I2C bus (via the battery plug) and acted as a Solo battery BMS and answered the voltage questions (and maybe more).
 
I wasn't looking at connecting anything new to the Solo. I was looking at having an arduino board that connected to the Solo's I2C bus (via the battery plug) and acted as a Solo battery BMS and answered the voltage questions (and maybe more).
In theory yes. But I am not aware of that anyone has written the Arduino code to read the BMS protocol yet.
If you find a source I would be interested ?
 
It shouldn't be too hard to set the arduino as an I2C slave at the correct address. Is there a list of the requests that the solo asks the battery BMS so I could prepare answers for?
 
  • Like
Reactions: Derriell
If you take a look into the AP_BattMonitor_SMBus.h you can see the parameters that arducopter (and I think Solo too) needs:

BATTMONITOR_SMBUS_TEMP = 0x08, // Temperature
BATTMONITOR_SMBUS_VOLTAGE = 0x09, // Voltage
BATTMONITOR_SMBUS_CURRENT = 0x0A, // Current
BATTMONITOR_SMBUS_REMAINING_CAPACITY = 0x0F, // Remaining Capacity
BATTMONITOR_SMBUS_FULL_CHARGE_CAPACITY = 0x10, // Full Charge Capacity
BATTMONITOR_SMBUS_SPECIFICATION_INFO = 0x1A, // Specification Info
BATTMONITOR_SMBUS_SERIAL = 0x1C, // Serial Number
BATTMONITOR_SMBUS_MANUFACTURE_NAME = 0x20, // Manufacture Name
BATTMONITOR_SMBUS_MANUFACTURE_DATA = 0x23, // Manufacture Data

good luck
 
Thanks for that list.

I have a Solo running the 3DR firmware. It contacts the arduino, then request the battery voltage 0x09. The arduino replies but may not be the correct formatted response as I2C and Smbus are slightly different. After a couple of seconds it must time out and stop requesting data.

I am hunting down my arduino mega as I have found an I2C sniffer program and can monitor the traffic so I can try and work out what is going wrong.
 
you can google "smbus quick start guide" and look at the frame shape (section data transferts on SMBus and section Bus protocols). It seems that without PEC (packet error checking) it also works.
 
I pushed a repo on github (looninho/BMSUnseal )

the arduino sketch is for arduino board that reads from and send to any BMS rev 1.0 board.
selectedSearchSoloUnseal.py : GUI for hacking unseal pwd of 3dr solo. It just use serial port for transaction

sorry this is my draft project yet!
 
Thanks for your input.

I found my mega and got the sniffer running. The Arduino gets the 09 command for voltage then it sends its 2 bytes but i am not sure if the Solo sends the ACK before it sends the second byte so i will need to investigate further.

I have had a similar play with something similar to your project and had success talking to the Solo battery. I will also look through the Solo code and see if i can find out how it requests and processes the data as it may be using something similar to your project using I2C rather than SMBus

I have also found the protocol for the SMBus so will use that and work through the Solo code and wire library and see.
 
I am looking through the ardupilot-solo and ardupilot 3.7 code and it is looking for a PEC which i wasn't giveing so this will be why it is stopping. I will find some code to generate a PEC and send that and then see if that solves the problem.
 
*** Success! ***

I have managed to get an original firmwared Solo talking to the Arduino and sending through a voltage. The Arduino slowly reduces the voltage and this changes in Mission planner.

I need to also work out why current requires 2 words and then get a response for that.

Once i have this working i will look at the 3.7 dev version as it asks different questions and see how i can progress form there. Once i have something working consistently i will post the code.
 

Attachments

  • Mission Planner.jpg
    Mission Planner.jpg
    72.7 KB · Views: 90
  • Mission Planner 2.jpg
    Mission Planner 2.jpg
    59.4 KB · Views: 89
I have included the PEC checking code from 3drobotics/ardupilot-solo to generate the PEC code and this has worked a treat.

I am working through the current request 0x2A as this isn't a standard request and still have testing to do on 0x10 Total Capacity and 0x23 Remaining Capacity to give %.

Next step is to get the Arduino to measure actual cell voltage (to get ready for Open Solo & 3.7 which reads cells). I will also have a play with an APM current/voltage unit and see if i can work out current to calculate capacity usage.
 
The orginal 3DR code calls 0x2A and requests 4 bytes, plus length plus the PEC to turn into a 32bit float. I have had a play and still sorting out the order.

I will need to upgrade my test board or my spare board to Open Solo to carry on with these tests and see what data is requested from the Solo battery. I know it takes the cell voltages rather than total voltage.
 
If you can see what data actually comes back from a 0x2a request that would be great as the is no spec for that. All the other requests so far i have found the size and units. In all the versions of the 3DR and Open Solo code 0x2a is requesting 4 bytes back which converts it to a 32bit float

I can deal with the block read but the issue i am having is generating the reply having all the bytes in the right order. I am having a look through how the data is processed as it requests 4 bytes and expects 6 bytes back. 1st byte is number of bytes returned (4 requested and 4 returned), bytes 2-5 is the data (just need to work out the order for these 4 bytes, a word is 2 bytes with low first and high 2nd) and the the PEC for the 6th byte. Again i need to see what data is used to make up the PEC for this ie does it include the length byte or jsut the data etc.

Once i have the above sorted then i can deal with any block read of any length and should be full steam ahead.....
 
The battery return 0 mA because I think it is not connected to Solo as I test it in stand alone. Sorry I can't give you the exact frame since the write-read process is nested. If my understanding is not so bad, i can give you an example:

Consider you want to read the current (0x0a) using PEC. Here is the transaction frame (include writing to your hacking device (slave) and reading from it):
| S | 0x0B | Wr | A | 0x0A | A | PEC | A | S | 0x0B | Rd | A | data LSB | A | data MSB | A | PEC | A | P |
and its coresponding lenght in bit:
| 1 | 8 | 1 | 1 | 8 | 1 | 8 | 1 | 1 | 8 | 1 | 1 | 8 | 1 | 8 | 1 | 8 | 1 | 1 |
S=start bit; Wr/Rd=write bit (0)/read bit (1); A=ACK (0) or NACK (1);P=stop bit

How to process over the bus:

1) Solo writes to slave: | S | 0x0B | Wr |,
2) Solo wait ack from slave | A | then Solo sends cmd code | 0x0A | , waits | A | then sends | PEC | wait | A |,
2) then immediatly Solo sends a repeat start to denote a reading process from the slave device: | S | ,
3) now Solo is reading from the slave device : | 0x0B | Rd | A | ,
4) and then the least significant byte : | data LSB | A | ans so forth...the last byte (PEC) needs to be NACK (?)
5) then Solo send a stop | P | to release the bus.

so what you should implement in the slave are these responses | 0x0B | Rd | A | and | data_i | A | according to the request of course.

I found a smbus library for slave from TI here : http://www.ti.com/tool/msp430-smbus#
 

Members online

Forum statistics

Threads
13,093
Messages
147,741
Members
16,048
Latest member
ihatethatihavetomakeanacc