Add existing code: Power consumption test cases and Semaphore power scheduler skeleton

This commit is contained in:
Phillip Kühne 2024-11-24 23:09:46 +01:00
parent 87b9fbe66f
commit e4dffe50c7
13 changed files with 522 additions and 0 deletions

View File

@ -0,0 +1,26 @@
#include "Dezibot.h"
Dezibot dezibot = Dezibot();
// How many times to run a command on the display consecutively;
const uint16_t iterations = 5000;
void setup() {
dezibot.begin();
}
void loop() {
//Typical output
dezibot.display.println("Typical output");
for(uint16_t iter=0; iter<iterations; iter++) {
dezibot.display.println(iter);
}
delay(10);
//Lots of pixels turned on
dezibot.display.invertColor();
dezibot.display.println("Inverted output");
for(uint16_t iter=0; iter<iterations; iter++) {
dezibot.display.println(iter);
}
delay(10);
}

View File

@ -0,0 +1,136 @@
#include "Dezibot.h"
#include "esp_pm.h"
#include "esp_task_wdt.h"
Dezibot dezibot;
const uint16_t cycleTime = 2e4; //20000 ms = 20 s
esp_pm_lock_handle_t cpuFreqLock;
esp_pm_lock_handle_t apbFreqLock;
esp_pm_lock_handle_t lightSleepLock;
static bool pmLocksCreated = false;
void stress_task0(void *pvParameters) {
// Register ourselves with the task watchdog
if (esp_task_wdt_add(NULL) != ESP_OK) {
Serial.println("Failed to add task 0 to TWDT");
}
while (1) {
volatile uint32_t x = 0;
for (uint32_t i = 0; i < 10000; i++) {
x += i;
}
esp_task_wdt_reset();
}
}
void stress_task1(void *pvParameters) {
// Register ourselves with the task watchdog
if (esp_task_wdt_add(NULL) != ESP_OK) {
Serial.println("Failed to add task 0 to TWDT");
}
while (1) {
volatile uint32_t x = 0;
for (uint32_t i = 0; i < 10000; i++) {
x += i;
}
esp_task_wdt_reset();
}
}
void setup() {
Serial.begin(115200);
while (!Serial) {
;
}
uint32_t Freq = getCpuFrequencyMhz();
Serial.print("CPU Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getXtalFrequencyMhz();
Serial.print("XTAL Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getApbFrequency();
Serial.print("APB Freq = ");
Serial.print(Freq);
Serial.println(" Hz");
// Create lock handles for controlling power management features
// Parameter arg is always unused and should thus be set to 0
// Ref: https://docs.espressif.com/projects/esp-idf/en/v3.3.6/api-reference/system/power_management.html#enumerations
if (!pmLocksCreated) {
bool cpuFreqLockSuccess = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "CPU_FREQ_MAX", &cpuFreqLock);
bool apbFreqLockSuccess = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "APB_FREQ_MAX", &apbFreqLock);
bool lightSleepLockSuccess = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "NO_LIGHT_SLEEP", &lightSleepLock);
if ((cpuFreqLockSuccess && apbFreqLockSuccess && lightSleepLockSuccess)) {
pmLocksCreated = true;
Serial.println("Sucessfully created handles to control power management features.");
} else {
Serial.println("Failed to create handles to control power management features!");
}
} else {
Serial.println("Powermanagement lock handles already created, skipping creation!");
}
// Configure Task Watchdog so it does not interfere
esp_task_wdt_config_t twdt_config = {
.timeout_ms = 30000,
.idle_core_mask = (1 << portNUM_PROCESSORS) - 1,
.trigger_panic = true
};
if (esp_task_wdt_reconfigure(&twdt_config) != ESP_OK) {
Serial.println("Failed to reconfigure task watchdog!");
}
delay(500);
Serial.flush();
Serial.end();
}
/*
* A function that prints to serial, setting up the serial peripheral beforehand, and shutting it down afterwards.
* Do not use this on a regular basis, as it is probably very slow. It is useful for not having the serial peripheral
* active at all times.
*
* @param str The text to print
*/
void setupAndCleanupSerialPrint(char *str) {
Serial.begin(115200);
while (!Serial) {
;
;
}
delay(10);
Serial.print(str);
delay(10);
Serial.flush();
delay(10);
Serial.end();
}
void loop() {
// Alternate between 20 Seconds at 100% CPU load, no artificial load but not sleeping, and normal behaviour (light sleep when there is nothing to do).
setupAndCleanupSerialPrint("Beginning stress phase\n");
TaskHandle_t core0StressTask = NULL;
TaskHandle_t core1StressTask = NULL;
xTaskCreatePinnedToCore(stress_task0, "CPU0Stress", 4096, NULL, 1, &core0StressTask, 0);
xTaskCreatePinnedToCore(stress_task1, "CPU1Stress", 4096, NULL, 1, &core1StressTask, 1);
vTaskDelay(pdMS_TO_TICKS(cycleTime));
setupAndCleanupSerialPrint("Still alive after waiting cycleTime after setting up stress tasks...\n");
esp_task_wdt_delete(core0StressTask);
esp_task_wdt_delete(core1StressTask);
vTaskDelete(core0StressTask);
vTaskDelete(core1StressTask);
// Now disable light sleep
setupAndCleanupSerialPrint("Beginning idle with power management disabled\n");
esp_pm_lock_acquire(cpuFreqLock);
esp_pm_lock_acquire(apbFreqLock);
esp_pm_lock_acquire(lightSleepLock);
vTaskDelay(pdMS_TO_TICKS(cycleTime));
// Restore auto light sleep and dynamic frequency scaling
setupAndCleanupSerialPrint("Beginning idle with power management reenabled\n");
esp_pm_lock_release(cpuFreqLock);
esp_pm_lock_release(apbFreqLock);
esp_pm_lock_release(lightSleepLock);
vTaskDelay(pdMS_TO_TICKS(cycleTime));
}

View File

@ -0,0 +1,43 @@
#include "Dezibot.h"
Dezibot dezibot;
// How many times to run a command on the IMU consecutively;
const uint16_t iterations = 5000;
void setup() {
dezibot.motion.detection.begin();
//dezibot.motion.detection.end();
// put your setup code here, to run once:
Serial.begin(115200);
// Wait for Serial to init
while (!Serial) {
;;
}
// Test if IMU is working correctly
char imu_whoami = dezibot.motion.detection.getWhoAmI();
if (imu_whoami == 0x67) {
Serial.println("IMU seems to be working. Starting measurements...");
} else {
Serial.println("IMU does not seemm to be working correctly.");
exit(0);
}
dezibot.motion.detection.end();
Serial.println("Returned IMU to low-power mode. Killing Serial peripheral. Goodbye!");
delay(1000);
Serial.end();
delay(1000);
}
void loop() {
// This puts both accelerometer and gyroscope into low noise mode, which is their highest
// power consumption state
dezibot.motion.detection.begin();
for (uint16_t iter = 0; iter < iterations; iter++) {
dezibot.motion.detection.getRotation();
dezibot.motion.detection.getAcceleration();
delay(1);
}
// Turn everything back off to measure baseline power consumption
delay(iterations);
}

View File

@ -0,0 +1,23 @@
#include "Dezibot.h"
Dezibot dezibot;
const uint16_t cycleMillis = 2e4;
void setup() {
// put your setup code here, to run once:
dezibot.infraredLight.begin();
}
void loop() {
// put your main code here, to run repeatedly:
// Just turn the lights on alternating each five seconds, to get the consumption
dezibot.infraredLight.front.turnOn();
delay(cycleMillis);
dezibot.infraredLight.front.turnOff();
dezibot.infraredLight.bottom.turnOn();
delay(cycleMillis);
//Turn off and wait a little to measure baseline consumption
dezibot.infraredLight.bottom.turnOff();
delay(cycleMillis);
}

View File

@ -0,0 +1,34 @@
#include "Dezibot.h"
Dezibot dezibot;
void setup() {
dezibot.lightDetection.begin();
//dezibot.motion.detection.end();
// put your setup code here, to run once:
Serial.begin(115200);
// Wait for Serial to init
while (!Serial) {
;;
}
delay(1000);
// Test if SFH325 (Q3) is working correctly
char light_value = dezibot.lightDetection.getValue(DL_FRONT);
if (light_value != UINT16_MAX) {
Serial.printf("Light detection seems to be working (detected value: %d). Starting measurements...\r\n", light_value);
} else {
Serial.printf("Light detection does not seem to be working correctly (detected value: %d).\n",light_value);
exit(0);
}
Serial.println("Killing Serial peripheral now to not influence anything. Goodbye!");
delay(1000);
Serial.flush();
Serial.end();
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
dezibot.lightDetection.getValue(DL_FRONT);
delay(10);
}

View File

@ -0,0 +1,34 @@
#include "Dezibot.h"
Dezibot dezibot;
void setup() {
dezibot.lightDetection.begin();
//dezibot.motion.detection.end();
// put your setup code here, to run once:
Serial.begin(115200);
// Wait for Serial to init
while (!Serial) {
;;
}
delay(1000);
// Test if SFH320 (Q12) is working correctly
char light_value = dezibot.lightDetection.getValue(DL_FRONT);
if (light_value != UINT16_MAX) {
Serial.printf("Light detection seems to be working (detected value: %d). Starting measurements...\r\n", light_value);
} else {
Serial.printf("Light detection does not seem to be working correctly (detected value: %d).\n",light_value);
exit(0);
}
Serial.println("Killing Serial peripheral now to not influence anything. Goodbye!");
delay(1000);
Serial.flush();
Serial.end();
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
dezibot.lightDetection.getValue(DL_BOTTOM);
delay(10);
}

View File

@ -0,0 +1,34 @@
#include "Dezibot.h"
Dezibot dezibot;
void setup() {
dezibot.lightDetection.begin();
//dezibot.motion.detection.end();
// put your setup code here, to run once:
Serial.begin(115200);
// Wait for Serial to init
while (!Serial) {
;;
}
delay(1000);
// Test if VEML6040 is working correctly
char ir_value = dezibot.lightDetection.getValue(DL_FRONT);
if (ir_value != UINT16_MAX) {
Serial.printf("IR detection seems to be working (detected value: %d). Starting measurements...\r\n", ir_value);
} else {
Serial.printf("IR detection does not seem to be working correctly (detected value: %d).\n",ir_value);
exit(0);
}
Serial.println("Killing Serial peripheral now to not influence anything. Goodbye!");
delay(1000);
Serial.flush();
Serial.end();
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
dezibot.lightDetection.getValue(IR_FRONT);
delay(10);
}

View File

@ -0,0 +1,22 @@
#include "Dezibot.h"
Dezibot dezibot;
void setup() {
dezibot.motion.begin();
}
void loop() {
// Alternatingly turn on the Motors. Use the commands provided by motion for this, using the provided
// functions (with their duty cycle), as it represents typical usage
dezibot.motion.rotateClockwise();
delay(20000);
dezibot.motion.rotateAntiClockwise();
delay(20000);
// Turn on both motors at the same time
dezibot.motion.left.setSpeed(DEFAULT_BASE_VALUE);
dezibot.motion.right.setSpeed(DEFAULT_BASE_VALUE);
delay(20000);
dezibot.motion.stop();
delay(20000);
}

View File

@ -0,0 +1,24 @@
#include "Dezibot.h"
Dezibot dezibot;
const uint duty = 8192; //Full tilt
void setup() {
dezibot.motion.begin();
}
void loop() {
// Alternatingly turn on the Motors. Use the commands provided by motion for this, using the provided
// functions (with their duty cycle), as it represents typical usage
dezibot.motion.rotateClockwise(0,duty);
delay(20000);
dezibot.motion.rotateAntiClockwise(0,duty);
delay(20000);
// Turn on both motors at the same time
dezibot.motion.left.setSpeed(duty);
dezibot.motion.right.setSpeed(duty);
delay(20000);
dezibot.motion.stop();
delay(20000);
}

View File

@ -0,0 +1,44 @@
#include "Dezibot.h"
Dezibot dezibot = Dezibot();
void setup() {
dezibot.multiColorLight.begin();
}
void loop() {
/* Loop through the LEDs at full brightness for measurements, with 20 seconds to measure for each state */
for (int state = 0; state < 6; state++) {
switch (state) {
case 0:
dezibot.multiColorLight.turnOffLed(ALL);
break;
case 1:
dezibot.multiColorLight.turnOffLed(ALL);
delay(10);
dezibot.multiColorLight.setLed(TOP_LEFT,WHITE);
break;
case 2:
dezibot.multiColorLight.turnOffLed(ALL);
delay(10);
dezibot.multiColorLight.setLed(TOP_RIGHT,WHITE);
break;
case 3:
dezibot.multiColorLight.turnOffLed(ALL);
delay(10);
dezibot.multiColorLight.setLed(BOTTOM,WHITE);
break;
case 4:
dezibot.multiColorLight.turnOffLed(ALL);
delay(10);
dezibot.multiColorLight.setLed(TOP,WHITE);
break;
case 5:
dezibot.multiColorLight.turnOffLed(ALL);
delay(10);
dezibot.multiColorLight.setLed(ALL,WHITE);
break;
}
sleep(20);
}
}

View File

@ -0,0 +1,32 @@
#include "Dezibot.h"
Dezibot dezibot;
void setup() {
dezibot.lightDetection.begin();
//dezibot.motion.detection.end();
// put your setup code here, to run once:
Serial.begin(115200);
// Wait for Serial to init
while (!Serial) {
;;
}
delay(1000);
// Test if Part under Test is working correctly
if (result = working) {
Serial.printf("Part X seems to be working (detected value: %d). Starting measurements...\r\n", result);
} else {
Serial.printf("Part X does not seem to be working correctly (detected value: %d).\n",result);
exit(0);
}
Serial.println("Killing Serial peripheral now to not influence anything. Goodbye!");
delay(1000);
Serial.flush();
Serial.end();
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
delay(10);
}

View File

@ -0,0 +1,34 @@
#include "Dezibot.h"
Dezibot dezibot;
void setup() {
dezibot.lightDetection.begin();
//dezibot.motion.detection.end();
// put your setup code here, to run once:
Serial.begin(115200);
// Wait for Serial to init
while (!Serial) {
;;
}
delay(1000);
// Test if VEML6040 is working correctly
char light_value = dezibot.lightDetection.getValue(DL_FRONT);
if (light_value != UINT16_MAX) {
Serial.printf("Light detection seems to be working (detected value: %d). Starting measurements...\r\n", light_value);
} else {
Serial.printf("Light detection does not seem to be working correctly (detected value: %d).\n",light_value);
exit(0);
}
Serial.println("Killing Serial peripheral now to not influence anything. Goodbye!");
delay(1000);
Serial.flush();
Serial.end();
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
dezibot.lightDetection.getValue(DL_FRONT);
delay(10);
}

View File

@ -0,0 +1,36 @@
#include "Dezibot.h"
#define DEBUG
Dezibot dezibot = Dezibot();
void setup() {
Serial.begin(112500);
while (!Serial) {
; /* Wait for USB-CDC Serial init to complete. */
}
#ifdef DEBUG
dezibot.display.begin();
dezibot.display.println("Debug enabled.");
Serial.println("Debug enabled.");
#endif
dezibot.communication.begin();
dezibot.communication.setGroupNumber(1);
dezibot.communication.sendMessage("Repeated send power consumption test commencing");
#ifdef DEBUG
dezibot.display.println("Mesh set up");
/* Set up receive handler */
dezibot.communication.onReceive(handle_receive);
dezibot.display.println("Set up receive. Printing incoming messages:");
Serial.println("Sending broadcast messages to generate TX power consumption:");
#endif
}
void handle_receive(String &message) {
dezibot.display.println(message);
}
void loop() {
/* Continuously send to consume power on TX */
dezibot.communication.sendMessage("Power Test Message");
}