-
-
Notifications
You must be signed in to change notification settings - Fork 80
pbio/drv/battery/battery_ev3.c: Implement EV3 battery driver #375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Done. Also added a workaround for detecting low battery on bootup (it's added in the ADC driver, unlike the REVISIT in the STM32 implementation). |
| // Battery current is read across a 0.05 ohm equivalent shunt resistor | ||
| // which is then connected to an op-amp configured with a gain of 16 | ||
| // (non-inverting). This yields 1 A = 0.8 V. | ||
| *value = ((uint32_t)(value_raw) * 5000 * 10) / (1023 * 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to move scaling to mV to the ADC driver on all platforms. Can be a different PR though. I think David might be working on ADC at the moment.
| // Battery voltage is read through a voltage divider consisting of two | ||
| // 100 K resistors, which halves the voltage. The ADC returns 10 LSBs, | ||
| // where full scale is 5 V. | ||
| *value = ((uint32_t)(value_raw) * 2 * 5000) / 1023; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the Linux kernel, for the battery voltage, I also took into account the VCE of Q19B that I somehow figured to be 50 mV (don't remember how I came up with that number). And I also added a bit more to account for the shunt resistor which depends on the current.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After lowering the SCLK rate to 1MHz, this 50 mV offset seems to go away, so I might have figured that wrong in the Linux driver.
As far as the shunt resistor goes, it would probably be better to include that in the low battery shutdown battery level, but not in the battery voltage that we use for motor control. So for now, I guess we should just leave that out.
|
I also think we need to first slow down the SPI on the ADC a bit more to get more accurate readings. Below are some data points I took (by enabling debug prints in the DCM). As we can see, the {W,C2T,T2C}DELAYs are already helping quite a bit, but the values are still skewed a bit compared to running at a slower SCLK rate. It looks like 1MHz is the magic value to let us actually read a saturated 5V on the ADC. (Note: the values are what I set |
|
@dlech , what is the status on this one? Would you like to make the ADC fixes first before we merge this? |
|
I'm still doing testing on this. |
This reads the values from the ADC and scales them according to the ideal scaling factors.
Without this, the hub can falsely detect low battery when booting.
Using the max SPI SCLK speed of 20 MHz, the ADC is not able to read up to the full 5V but rather reading somewhere around 50 mV less. By slowing down the SCLK rate, we give the ADC more time to settle after switching the mux and can get more accurate readings as a result. Testing has shown that 1 MHz slow enough to achieve this.
|
I rebased and added a couple of extra commits. One to slow down the ADC SPI SCLK to get more accurate measurements. (I suspect this may help with the long standing issue of large motors being detected as medium motors). Another is some more battery monitoring code we had from ev3dev and is also in the official LEGO firmware for a high temperature shutdown. |
Copy the EV3 battery monitor code from [1]. This is something that comes from the original EV3 firmware. [1]: https://github.com/ev3dev/brickd/blob/master/src/power_monitor.vala


This reads the values from the ADC and scales them according to the ideal scaling factors.
Voltage was tested and reads in the correct order of magnitude, slightly lower (~100 mV) when compared against a cheap DMM without traceable calibration.
Current appears reasonable (116 mA) and increases when I squeeze a running motor (up to 500 mA).
Fixes pybricks/support#2311