From 5eb96c225803fda67ac36aff0c906c3d5d24eaa3 Mon Sep 17 00:00:00 2001 From: jaketheduque Date: Wed, 16 Jul 2025 17:31:10 -0700 Subject: [PATCH 1/8] added spo2 code to firmware --- EmotiBit.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ EmotiBit.h | 6 ++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/EmotiBit.cpp b/EmotiBit.cpp index 13a46a96..a9f134a3 100644 --- a/EmotiBit.cpp +++ b/EmotiBit.cpp @@ -3363,6 +3363,50 @@ void EmotiBit::processHeartRate() //addPacket(timestamp, FIR_FILT_DATA, iirFiltData, dataSize, true); } +void EmotiBit::processSpO2() +{ + static uint8_t irDataIndex = 0; + static uint8_t redDataIndex = 0; + static float irDataBuffer[SPO2_PPG_BUFFER_SIZE]; + static float redDataBuffer[SPO2_PPG_BUFFER_SIZE]; + + float* ir_data; + float* red_data; + uint16_t irDataSize; + uint16_t redDataSize; + uint32_t timestamp; + const static size_t APERIODIC_DATA_LEN = 1; //used in packet header + const static float timePeriod = (1.f / _samplingRates.ppg) * 1000; // in mS + float spo2; + + irDataSize = dataDoubleBuffers[(uint8_t)DataType::PPG_INFRARED]->getData(&ir_data, ×tamp, false); + redDataSize = dataDoubleBuffers[(uint8_t)DataType::PPG_RED]->getData(&red_data, ×tamp, false); + + if (irDataIndex + irDataSize < SPO2_PPG_BUFFER_SIZE) { + for (int i = 0 ; i < irDataSize ; i++) { + irDataBuffer[irDataIndex + i] = ir_data[i]; + } + } + irDataIndex += irDataSize; + + if (redDataIndex + redDataSize < SPO2_PPG_BUFFER_SIZE) { + for (int i = 0 ; i < redDataSize ; i++) { + redDataBuffer[redDataIndex + i] = red_data[i]; + } + } + redDataIndex += redDataSize; + + if (irDataIndex >= SPO2_PPG_BUFFER_SIZE-15 && redDataIndex >= SPO2_PPG_BUFFER_SIZE-15) { + get_oxygen_level(irDataBuffer, redDataBuffer, min(irDataIndex, redDataIndex), &spo2); + + irDataIndex = 0; + redDataIndex = 0; + + // Add packets to output + addPacket(timestamp, EmotiBitPacket::TypeTag::SPO2, &spo2, APERIODIC_DATA_LEN); + } +} + void EmotiBit::processData() { // Perform all derivative calculations @@ -3412,6 +3456,10 @@ void EmotiBit::processData() { processHeartRate(); } + if (acquireData.spo2) + { + processSpO2(); + } if (acquireData.edrMetrics) { // Note: this may move to emotiBitEda.processData() in the future diff --git a/EmotiBit.h b/EmotiBit.h index 08c6f430..6bf54fb7 100644 --- a/EmotiBit.h +++ b/EmotiBit.h @@ -35,6 +35,7 @@ #include "EmotiBitVariants.h" #include "EmotiBitNvmController.h" #include "heartRate.h" +#include "BrainflowSpO2Algorithm.h" #ifdef ARDUINO_FEATHER_ESP32 #include "FileTransferManager.h" #endif @@ -55,7 +56,7 @@ class EmotiBit { - String firmware_version = "1.14.0"; + String firmware_version = "1.14.0-feat-spo2.0"; @@ -376,7 +377,8 @@ class EmotiBit { bool debug = false; bool battery = true; bool heartRate = true; // Note: we may want to move this to a separarte flag someday, for controlling derivative signals - bool edrMetrics = true; + bool spo2 = true; + bool edrMetrics = true; } acquireData; struct ChipBegun { From e3b288775e8f7da1fdc7bfb2e6fca9692138e790 Mon Sep 17 00:00:00 2001 From: jaketheduque Date: Thu, 17 Jul 2025 08:51:20 -0700 Subject: [PATCH 2/8] new partition table, added script to skip bindings.cpp --- EmotiBit_stock_firmware/partitions.csv | 5 +++++ EmotiBit_stock_firmware/platformio.ini | 5 +++-- pio_scripts/removeBindingCPP.py | 6 ++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 EmotiBit_stock_firmware/partitions.csv create mode 100644 pio_scripts/removeBindingCPP.py diff --git a/EmotiBit_stock_firmware/partitions.csv b/EmotiBit_stock_firmware/partitions.csv new file mode 100644 index 00000000..94ed617d --- /dev/null +++ b/EmotiBit_stock_firmware/partitions.csv @@ -0,0 +1,5 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, factory, 0x10000, 0x3E0000, +coredump, data, coredump, 0x3F0000, 0x10000, \ No newline at end of file diff --git a/EmotiBit_stock_firmware/platformio.ini b/EmotiBit_stock_firmware/platformio.ini index d8e9cbd7..6fe6b20f 100644 --- a/EmotiBit_stock_firmware/platformio.ini +++ b/EmotiBit_stock_firmware/platformio.ini @@ -14,9 +14,10 @@ extra_configs = src_dir = ./ lib_dir = ../../ - [custom] variant_flags = -DSTOCK_FIRMWARE [env] -lib_ldf_mode = deep+ \ No newline at end of file +lib_ldf_mode = deep+ +monitor_speed = 115200 +board_build.partitions = partitions.csv \ No newline at end of file diff --git a/pio_scripts/removeBindingCPP.py b/pio_scripts/removeBindingCPP.py new file mode 100644 index 00000000..786b4527 --- /dev/null +++ b/pio_scripts/removeBindingCPP.py @@ -0,0 +1,6 @@ +Import("env") + +def skip_bindings_cpp(env, node): + return None + +env.AddBuildMiddleware(skip_bindings_cpp, "**/bindings.cpp") \ No newline at end of file From 61dd110b23ffe3df1262ec0fb838e193e0a538d4 Mon Sep 17 00:00:00 2001 From: jaketheduque Date: Thu, 17 Jul 2025 08:51:54 -0700 Subject: [PATCH 3/8] added BrainflowSpO2Algorithm to library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index f3f76958..2f220de8 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph= Requires dependent libraries as shown in the getting started document category=Sensors url=https://github.com/EmotiBit/EmotiBit_FeatherWing architectures=* -depends=EmotiBit BMI160, EmotiBit MAX30101, EmotiBit MLX90632, EmotiBit NCP5623, EmotiBit SI7013, EmotiBit XPlat Utils, EmotiBit ADS1X15, EmotiBit External EEPROM, EmotiBit EmojiLib, EmotiBit ArduinoFilters, EmotiBit SimpleFTPServer, EmotiBit KTD2026 +depends=EmotiBit BMI160, EmotiBit MAX30101, EmotiBit MLX90632, EmotiBit NCP5623, EmotiBit SI7013, EmotiBit XPlat Utils, EmotiBit ADS1X15, EmotiBit External EEPROM, EmotiBit EmojiLib, EmotiBit ArduinoFilters, EmotiBit SimpleFTPServer, EmotiBit KTD2026, BrainflowSpO2Algorithm From 3693bc02bea8ad297fb08745071e0c74b7dc7225 Mon Sep 17 00:00:00 2001 From: jaketheduque Date: Thu, 17 Jul 2025 11:59:54 -0700 Subject: [PATCH 4/8] updated EmotiBit.h --- EmotiBit.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EmotiBit.h b/EmotiBit.h index 6bf54fb7..8883f5f3 100644 --- a/EmotiBit.h +++ b/EmotiBit.h @@ -332,6 +332,7 @@ class EmotiBit { #define IMU_SAMPLING_DIV 2 #define BATTERY_SAMPLING_DIV 50 #define DUMMY_ISR_DIV 10 +#define SPO2_PPG_BUFFER_SIZE 64 struct TimerLoopOffset { @@ -455,6 +456,7 @@ class EmotiBit { void parseIncomingControlPackets(String &controlPackets, uint16_t &packetNumber); void readSensors(); void processHeartRate(); + void processSpO2(); void processData(); void sendData(); bool processThermopileData(); // placeholder until separate EmotiBitThermopile controller is implemented From 2c42f1730c77d48a6a47f8e8b07c0557f700ff6f Mon Sep 17 00:00:00 2001 From: Jake Xie <69865215+jaketheduque@users.noreply.github.com> Date: Thu, 17 Jul 2025 12:04:30 -0700 Subject: [PATCH 5/8] removed hard-coded monitor speed from platform.ini --- EmotiBit_stock_firmware/platformio.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/EmotiBit_stock_firmware/platformio.ini b/EmotiBit_stock_firmware/platformio.ini index 6fe6b20f..3da5de4b 100644 --- a/EmotiBit_stock_firmware/platformio.ini +++ b/EmotiBit_stock_firmware/platformio.ini @@ -19,5 +19,4 @@ variant_flags = -DSTOCK_FIRMWARE [env] lib_ldf_mode = deep+ -monitor_speed = 115200 -board_build.partitions = partitions.csv \ No newline at end of file +board_build.partitions = partitions.csv From 1795177f821ec6da3b90a273a56c495a427bf562 Mon Sep 17 00:00:00 2001 From: jaketheduque Date: Sat, 9 Aug 2025 13:36:38 -0700 Subject: [PATCH 6/8] fix DataType debug print --- EmotiBit.cpp | 2 +- EmotiBit_stock_firmware/EmotiBit_stock_firmware.ino | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/EmotiBit.cpp b/EmotiBit.cpp index a9f134a3..2de70932 100644 --- a/EmotiBit.cpp +++ b/EmotiBit.cpp @@ -2434,7 +2434,7 @@ bool EmotiBit::processThermopileData() size_t EmotiBit::getData(DataType type, float** data, uint32_t * timestamp) { #ifdef DEBUG Serial.print("getData: type="); - Serial.println((uint8_t) t); + Serial.println((uint8_t) type); #endif // DEBUG if ((uint8_t)type < (uint8_t)EmotiBit::DataType::length) { return dataDoubleBuffers[(uint8_t)type]->getData(data, timestamp, false); diff --git a/EmotiBit_stock_firmware/EmotiBit_stock_firmware.ino b/EmotiBit_stock_firmware/EmotiBit_stock_firmware.ino index c9fbebe0..62b8dde2 100644 --- a/EmotiBit_stock_firmware/EmotiBit_stock_firmware.ino +++ b/EmotiBit_stock_firmware/EmotiBit_stock_firmware.ino @@ -1,8 +1,8 @@ -#include #include "EmotiBit.h" +#include #define SerialUSB SERIAL_PORT_USBVIRTUAL // Required to work in Visual Micro / Visual Studio IDE -const uint32_t SERIAL_BAUD = 2000000; //115200 +const uint32_t SERIAL_BAUD = 2000000; EmotiBit emotibit; const size_t dataSize = EmotiBit::MAX_DATA_BUFFER_SIZE; @@ -11,7 +11,7 @@ float data[dataSize]; void onShortButtonPress() { // toggle wifi on/off - if (emotibit.getPowerMode() == EmotiBit::PowerMode::NORMAL_POWER) + if (emotibit.getPowerMode() == EmotiBit::PowerMode::NORMAL_POWER) { emotibit.setPowerMode(EmotiBit::PowerMode::WIRELESS_OFF); Serial.println("PowerMode::WIRELESS_OFF"); From 37711dbbf87a4da2ba77d47c947358a66110a390 Mon Sep 17 00:00:00 2001 From: jaketheduque Date: Sat, 9 Aug 2025 17:19:00 -0700 Subject: [PATCH 7/8] Changed library.properties dependencies --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 2f220de8..f4d536e5 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph= Requires dependent libraries as shown in the getting started document category=Sensors url=https://github.com/EmotiBit/EmotiBit_FeatherWing architectures=* -depends=EmotiBit BMI160, EmotiBit MAX30101, EmotiBit MLX90632, EmotiBit NCP5623, EmotiBit SI7013, EmotiBit XPlat Utils, EmotiBit ADS1X15, EmotiBit External EEPROM, EmotiBit EmojiLib, EmotiBit ArduinoFilters, EmotiBit SimpleFTPServer, EmotiBit KTD2026, BrainflowSpO2Algorithm +depends=EmotiBit BMI160, EmotiBit MAX30101, EmotiBit MLX90632, EmotiBit NCP5623, EmotiBit SI7013, EmotiBit XPlat Utils, EmotiBit ADS1X15, EmotiBit External EEPROM, EmotiBit EmojiLib, EmotiBit ArduinoFilters, EmotiBit SimpleFTPServer, EmotiBit KTD2026, EmotiBit Brainflow SpO2 Algorithm From a221ce60b7bc7c5adff440a0d3fa430f8d3f84b8 Mon Sep 17 00:00:00 2001 From: jaketheduque Date: Sat, 9 Aug 2025 17:23:24 -0700 Subject: [PATCH 8/8] updated SpO2 header file name --- EmotiBit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EmotiBit.h b/EmotiBit.h index 8883f5f3..ca1a7544 100644 --- a/EmotiBit.h +++ b/EmotiBit.h @@ -35,7 +35,7 @@ #include "EmotiBitVariants.h" #include "EmotiBitNvmController.h" #include "heartRate.h" -#include "BrainflowSpO2Algorithm.h" +#include "Emotibit_Brainflow_SpO2_Algorithm.h" #ifdef ARDUINO_FEATHER_ESP32 #include "FileTransferManager.h" #endif