Measurement tasks¶
The needforheat-generic-firmware library has a scheduler that runs tasks according to a specified interval. The library has some generic tasks that can be started. Your measurement device firmware code can add custom measurement tasks for custom properties.
Generic tasks¶
The needforheat-generic-firmware library comes with support for the following generic tasks:
Task | Purpose | Default interval |
---|---|---|
Heartbeat | Creates a heartbeat measurement and places it on the queue. | 10 minutes |
Battery voltage | Measures the battery voltage and places it on the queue. | 10 minutes |
Upload | Uploads the contents of the secure upload queue to a NeedForHeat server. | 10 minutes |
Time sync | Synchronizes the device clock via NTP | 24 hours |
OTA firmware update | Checks for OTA firmware updates and installs them | 48 hours |
Presence detection | Sends Bluetooth name requests to specific static MAC addresses and places a response count on the queue. | 10 minutes |
Upload task¶
The upload task uploads all the contents of the secure upload queue to a NeedForHeat server.
Heartbeat task¶
The heartbeat task creates a heartbeat measurement and places it on the secure upload queue. The timestamp of a heartbeat and its value are intended to give insight in the basic status of a measurement device. This may be useful for monitoring purposes during a measurement campaign. It also may be useful to get insight in the status of measurement devices during the analysis phase after a measurement campaign.
Battery voltage task¶
The battery voltage measures the closed circuit voltage of the battery of a battery-powered measurement device, such as the M5Stack CoreInk and places it on the secure upload queue.
Time sync task¶
The time sync tasks synchronizes the system time over the internet using NTP and updates the device clock. It also updates the time on the separate RTC1 chip, for supported devices that have it,like the M5Stack CoreInk.
OTA firmware update task¶
If enabled, the Over The Air (OTA) firmware update task periodically checks for new firmware updates, if enabled. When a new firmware update is found, it will be downloaded and installed. It will then restart once the other tasks are done, and boot the new firmware.
Presence detection task¶
If enabled, the presence detection task measures the number of people present nearby via Bluetooth name requests sent to a list of known static MAC-addresses. Such addresses of people's smartphones should only used after obtaining informed consent of each subject involved.
For each task time, the total number of unique smartphones that respond to such Bluetooth name requests is counted and this count is placed as a measurement on the secure upload queue.
In this way, privacy is respected both for people that gave permission to be counted (no individual information about their presence is sent in measurement values, only aggregate information) as well as other persons that are not participating in your measuremetn campaign as subjects (their smartphones don't even get a Bluetooth name request).
Starting generic tasks¶
The generic tasks can be added to the scheduler in the main
function of your code:
#include <generic_tasks.hpp>
extern "C" void app_main(void)
{
GenericTasks::AddTasksToScheduler();
Scheduler::Start(); // (1)!
}
AddTasksToScheduler()
only adds the generic tasks to the scheduler. They will not run until the scheduler is started.
Create a custom measurement task¶
Beside generic tasks, more tasks can be added to the scheduler. In your firmware code you can create custom measurement tasks for properties that your device measures, use the scheduler to make sure your specific measurements are done at specific times.
Rules¶
A NeedForHeat measurement task is freeRTOS task, that adheres to specific rules and for which you need to add specific information that is used by the NeedForHeat scheduler .
Any custom NeedForHeat task needs to adhere to these rules:
- A task is a function that takes a
void *taskInfo
2 as a parameter and should not return anything.The task takes a void pointer and returns nothingvoid ExampleTask(void *taskInfo /* (1)! */) { ... }
- Use
taskInfo
here instead ofparams
; these are not the parameters that were passed to the task when adding it to the scheduler.
- Use
- A task should not contain infinite loops and it must return.
- The task should be as short as possible. This will maximize the time that the system can sleep and maximize the battery lifetime if your measurement device is powered by batteries.
Usage of the scheduler¶
The scheduler makes some convenience functions available to any task. If your custom task is added to the scheduler, it can use any of those functions.
Scheduling your custom task¶
When you add your custom task to the scheduler, it will run your task automatically according to a specific interval that you choose:
#include <scheduler.hpp>
Scheduler::AddTask(ExampleTask, // (1)!
"Example task", // (2)!
4096, // (3)!
nullptr, // (4)!
1, // (5)!
Scheduler::Interval::MINUTES_10); // (6)!
- Task function.
- Task name.
- Stack size.
- Parameters passed into task.
- Priority.
- Interval.
Example task¶
#include <scheduler.hpp>
#include <measurements.hpp>
#include <secure_upload.hpp>
// Get access tot the secure upload queue.
auto secureUploadQueue = SecureUpload::Queue::GetInstance();
void ExampleTask(void *taskInfo)
{
// "example" is the property name.
// "%d" is how the value must be formatted.
// Formatting happens according to printf formatting rules:
// see also https://cplusplus.com/reference/cstdio/printf/
Measurements::Measurement::AddFormatter("example", "%d");
static int exampleValue = 0;
exampleValue++;
// Create a new measurement with property type "example"
// and the value of exampleValue,
// formatted according to the printf specifier "%d".
// Note that in this example, the timestamp is not explicitely specified
// so in this case, the secure upload queue will
// automatically attach the current task time to this measurement.
Measurements::Measurement exampleMeasurement("example", exampleValue);
// Add the measurement to the queue.
secureUploadQueue.AddMeasurement(exampleMeasurement);
}