Skip to content

Commit

Permalink
Add feature to log voltage into the datalog.
Browse files Browse the repository at this point in the history
  • Loading branch information
microbit-carlos committed Nov 15, 2024
1 parent 369a3eb commit a595cb5
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 4 deletions.
28 changes: 24 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
# BBC micro:bit V2 Battery Voltage Measurement

A C++ example project showing how to measure the BBC micro:bit V2 battery
A micro:bit C++ project showing how to measure the BBC micro:bit V2 battery
voltage.

This project measures the input voltage, in millivolts, from the nRF52833
microcontroller and prints it on the display and serial.
This project measures the input voltage, in millivolts, of the nRF52833
microcontroller. It shows the value on the micro:bit display and also sends
it via serial.

A prebuilt hex file can be download from the
It's important to note that the battery voltage is not exactly the same
as the microcontroller input voltage, as there is some
[safety circuitry](https://github.com/microbit-foundation/microbit-v2-hardware)
between the battery and the microcontroller that will produce a small voltage
drop.

A prebuilt hex file can be downloaded from the
[GitHub Releases page](https://github.com/microbit-foundation/microbit-v2-battery-voltage/releases).

A similar example for micro:bit V1 can be found in:
https://os.mbed.com/teams/microbit/code/microbit-battery-test/

## Logging the voltage

If the button A is pressed (keep it pressed until the text stops scrolling and
all display LEDs are on), the battery voltage will be logged into the
[data log](https://microbit.org/get-started/user-guide/data-logging/).

The voltage is logged once per minute, and when the log is full
(it should take over 5 days) a cross will be displayed and the programme will
stop running.

The data-log can then be accessed by connecting the micro:bit to a computer
and opening the `MY_DATA.HTM` file inside the `MICROBIT` USB drive.

## How is the battery voltage measured

To measure the micro:bit battery voltage, the nRF52833 (the target MCU)
Expand Down
70 changes: 70 additions & 0 deletions source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

MicroBit uBit;

// Configures the interval (in seconds) between battery voltage logs
static size_t LOGGING_INTERVAL_SECS = 60;

// The ADC channel to be used for the battery voltage measurement
static int BATTERY_ADC_CHANNEL = -1;
Expand Down Expand Up @@ -70,6 +72,69 @@ static void vdd_adc_init() {
(void)get_vdd_millivolts();
}

/**
* Log the battery voltage every minute.
*
* The logging interval is set by the LOGGING_INTERVAL_SECS global variable.
* Once the log is full, a cross is displayed on the LED matrix and the program
* stops running.
*/
static void log_battery_voltage() {
// First turn on all display LEDS on
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
uBit.display.image.setPixelValue(row, col, 255);
}
}

// Configure data logging and clear any previous data
uBit.log.setSerialMirroring(false);
uBit.log.setTimeStamp(TimeStampFormat::Seconds);
uBit.log.clear(false);
uBit.log.setVisibility(true);

// Read the battery voltage every second, average it over 60 seconds and log it
const size_t BUFFER_SIZE = LOGGING_INTERVAL_SECS;
int voltages[BUFFER_SIZE] = {0};
size_t voltages_index = 0;

uint32_t next_log_time = uBit.systemTime();
while (!uBit.log.isFull()) {
while (uBit.systemTime() < next_log_time);
next_log_time += LOGGING_INTERVAL_SECS * 1000;

voltages[voltages_index] = get_vdd_millivolts();
voltages_index++;

if (voltages_index >= BUFFER_SIZE) {
voltages_index = 0;
int voltage_sum = 0;
for (size_t i = 0; i < BUFFER_SIZE; i++) {
voltage_sum += voltages[i];
}
int voltage_average = voltage_sum / BUFFER_SIZE;

uBit.log.beginRow();
uBit.log.logData("mV", ManagedString(voltage_average));
uBit.log.endRow();
}
}

// Log storage is full, show a cross on the display
const MicroBitImage IMG_CROSS(
"255,000,000,000,255\n"
"000,255,000,255,000\n"
"000,000,255,000,000\n"
"000,255,000,255,000\n"
"255,000,000,000,255\n"
);
uBit.display.print(IMG_CROSS);
while (true) {
uBit.sleep(1000);
}
}


int main() {
uBit.init();

Expand All @@ -81,6 +146,11 @@ int main() {
uBit.serial.send(battery_mv + "\r\n");
uBit.display.scroll(battery_mv);

// On button A enter into a mode where the battery voltage into logged once per minute
if (uBit.buttonA.isPressed()) {
log_battery_voltage();
}

uBit.sleep(1000);
}
}

0 comments on commit a595cb5

Please sign in to comment.