Skip to content

Commit 12e9db6

Browse files
authored
Merge pull request #74 from CURocketEngineering/voltageReader
feat: update PowerManagement voltage calculation logic
2 parents 695f0b9 + fd7011f commit 12e9db6

2 files changed

Lines changed: 46 additions & 19 deletions

File tree

hal/ArduinoHAL.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ using String = std::string;
2828
#define INPUT 0
2929
#define HIGH 1
3030
#define LOW 0
31+
#define ADC_VOLTAGE 192
3132

3233
inline void pinMode(int pin, int mode) { //NOLINT
3334
// Do nothing
@@ -37,6 +38,18 @@ inline void digitalWrite(int pin, int value) { //NOLINT
3738
// Do nothing
3839
}
3940

41+
inline void analogReadResolution(int bits) {
42+
// Do nothing, we will just return a 12-bit value in analogRead
43+
}
44+
45+
inline uint32_t analogRead(int pin) {
46+
// Return a dummy 12 bit value for the voltage pin, and 0 for other pins.
47+
// This allows us to test the battery voltage reading functionality without needing a real ADC.
48+
if (pin == ADC_VOLTAGE) {
49+
return static_cast<uint32_t>((1 << 12) - 1); // Return full-scale value for a 12-bit ADC
50+
}
51+
return 0; // Default dummy value for other pins
52+
}
4053

4154
// millis mock which still gives us the time since the program started in milliseconds
4255
static auto program_start = std::chrono::high_resolution_clock::now();

include/PowerManagement.h

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,64 @@
11
#ifndef PowerManagement_H
22
#define PowerManagement_H
33

4-
#include "Arduino.h"
5-
#include "pins.h"
4+
#include "ArduinoHAL.h"
65

76
/**
87
* @brief Simple ADC-based battery voltage helper.
9-
* @note When to use: quick health checks of the main battery using an analog
10-
* pin and known divider scaling.
8+
* This class provides a way to read the battery voltage using an ADC pin and a scaling factor.
9+
*
10+
* The correct pin can be found in the hardware scematics under "ADC_VOLTAGE"
11+
* and the scaling factor can be calculated based on the voltage divider used in the hardware design.
12+
* For MARTHA 1.4, the voltage divider is 200k and 1k5, so the factor is (200k + 1k5) / 1k5 = 134.33333.
13+
*
14+
* The voltage at the pin is calculated as:
15+
* vPin = (rawValue / (2^numAdcBits - 1)) * vRef
16+
* where rawValue is the ADC reading, numAdcBits is the resolution of the ADC, and vRef is the reference voltage for the ADC (3.3V for MARTHA 1.4).
17+
* The battery voltage is then calculated as:
18+
* vBat = vPin * factor
1119
*/
1220
class BatteryVoltage {
1321
public:
14-
BatteryVoltage(uint8_t adcPin, float conversionFactor)
15-
: pin(adcPin), factor(conversionFactor) {}
22+
/**
23+
* @param adcPin The ADC pin connected to the battery voltage divider.
24+
* @param factor The scaling factor to convert the pin voltage to battery voltage.
25+
* @param numAdcBits The resolution of the ADC (e.g., 12 for 12-bit ADC).
26+
* @param voltageThreshold A threshold voltage for low battery checks (not used in current implementation but can be useful for future extensions).
27+
*/
28+
BatteryVoltage(uint8_t adcPin, float factor, int numAdcBits, float voltageThreshold)
29+
: pin(adcPin), factor(factor), numAdcBits(numAdcBits), voltageThreshold(voltageThreshold) {analogReadResolution(numAdcBits);}
1630

1731
/**
1832
* @brief Sample the ADC and convert to battery voltage.
1933
* @return Converted voltage reading.
20-
* @note When to use: periodic health checks or brownout warnings.
2134
*/
2235
float readVoltage() {
2336
// Set the pin for reading
2437
pinMode(pin, INPUT);
25-
uint32_t rawValue = 0;
26-
rawValue = analogRead(pin); // Should give a value between 0 and 1023, not sure how to convert this to the true voltage.
27-
// Conversion notes -> respect to Vref you would do Vref * analogRead()/2^12.
28-
// After that you can use the voltage divider equation to get the battery voltage level
29-
// Vref is 134.33?
30-
// float voltage = pow((rawValue/2),12) * factor;
31-
Serial.println(rawValue);
32-
return rawValue;
38+
uint32_t rawValue = analogRead(pin); // Should give a value between 0 and 2^numAdcBits - 1
39+
float vRef = 3.3f; // reference voltage for the ADC on MARTHA 1.4
40+
41+
// Convert raw ADC value to voltage at the pin, then apply the factor to get battery voltage
42+
float vPin = (static_cast<float>(rawValue) / (static_cast<float>(1 << numAdcBits) - 1)) * vRef;
43+
float vBat = vPin * factor;
44+
45+
return vBat;
3346
}
3447

3548
/**
3649
* @brief Check whether voltage exceeds a minimal threshold.
3750
* @return true if voltage is above the survival threshold.
38-
* @note When to use: lightweight go/no-go checks before more detailed
39-
* power analysis.
51+
* @note Could be useful for future extension, like triggering a low power mode
4052
*/
41-
bool isAlive(){
42-
return readVoltage() > .3; // Not sure what a good cutoff is
53+
bool isLow(){
54+
return readVoltage() < voltageThreshold;
4355
}
4456

4557
private:
4658
uint8_t pin;
4759
float factor;
60+
int numAdcBits;
61+
float voltageThreshold;
4862
};
4963

5064
#endif // PowerManagement_H

0 commit comments

Comments
 (0)