Buingiorno a tutti.
Sto svolgendo il mio lavoro di tesi magistrale: ho creato un dispositivo con Wemos D1 Mini che collezione i battiti cardiaci e la temperatura periferica della pelle e, attraverso un algoritmo di apprendimento che segue un'estrazione delle caratteristiche del segnale, individua i picchi di stress.
Per il mio progetto ho utilizzato il sensore max30101 e mlx90614.
Tuttavia, necessito di apportare dei miglioramenti alla parte software, avevo in mente dunque di ottimizzare il codice anche in termini di consumo, per poi calcolare il consumo del dispositivo (ad esempio, ho trovato questo strumento, ma non so utilizzarlo perchè non ho idea di come calcolare il consumo del dispositivo.)
Io non mi sono mai approcciata a tecniche di ottimizzazione del codice, mi chiedevo se qualcuno fosse disposto ad aiutarmi, anche fornendomi delle risorse di semplice comprendonio. Quello che vorrei applicare è cercare di diminuire il più possibile il consumo "inutile" dell'energia e aumentare lo spazip disponibile, aggiungendo ad esempio delle condizioni, il delay o lo sleep mode.
La board si connette ad Arduino IoT Cloud tramite WiFi e il codice contiene due librerie aggiuntive create da me: una per l'estrazione delle caratteristiche statistiche dei segnali e l'altra che implementa l'algoritmo. Per evitare di incollare papelli potrei aggiungerla su richiesta, anche perchè è stata automaticamente generata tramite questa libreria
#include "arduino_secrets.h"
#include <MAX30105.h> // --> Sparkfun library for MAX30101 sensor [https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library]
#include <heartRate.h> // --> Optical Heart Rate Detection (PBA Algorithm) [https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/blob/master/src/heartRate.h]
#include <DFRobot_MLX90614.h> // --> Melexis temperature sensor library
#include "Scaler.h" // --> Feature extraction library [https://github.com/eloquentarduino/everywhereml]
#include "Classifier.h" // --> Classification library containing Logistic Regression algorithm [https://github.com/eloquentarduino/micromlgen]
#include <Arduino.h>
#include <U8x8lib.h>
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
#include "thingProperties.h"
MAX30105 particleSensor; // --> defining particle sensor object used for BPM
Eloquent::ML::Port::LogisticRegression clf; // --> declare classifier library
DFRobot_MLX90614_I2C tempSensor; // --> defining temperature sensor object used for st
const byte RATE_SIZE = 3; //Averaging
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
int beatsPerMinute; // --> raw BPM
//st
byte st_values[RATE_SIZE];
byte st_spot = 0;
int degree; // --> raw peripheral skin temperature in °C
void setup() {
particleSensor.begin(Wire, I2C_SPEED_FAST, 0x57);
tempSensor.begin();
//Serial.begin(9600);
u8x8.begin();
u8x8.setBusClock(100000);
byte ledBrightness = 0x1F;
byte sampleAverage = 1;
byte ledMode = 3;
byte sampleRate = 50;
int pulseWidth = 411;
int adcRange = 4096;
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
particleSensor.setPulseAmplitudeRed(0); //0 mA
particleSensor.setPulseAmplitudeIR(0); // 0 mA
particleSensor.setPulseAmplitudeGreen(0x19); // 1 mA
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.drawString(0, 4, "Initializing...");
delay(2000);
u8x8.clearDisplay();
u8x8.drawString(3, 0, "Enjoy!");
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void hrCollection() {
/**
* The particle sensor capture the green led emission from the inner wrist. When a blood pulse happen, the photodiode capture a pulse of light which corresponds to a heart beat.
* In order to be able to capture peaks throw the wrist, the green led has been accurately set up in the setup() section, following the instructions published by the authors
* on page 22 of the paper. [https://pdfserv.maximintegrated.com/en/an/AN6409.pdf]
* The peaks, corresponding to the BPM, are computed throw a PBA algorithm, then, they are averaged with a moving window of size 3.
*/
long irValue = particleSensor.getGreen();
if (checkForBeat(irValue) == true)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
// removing signal error
if (beatsPerMinute < 255 && beatsPerMinute > 20)
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//computing average of 3 samples
beatAvg = 0;
for (byte j = 0 ; j < RATE_SIZE ; j++)
beatAvg += rates[j];
beatAvg /= RATE_SIZE;
}
}
}
void stCollection() {
/**
* Peripheral skin Temperature has been measured in degree Celsius thanks to an InfraRed thermophile that capture the emissivity of the human skin.
*/
degree = tempSensor.getObjectTempCelsius();
if (degree > 10 && degree < 50) // removing signal error
{
//computing average of 3 samples
st_values[st_spot++] = (byte)degree;
st_spot %= RATE_SIZE;
st = 0;
for (byte z = 0 ; z < RATE_SIZE ; z++)
st += st_values[z];
st /= RATE_SIZE;
}
}
void loop() {
ArduinoCloud.update();
hrCollection();
stCollection();
int features[] = {beatAvg, st};
if (!processor.transform(features))
return;
response = clf.predictLabel(processor.X);
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.setCursor(5, 2);
u8x8.print(beatAvg);
u8x8.setCursor(5, 3);
u8x8.print(st);
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
u8x8.drawGlyph(3, 2, 0x46);
u8x8.drawGlyph(3, 3, 0x45);
u8x8.setFont(u8x8_font_open_iconic_check_2x2);
if (response == "Baseline") {
u8x8.drawGlyph(5, 5, 0x40);
}
if (response == "Stress") {
u8x8.drawGlyph(5, 5, 0x44);
}
//Serial is used to collect data throw Excel Data Streamer only
//Serial.print(BeatAvg); Serial.print(","); Serial.print(st); Serial.print(","); Serial.println(response);
}