diff --git a/senseBox-bike-atrai-v2/boards/sensebox_mcu_esp32s2.json b/senseBox-bike-atrai-v2/boards/sensebox_mcu_esp32s2.json deleted file mode 100644 index c031fa6..0000000 --- a/senseBox-bike-atrai-v2/boards/sensebox_mcu_esp32s2.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "build": { - "arduino":{ - "ldscript": "esp32_out.ld" - }, - "core": "esp32", - "extra_flags": [ - "-DARDUINO_SENSEBOX_MCU_ESP32S2", - "-DARDUINO_USB_CDC_ON_BOOT=1", - "-DBOARD_HAS_PSRAM", - "-DARDUINO_USB_MSC_ON_BOOT=1" - ], - "f_cpu": "240000000L", - "f_flash": "80000000L", - "hwids": [ - [ - "0x303A", - "0x81B8" - ], - [ - "0x303A", - "0x81B9" - ], - [ - "0x303A", - "0x81BA" - ] - ], - "flash_mode": "qio", - "mcu": "esp32s2", - "variant": "sensebox_mcu_esp32s2" - }, - "connectivity": [ - "wifi" - ], - "debug": { - "openocd_target": "esp32s2.cfg" - }, - "frameworks": [ - "arduino", - "espidf" - ], - "name": "senseBox MCU S2", - "upload": { - "flash_size": "4MB", - "maximum_ram_size": 327680, - "maximum_size": 4194304, - "use_1200bps_touch": true, - "wait_for_upload_port": true, - "require_upload_port": true, - "speed": 460800 - }, - "vendor": "senseBox", - "url": "https://sensebox.de/" - } \ No newline at end of file diff --git a/senseBox-bike-atrai-v2/platformio.ini b/senseBox-bike-atrai-v2/platformio.ini index 13a1d78..eeaff1a 100644 --- a/senseBox-bike-atrai-v2/platformio.ini +++ b/senseBox-bike-atrai-v2/platformio.ini @@ -11,12 +11,8 @@ [env:sensebox_mcu_esp32s2] platform = espressif32 board = sensebox_mcu_esp32s2 -platform_packages = - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.17 +platform_packages = platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.17 framework = arduino -build = - include_dir = lib/sensors -lib_ldf_mode = deep lib_deps = adafruit/Adafruit SSD1306 @ ^2.5.10 adafruit/Adafruit HDC1000 Library@^2.0.2 @@ -26,3 +22,6 @@ lib_deps = stm32duino/STM32duino VL53L8CX@^1.0.3 adafruit/Adafruit MPU6050@^2.2.6 sensebox/SenseBoxBLE@^1.1.0 + adafruit/Adafruit NeoPixel@^1.12.2 + arduino-libraries/Arduino_ESP32_OTA@^0.3.0 + arduino-libraries/Arduino_DebugUtils@^1.4.0 diff --git a/senseBox-bike-atrai-v2/src/ble/BLEModule.cpp b/senseBox-bike-atrai-v2/src/ble/BLEModule.cpp index dacda6e..0a79ff9 100644 --- a/senseBox-bike-atrai-v2/src/ble/BLEModule.cpp +++ b/senseBox-bike-atrai-v2/src/ble/BLEModule.cpp @@ -1,10 +1,21 @@ #include "BLEModule.h" +#include "Utf16Converter/Utf16Converter.h" -// void (*BLEModule::receiveCallback)(BLEDevice, BLECharacteristic) = nullptr; +void (*BLEModule::receiveCallback)(String) = nullptr; + +void BLEModule::receivedData() +{ + int size = 32; + uint8_t receivedData[size]; + SenseBoxBLE::read(receivedData, size); + + String data = utf16leToString(receivedData, size); + + BLEModule::receiveCallback(data); +} BLEModule::BLEModule() { - // service = nullptr; bleName = ""; } @@ -18,7 +29,12 @@ bool BLEModule::begin() delay(200); SenseBoxBLE::addService("CF06A218F68EE0BEAD048EBC1EB0BC84"); - xTaskCreate(bleTask, "bleTask", 1024, NULL, 1, NULL); + delay(200); + SenseBoxBLE::configHandler = &receivedData; + + int configCharacteristic = SenseBoxBLE::setConfigCharacteristic("29BD0A8551E44D3C914E126541EB2A5E", "60B1D5CE353944D2BB35FF2DAABE17FF"); + + xTaskCreate(bleTask, "bleTask", 2048, NULL, 1, NULL); return true; } @@ -71,21 +87,16 @@ bool BLEModule::writeBLE(int characteristicId, float value, float value2, float return SenseBoxBLE::write(characteristicId, value, value2, value3, value4, value5); } -// void BLEModule::setReceiveCallback(void (*callback)(BLEDevice, BLECharacteristic)) { -// receiveCallback = callback; -// } - -// void BLEModule::onReceive(BLEDevice central, BLECharacteristic characteristic) { -// if (receiveCallback) { -// receiveCallback(central, characteristic); -// } -// } +void BLEModule::setReceiveCallback(void (*callback)(String data)) +{ + BLEModule::receiveCallback = callback; +} void BLEModule::bleTask(void *pvParameters) { while (true) { SenseBoxBLE::poll(); - vTaskDelay(pdMS_TO_TICKS(5)); + vTaskDelay(pdMS_TO_TICKS(10)); } } diff --git a/senseBox-bike-atrai-v2/src/ble/BLEModule.h b/senseBox-bike-atrai-v2/src/ble/BLEModule.h index 9ef395d..458c3b4 100644 --- a/senseBox-bike-atrai-v2/src/ble/BLEModule.h +++ b/senseBox-bike-atrai-v2/src/ble/BLEModule.h @@ -15,7 +15,7 @@ class BLEModule // Get the BLE module ID String getBLEName(); - const char** getBLEConnectionString(); + const char **getBLEConnectionString(); // Create a BLE characteristic static int createCharacteristic(const char *uuid); @@ -27,17 +27,16 @@ class BLEModule static bool writeBLE(int characteristicId, float value, float value2, float value3, float value4, float value5); // Set callback for receiving data - // void setReceiveCallback(void (*callback)(BLEDevice, BLECharacteristic)); + void setReceiveCallback(void (*callback)(String data)); + static void (*receiveCallback)(String data); // Task function for polling BLE static void bleTask(void *pvParameters); private: - // BLEService* service; String bleName; - // static void onReceive(BLEDevice central, BLECharacteristic characteristic); - // static void (*receiveCallback)(BLEDevice, BLECharacteristic); + static void receivedData(); }; #endif // BLE_MODULE_H diff --git a/senseBox-bike-atrai-v2/src/ble/Utf16Converter/Utf16Converter.cpp b/senseBox-bike-atrai-v2/src/ble/Utf16Converter/Utf16Converter.cpp new file mode 100644 index 0000000..d3516e3 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/ble/Utf16Converter/Utf16Converter.cpp @@ -0,0 +1,32 @@ +#include "Utf16Converter.h" + +String utf16leToString(uint8_t *data, size_t length) +{ + String result = ""; + + // Ensure the length is even + if (length % 2 != 0) + { + return result; + } + + for (size_t i = 0; i < length; i += 2) + { + // Combine the two bytes to form a UTF-16 character + uint16_t utf16_char = data[i] | (data[i + 1] << 8); + + // If the character is null (0x0000), break the loop as it indicates the end of the string + if (utf16_char == 0x0000) + { + break; + } + + // Append the character to the result string if it is within the ASCII range + if (utf16_char <= 0x007F) + { + result += (char)utf16_char; + } + } + + return result; +} diff --git a/senseBox-bike-atrai-v2/src/ble/Utf16Converter/Utf16Converter.h b/senseBox-bike-atrai-v2/src/ble/Utf16Converter/Utf16Converter.h new file mode 100644 index 0000000..2554e85 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/ble/Utf16Converter/Utf16Converter.h @@ -0,0 +1,8 @@ +#ifndef UTF16_CONVERTER_H +#define UTF16_CONVERTER_H + +#include + +String utf16leToString(uint8_t *data, size_t length); + +#endif // UTF16_CONVERTER_H diff --git a/senseBox-bike-atrai-v2/src/display/Display.cpp b/senseBox-bike-atrai-v2/src/display/Display.cpp index 51b235b..cb4a836 100644 --- a/senseBox-bike-atrai-v2/src/display/Display.cpp +++ b/senseBox-bike-atrai-v2/src/display/Display.cpp @@ -137,8 +137,10 @@ void SBDisplay::showConnectionScreen() isBicycleAnimationShowing = false; } - String name = SenseBoxBLE::getMCUId(); String bleId = "[" + SenseBoxBLE::getMCUId() + "]"; + + String name = "senseBox:bike " + bleId; + String bleIdBegin = bleId.substring(0, bleId.length() / 2); String bleIdEnd = bleId.substring(bleId.length() / 2); const char *message[] = { diff --git a/senseBox-bike-atrai-v2/src/main.cpp b/senseBox-bike-atrai-v2/src/main.cpp index f178a16..11a2fe6 100644 --- a/senseBox-bike-atrai-v2/src/main.cpp +++ b/senseBox-bike-atrai-v2/src/main.cpp @@ -1,26 +1,45 @@ #include -#include -#include #include "sensors/TempHumiditySensor/TempHumiditySensor.h" #include "sensors/DustSensor/DustSensor.h" #include "sensors/DistanceSensor/DistanceSensor.h" #include "sensors/AccelerationSensor/AccelerationSensor.h" #include "display/Display.h" #include "ble/BLEModule.h" +#include "update/SoftwareUpdater.h" -TempHumiditySensor tempHumiditySensor; +// --- Sensor instances --- DustSensor dustSensor; +TempHumiditySensor tempHumiditySensor; DistanceSensor distanceSensor; AccelerationSensor accelerationSensor; +BaseSensor *sensors[] = {&dustSensor, &tempHumiditySensor, &distanceSensor, &accelerationSensor}; + +// --- Display instance --- SBDisplay display; +// --- BLE instance --- BLEModule bleModule; +// --- SoftwareUpdater instance --- +SoftwareUpdater softwareUpdater; + +// create an enum with the different states and modes the device can be in +enum class State +{ + IDLE, + MEASURING, + CONNECTED, + WIFI_READ_SSID, + WIFI_READ_PASSWORD, + START_SOFTWARE_UPDATE +}; + void setup() { Serial.begin(115200); delay(1000); + SBDisplay::begin(); pinMode(IO_ENABLE, OUTPUT); @@ -29,54 +48,102 @@ void setup() SBDisplay::showLoading("Setup BLE...", 0.1); bleModule.begin(); - SBDisplay::showLoading("Distance...", 0.2); - distanceSensor.begin(); - - SBDisplay::showLoading("Dust...", 0.3); - dustSensor.begin(); - - SBDisplay::showLoading("Acceleration...", 0.4); - accelerationSensor.begin(); - - SBDisplay::showLoading("Temperature...", 0.5); - tempHumiditySensor.begin(); - - SBDisplay::showLoading("Ventilation...", 0.6); - pinMode(3, OUTPUT); - delay(100); - digitalWrite(3, HIGH); - - SBDisplay::showLoading("Start measurements...", 1); - - // Subscribe to sensor measurements - // tempHumiditySensor.subscribe([](String uuid, std::vector values) { - // float temperature = values[0]; - // float humidity = values[1]; - // Serial.printf("TempHumiditySensor [%s]: %.2f, %.2f\n", uuid.c_str(), temperature, humidity); }); - - // dustSensor.subscribe([](String uuid) { - // Serial.printf("DustSensor [%s]\n", uuid.c_str()); - // }, "UUID-Dust"); - - // distanceSensor.subscribe([](String uuid, std::vector values) - // { Serial.printf("DistanceSensor [%s]: %.2f\n", uuid.c_str(), values[0]); }); - - // accelerationSensor.subscribe([](String uuid, std::vector values) - // { - // float x = values[0]; - // float y = values[1]; - // float z = values[2]; - // Serial.printf("Acceleration [%s]: %.2f, %.2f, %.2f\n", uuid.c_str(), x, y, z); }); - - tempHumiditySensor.startSubscription(); - dustSensor.startSubscription(); - distanceSensor.startSubscription(); - accelerationSensor.startSubscription(); - - tempHumiditySensor.startBLE(); - dustSensor.startBLE(); - distanceSensor.startBLE(); - accelerationSensor.startBLE(); + bleModule.receiveCallback = [](String data) + { + // get first character of the string and parse it to int + int mode = data.charAt(0) - '0'; + + // payload is all behind the first character + String payload = data.substring(1); + + // mode to state + State state = static_cast(mode); + + Serial.printf("Received mode: %d\n", mode); + + // switch case with mode and the state enum + switch (state) + { + case State::IDLE: + SBDisplay::showLoading("Idle...", 0.1); + for (BaseSensor *sensor : sensors) + { + sensor->stopBLE(); + } + for (BaseSensor *sensor : sensors) + { + sensor->stopSubscription(); + } + break; + case State::MEASURING: + SBDisplay::showLoading("Measuring...", 0.1); + for (BaseSensor *sensor : sensors) + { + sensor->startSubscription(); + } + break; + case State::CONNECTED: + SBDisplay::showLoading("Connected...", 0.1); + for (BaseSensor *sensor : sensors) + { + sensor->startBLE(); + } + break; + case State::WIFI_READ_SSID: + SBDisplay::showLoading(payload, 0.1); + softwareUpdater.setSSID(payload); + break; + case State::WIFI_READ_PASSWORD: + SBDisplay::showLoading(payload, 0.1); + softwareUpdater.setPassword(payload); + break; + case State::START_SOFTWARE_UPDATE: + SBDisplay::showLoading("Updating...", 0.1); + softwareUpdater.startUpdate(); + break; + default: + break; + } + }; + + // SBDisplay::showLoading("Distance...", 0.2); + // distanceSensor.begin(); + + // SBDisplay::showLoading("Dust...", 0.3); + // dustSensor.begin(); + + // SBDisplay::showLoading("Acceleration...", 0.4); + // accelerationSensor.begin(); + + // SBDisplay::showLoading("Temperature...", 0.5); + // tempHumiditySensor.begin(); + + // SBDisplay::showLoading("Ventilation...", 0.6); + // pinMode(3, OUTPUT); + // delay(100); + // digitalWrite(3, HIGH); + + // SBDisplay::showLoading("Start measurements...", 1); + + // // Subscribe to sensor measurements + // // tempHumiditySensor.subscribe([](String uuid, std::vector values) { + // // float temperature = values[0]; + // // float humidity = values[1]; + // // Serial.printf("TempHumiditySensor [%s]: %.2f, %.2f\n", uuid.c_str(), temperature, humidity); }); + + // // dustSensor.subscribe([](String uuid) { + // // Serial.printf("DustSensor [%s]\n", uuid.c_str()); + // // }, "UUID-Dust"); + + // // distanceSensor.subscribe([](std::vector values) + // // { Serial.printf("DistanceSensor [%s]: %.2f\n", values[0]); }); + + // // accelerationSensor.subscribe([](String uuid, std::vector values) + // // { + // // float x = values[0]; + // // float y = values[1]; + // // float z = values[2]; + // // Serial.printf("Acceleration [%s]: %.2f, %.2f, %.2f\n", uuid.c_str(), x, y, z); }); display.showConnectionScreen(); } diff --git a/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.cpp b/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.cpp index 05d0066..6a1b614 100644 --- a/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.cpp +++ b/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.cpp @@ -1,18 +1,14 @@ #include "AccelerationSensor.h" -#include -#include -#include +AccelerationSensor::AccelerationSensor() : BaseSensor("accelerationSensorTask", 2048, 100) {} -const String AccelerationSensor::accUUID = "B944AF10F4954560968F2F0D18CAB522"; +String accUUID = "B944AF10F4954560968F2F0D18CAB522"; +int accCharacteristic = 0; Adafruit_MPU6050 mpu; -int accCharacteristic = 0; - -void AccelerationSensor::begin() +void AccelerationSensor::initSensor() { - if (!mpu.begin(0x68, &Wire1)) { Serial.println("MPU6050 Chip wurde nicht gefunden"); @@ -28,75 +24,30 @@ void AccelerationSensor::begin() }; accCharacteristic = BLEModule::createCharacteristic(accUUID.c_str()); - - sendBLE = false; - activeSubscription = true; - xTaskCreate(sensorTask, "AccelerationSensorTask", 2048, this, 1, NULL); -} - -void AccelerationSensor::subscribe(std::function)> callback) -{ - this->measurementCallback = callback; } -void AccelerationSensor::startSubscription() +void AccelerationSensor::readSensorData() { - activeSubscription = true; -} + sensors_event_t a, g, temp; -void AccelerationSensor::stopSubscription() -{ - activeSubscription = false; -} + mpu.getEvent(&a, &g, &temp); -void AccelerationSensor::startBLE() -{ - setBLEStatus(true); -} + float x = a.acceleration.x; + float y = a.acceleration.y; + float z = a.acceleration.z; -void AccelerationSensor::stopBLE() -{ - setBLEStatus(false); -} - -void AccelerationSensor::sensorTask(void *pvParameters) -{ - AccelerationSensor *sensor = static_cast(pvParameters); - - while (true) + if (measurementCallback) { - if (sensor->activeSubscription) - { - - sensors_event_t a, g, temp; - - mpu.getEvent(&a, &g, &temp); - - float x = a.acceleration.x; - float y = a.acceleration.y; - float z = a.acceleration.z; - - if (sensor->measurementCallback) - { - sensor->measurementCallback(sensor->uuid, {x, y, z}); - } - - if (sensor->sendBLE) - { - sensor->notifyBLE(x, y, z); - } - } + measurementCallback({x, y, z}); + } - vTaskDelay(pdMS_TO_TICKS(500)); + if (sendBLE) + { + notifyBLE(x, y, z); } } void AccelerationSensor::notifyBLE(float x, float y, float z) { - // print characteristic - Serial.print("Acceleration Characteristic: "); - Serial.println(accCharacteristic); - Serial.printf("Acceleration: x: %f, y: %f, z: %f\n", x, y, z); - BLEModule::writeBLE(accCharacteristic, x, y, z); -} +} \ No newline at end of file diff --git a/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.h b/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.h index 39697ca..0b0d5fe 100644 --- a/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.h +++ b/senseBox-bike-atrai-v2/src/sensors/AccelerationSensor/AccelerationSensor.h @@ -1,25 +1,17 @@ #ifndef ACCELERATION_SENSOR_H #define ACCELERATION_SENSOR_H -#include "../Sensor.h" +#include "../BaseSensor.h" +#include -class AccelerationSensor : public Sensor +class AccelerationSensor : public BaseSensor { public: - void begin() override; - void subscribe(std::function)> callback) override; - void startSubscription() override; - void stopSubscription() override; - void startBLE() override; - void stopBLE() override; + AccelerationSensor(); -private: - std::function)> measurementCallback; - String uuid; - - static const String accUUID; - - static void sensorTask(void *pvParameters); +protected: + void initSensor() override; + void readSensorData() override; void notifyBLE(float x, float y, float z); }; diff --git a/senseBox-bike-atrai-v2/src/sensors/BaseSensor.cpp b/senseBox-bike-atrai-v2/src/sensors/BaseSensor.cpp new file mode 100644 index 0000000..0f84044 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/sensors/BaseSensor.cpp @@ -0,0 +1,49 @@ +#include "BaseSensor.h" + +BaseSensor::BaseSensor(const char *taskName, uint32_t taskStackSize, uint32_t taskDelay) + : activeSubscription(false), sendBLE(false), taskStackSize(taskStackSize), taskDelay(taskDelay) {} + +void BaseSensor::begin() +{ + initSensor(); + delay(1000); + xTaskCreate(sensorTask, taskName, taskStackSize, this, 1, NULL); +} + +void BaseSensor::subscribe(std::function)> callback) +{ + this->measurementCallback = callback; +} + +void BaseSensor::startSubscription() +{ + activeSubscription = true; +} + +void BaseSensor::stopSubscription() +{ + activeSubscription = false; +} + +void BaseSensor::startBLE() +{ + sendBLE = true; +} + +void BaseSensor::stopBLE() +{ + sendBLE = false; +} + +void BaseSensor::sensorTask(void *pvParameters) +{ + BaseSensor *sensor = static_cast(pvParameters); + while (true) + { + if (sensor->activeSubscription) + { + sensor->readSensorData(); + } + vTaskDelay(pdMS_TO_TICKS(sensor->taskDelay)); + } +} \ No newline at end of file diff --git a/senseBox-bike-atrai-v2/src/sensors/BaseSensor.h b/senseBox-bike-atrai-v2/src/sensors/BaseSensor.h new file mode 100644 index 0000000..912e07f --- /dev/null +++ b/senseBox-bike-atrai-v2/src/sensors/BaseSensor.h @@ -0,0 +1,35 @@ +#ifndef BASESENSOR_H +#define BASESENSOR_H + +#include +#include +#include +#include "../ble/BLEModule.h" + +class BaseSensor +{ +public: + BaseSensor(const char *taskName, uint32_t taskStackSize = 8192, uint32_t taskDelay = 1000); + + void begin(); + void subscribe(std::function)> callback); + void startSubscription(); + void stopSubscription(); + void startBLE(); + void stopBLE(); + +protected: + virtual void initSensor() = 0; + virtual void readSensorData() = 0; + static void sensorTask(void *pvParameters); + bool activeSubscription; + bool sendBLE; + std::function)> measurementCallback; + +private: + const char *taskName; + uint32_t taskStackSize; + uint32_t taskDelay; +}; + +#endif // BASESENSOR_H diff --git a/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.cpp b/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.cpp index 712100d..a164f83 100644 --- a/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.cpp +++ b/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.cpp @@ -1,104 +1,59 @@ #include "DistanceSensor.h" -#include -#include -#include +DistanceSensor::DistanceSensor() : BaseSensor("distanceTask", 8192, 1000) {} -const String DistanceSensor::distanceUUID = "B3491B60C0F34306A30D49C91F37A62B"; +String distanceUUID = "B3491B60C0F34306A30D49C91F37A62B"; +int distanceCharacteristic = 0; VL53L8CX sensor_vl53l8cx_top(&Wire, -1, -1); -int distanceCharacteristic = 0; - -void DistanceSensor::begin() +void DistanceSensor::initSensor() { - Wire.begin(); - Wire.setClock(1000000); // Sensor has max I2C freq of 1MHz - sensor_vl53l8cx_top.begin(); sensor_vl53l8cx_top.init_sensor(); sensor_vl53l8cx_top.vl53l8cx_set_ranging_frequency_hz(30); sensor_vl53l8cx_top.vl53l8cx_set_resolution(VL53L8CX_RESOLUTION_8X8); sensor_vl53l8cx_top.vl53l8cx_start_ranging(); distanceCharacteristic = BLEModule::createCharacteristic(distanceUUID.c_str()); - - sendBLE = false; - activeSubscription = true; - xTaskCreate(sensorTask, "DistanceSensorTask", 8192, this, 1, NULL); } -void DistanceSensor::subscribe(std::function)> callback) +void DistanceSensor::readSensorData() { - this->measurementCallback = callback; -} - -void DistanceSensor::startSubscription() -{ - activeSubscription = true; -} - -void DistanceSensor::stopSubscription() -{ - activeSubscription = false; -} - -void DistanceSensor::startBLE() -{ - setBLEStatus(true); -} - -void DistanceSensor::stopBLE() -{ - setBLEStatus(false); -} - -void DistanceSensor::sensorTask(void *pvParameters) -{ - DistanceSensor *sensor = static_cast(pvParameters); + Serial.println("Reading distance sensor data..."); VL53L8CX_ResultsData Results; uint8_t NewDataReady = 0; - uint8_t status; + uint8_t status = sensor_vl53l8cx_top.vl53l8cx_check_data_ready(&NewDataReady); - while (true) + float distance = -1.0; + + if ((!status) && (NewDataReady != 0)) { - if (sensor->activeSubscription) + sensor_vl53l8cx_top.vl53l8cx_get_ranging_data(&Results); + float min = 10000.0; + for (int i = 0; i < VL53L8CX_RESOLUTION_8X8 * VL53L8CX_NB_TARGET_PER_ZONE; i++) { - float oldVl53l8cxMin = -1.0; - status = sensor_vl53l8cx_top.vl53l8cx_check_data_ready(&NewDataReady); - - if ((!status) && (NewDataReady != 0)) + if (Results.target_status[i] != 255) { - sensor_vl53l8cx_top.vl53l8cx_get_ranging_data(&Results); - float min = 10000.0; - for (int i = 0; i < VL53L8CX_RESOLUTION_8X8 * VL53L8CX_NB_TARGET_PER_ZONE; i++) + float distance = Results.distance_mm[i]; + if (min > distance) { - if ((&Results)->target_status[i] != 255) - { - float distance = (&Results)->distance_mm[i]; - if (min > distance) - { - min = distance; - } - } + min = distance; } - oldVl53l8cxMin = (min == 10000.0) ? 0.0 : min; - } - - float distance = oldVl53l8cxMin / 10.0; - - if (sensor->measurementCallback) - { - sensor->measurementCallback(sensor->uuid, {distance}); - } - - if (sensor->sendBLE) - { - sensor->notifyBLE(distance); } } + distance = (min == 10000.0) ? 0.0 : min / 10.0; + Serial.printf("Distance: %.2f cm\n", distance); + } - vTaskDelay(pdMS_TO_TICKS(1000)); + if (measurementCallback) + { + measurementCallback({distance}); + } + + if (sendBLE) + { + notifyBLE(distance); } } diff --git a/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.h b/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.h index 801484f..62da62a 100644 --- a/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.h +++ b/senseBox-bike-atrai-v2/src/sensors/DistanceSensor/DistanceSensor.h @@ -1,26 +1,19 @@ -#ifndef DISTANCE_SENSOR_H -#define DISTANCE_SENSOR_H +#ifndef DISTANCESENSOR_H +#define DISTANCESENSOR_H -#include "../Sensor.h" +#include "../BaseSensor.h" +#include +#include -class DistanceSensor : public Sensor +class DistanceSensor : public BaseSensor { public: - void begin() override; - void subscribe(std::function)> callback) override; - void startSubscription() override; - void stopSubscription() override; - void startBLE() override; - void stopBLE() override; + DistanceSensor(); -private: - std::function)> measurementCallback; - String uuid; - - static const String distanceUUID; - - static void sensorTask(void *pvParameters); +protected: + void initSensor() override; + void readSensorData() override; void notifyBLE(float distance); }; -#endif // DISTANCE_SENSOR_H +#endif // DISTANCESENSOR_H diff --git a/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.cpp b/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.cpp index 9e851f2..8f2ef76 100644 --- a/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.cpp +++ b/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.cpp @@ -1,19 +1,20 @@ #include "DustSensor.h" -#include -#include -#include -const String DustSensor::pmUUID = "7E14E07084EA489FB45AE1317364B979"; +DustSensor::DustSensor() : BaseSensor("DustSensorTask", 2048, 1000) {} +String dustUUID = "7E14E07084EA489FB45AE1317364B979"; int dustCharacteristic = 0; -void DustSensor::begin() +// add more if needed + +void DustSensor::initSensor() { int16_t ret; uint8_t auto_clean_days = 4; uint32_t auto_clean; - Serial.println("Dust Setup"); + Serial.begin(9600); + delay(2000); sensirion_i2c_init(); @@ -23,6 +24,8 @@ void DustSensor::begin() delay(500); } + Serial.print("SPS sensor probing successful\n"); + ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days); if (ret) { @@ -36,100 +39,69 @@ void DustSensor::begin() Serial.print("error starting measurement\n"); } - dustCharacteristic = BLEModule::createCharacteristic(pmUUID.c_str()); - - sendBLE = false; - activeSubscription = true; - - xTaskCreate(sensorTask, "DustSensorTask", 2048, this, 1, NULL); -} + Serial.print("measurements started\n"); -void DustSensor::subscribe(std::function)> callback) -{ - this->measurementCallback = callback; + dustCharacteristic = BLEModule::createCharacteristic(dustUUID.c_str()); } -void DustSensor::startSubscription() +void DustSensor::readSensorData() { - activeSubscription = true; -} - -void DustSensor::stopSubscription() -{ - activeSubscription = false; -} + struct sps30_measurement m; + char serial[SPS30_MAX_SERIAL_LEN]; + uint16_t data_ready; + int16_t ret; -void DustSensor::startBLE() -{ - setBLEStatus(true); -} + // retry 5 times until the sensor has data ready + int retries = 5; + int retryCount = 0; + do + { + ret = sps30_read_data_ready(&data_ready); + if (ret < 0) + { + Serial.print("error reading data-ready flag: "); + Serial.println(ret); + } + else if (!data_ready) + Serial.print("data not ready, no new measurement available\n"); + else + break; + retryCount++; + delay(100); /* retry in 100ms */ + } while (retryCount <= retries); + + if (retryCount > retries) + { + Serial.print("No data available\n"); + return; + } -void DustSensor::stopBLE() -{ - setBLEStatus(false); -} + ret = sps30_read_measurement(&m); + if (ret < 0) + { + Serial.print("error reading measurement\n"); + } + else + { -void DustSensor::sensorTask(void *pvParameters) -{ - DustSensor *sensor = static_cast(pvParameters); + float pm1 = m.mc_1p0; + float pm2_5 = m.mc_2p5; + float pm4 = m.mc_4p0; + float pm10 = m.mc_10p0; - while (true) - { - if (sensor->activeSubscription) + if (measurementCallback) { - - struct sps30_measurement m; - char serial[SPS30_MAX_SERIAL_LEN]; - uint16_t data_ready; - int16_t ret; - - do - { - ret = sps30_read_data_ready(&data_ready); - if (ret < 0) - { - Serial.print("error reading data-ready flag: "); - Serial.println(ret); - } - else if (!data_ready) - Serial.print("data not ready, no new measurement available\n"); - else - break; - delay(100); /* retry in 100ms */ - } while (1); - - ret = sps30_read_measurement(&m); - if (ret < 0) - { - Serial.print("error reading measurement\n"); - } - else - { - float pm1 = m.mc_1p0; - float pm2_5 = m.mc_2p5; - float pm4 = m.mc_4p0; - float pm10 = m.mc_10p0; - - if (sensor->measurementCallback) - { - sensor->measurementCallback(sensor->uuid, {pm1, pm2_5, pm4, pm10}); - } - - if (sensor->sendBLE) - { - sensor->notifyBLE(pm1, pm2_5, pm4, pm10); - } - } + measurementCallback({pm1, pm2_5, pm4, pm10}); } - vTaskDelay(pdMS_TO_TICKS(2000)); + if (sendBLE) + { + notifyBLE(pm1, pm2_5, pm4, pm10); + } } } void DustSensor::notifyBLE(float pm1, float pm2_5, float pm4, float pm10) { - Serial.print("Dust Characteristic: "); - Serial.println(dustCharacteristic); - Serial.printf("Dust: PM1: %f, PM2.5: %f, PM4: %f, PM10: %f\n", pm1, pm2_5, pm4, pm10); - BLEModule::writeBLE(characteristicId, pm1, pm2_5, pm4, pm10); -} + BLEModule::writeBLE(dustCharacteristic, pm1, pm2_5, pm4, pm10); +} \ No newline at end of file diff --git a/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.h b/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.h index 0e6e89b..2dea590 100644 --- a/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.h +++ b/senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.h @@ -1,25 +1,19 @@ #ifndef DUST_SENSOR_H #define DUST_SENSOR_H -#include "../Sensor.h" +#include "../BaseSensor.h" +#include -class DustSensor : public Sensor +// include necceary libraries + +class DustSensor : public BaseSensor { public: - void begin() override; - void subscribe(std::function)> callback) override; - void startSubscription() override; - void stopSubscription() override; - void startBLE() override; - void stopBLE() override; - -private: - std::function)> measurementCallback; - String uuid; - - static const String pmUUID; + DustSensor(); - static void sensorTask(void *pvParameters); +protected: + void initSensor() override; + void readSensorData() override; void notifyBLE(float pm1, float pm2_5, float pm4, float pm10); }; diff --git a/senseBox-bike-atrai-v2/src/sensors/SampleSensor/SampleSensor.cpp b/senseBox-bike-atrai-v2/src/sensors/SampleSensor/SampleSensor.cpp new file mode 100644 index 0000000..9838781 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/sensors/SampleSensor/SampleSensor.cpp @@ -0,0 +1,37 @@ +#include "SampleSensor.h" + +SampleSensor::SampleSensor() : BaseSensor("sampleSensorTask", 2048, 1000) {} + +String sampleUUID = "00000000000000000"; +int sampleCharacteristic = 0; + +// add more if needed + +void SampleSensor::initSensor() +{ + // init sensor + + sampleCharacteristic = BLEModule::createCharacteristic(sampleUUID.c_str()); + // add more if needed +} + +void SampleSensor::readSensorData() +{ + float sampleValue = 0.0; + // read sensor data + + if (measurementCallback) + { + measurementCallback({sampleValue}); + } + + if (sendBLE) + { + notifyBLE(sampleValue); + } +} + +void SampleSensor::notifyBLE(float sampleValue) +{ + BLEModule::writeBLE(sampleCharacteristic, sampleValue); +} \ No newline at end of file diff --git a/senseBox-bike-atrai-v2/src/sensors/SampleSensor/SampleSensor.h b/senseBox-bike-atrai-v2/src/sensors/SampleSensor/SampleSensor.h new file mode 100644 index 0000000..3cf5676 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/sensors/SampleSensor/SampleSensor.h @@ -0,0 +1,19 @@ +#ifndef SAMPLE_SENSOR_H +#define SAMPLE_SENSOR_H + +#include "../BaseSensor.h" + +// include necceary libraries + +class SampleSensor : public BaseSensor +{ +public: + SampleSensor(); + +protected: + void initSensor() override; + void readSensorData() override; + void notifyBLE(float sampleValue); // change this to match the data type of the sensor data +}; + +#endif // SAMPLE_SENSOR_H diff --git a/senseBox-bike-atrai-v2/src/sensors/Sensor.cpp b/senseBox-bike-atrai-v2/src/sensors/Sensor.cpp deleted file mode 100644 index 6b9a34a..0000000 --- a/senseBox-bike-atrai-v2/src/sensors/Sensor.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "Sensor.h" - -void Sensor::setBLEStatus(bool status) -{ - sendBLE = status; -} diff --git a/senseBox-bike-atrai-v2/src/sensors/Sensor.h b/senseBox-bike-atrai-v2/src/sensors/Sensor.h deleted file mode 100644 index b7570a7..0000000 --- a/senseBox-bike-atrai-v2/src/sensors/Sensor.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SENSOR_H -#define SENSOR_H - -#include -#include -#include -#include "../ble/BLEModule.h" - -class Sensor -{ -public: - virtual void begin() = 0; - virtual void subscribe(std::function)> callback) = 0; - virtual void startSubscription() = 0; - virtual void stopSubscription() = 0; - virtual void startBLE() = 0; - virtual void stopBLE() = 0; - -protected: - bool sendBLE; - bool activeSubscription; - - int characteristicId; - void setBLEStatus(bool status); -}; - -#endif // SENSOR_H diff --git a/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.cpp b/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.cpp index edbfd19..6972c5e 100644 --- a/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.cpp +++ b/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.cpp @@ -1,18 +1,16 @@ #include "TempHumiditySensor.h" -#include -#include -#include "Adafruit_HDC1000.h" +TempHumiditySensor::TempHumiditySensor() : BaseSensor("temperatureHumidityTask", 2048, 1000) {} -const String TempHumiditySensor::tempUUID = "2CDF217435BEFDC44CA26FD173F8B3A8"; -const String TempHumiditySensor::humUUID = "772DF7EC8CDC4EA986AF410ABE0BA257"; +String tempUUID = "2CDF217435BEFDC44CA26FD173F8B3A8"; +String humUUID = "772DF7EC8CDC4EA986AF410ABE0BA257"; int temperatureCharacteristic = 0; int humidityCharacteristic = 0; -Adafruit_HDC1000 hdc = Adafruit_HDC1000(); +Adafruit_HDC1000 hdc; -void TempHumiditySensor::begin() +void TempHumiditySensor::initSensor() { if (!hdc.begin()) { @@ -23,69 +21,26 @@ void TempHumiditySensor::begin() temperatureCharacteristic = BLEModule::createCharacteristic(tempUUID.c_str()); humidityCharacteristic = BLEModule::createCharacteristic(humUUID.c_str()); - - sendBLE = false; - activeSubscription = true; - xTaskCreate(sensorTask, "TempHumiditySensorTask", 2048, this, 1, NULL); -} - -void TempHumiditySensor::subscribe(std::function)> callback) -{ - this->measurementCallback = callback; -} - -void TempHumiditySensor::startSubscription() -{ - activeSubscription = true; -} - -void TempHumiditySensor::stopSubscription() -{ - activeSubscription = false; -} - -void TempHumiditySensor::startBLE() -{ - setBLEStatus(true); -} - -void TempHumiditySensor::stopBLE() -{ - setBLEStatus(false); } -void TempHumiditySensor::sensorTask(void *pvParameters) +void TempHumiditySensor::readSensorData() { - TempHumiditySensor *sensor = static_cast(pvParameters); + float temperature = hdc.readTemperature(); + float humidity = hdc.readHumidity(); - while (true) + if (measurementCallback) { - if (sensor->activeSubscription) - { - float temperature = hdc.readTemperature(); - float humidity = hdc.readHumidity(); - - if (sensor->measurementCallback) - { - sensor->measurementCallback(sensor->uuid, {temperature, humidity}); - } - - if (sensor->sendBLE) - { - sensor->notifyBLE(temperature, humidity); - } - } + measurementCallback({temperature, humidity}); + } - vTaskDelay(pdMS_TO_TICKS(5000)); + if (sendBLE) + { + notifyBLE(temperature, humidity); } } -void TempHumiditySensor::notifyBLE(float temperature, float humidity) +void TempHumiditySensor::notifyBLE(float temoperature, float humidity) { - Serial.println("Notifying BLE"); - Serial.println(temperature); - Serial.println(temperatureCharacteristic); - - BLEModule::writeBLE(temperatureCharacteristic, temperature); + BLEModule::writeBLE(temperatureCharacteristic, temoperature); BLEModule::writeBLE(humidityCharacteristic, humidity); -} +} \ No newline at end of file diff --git a/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.h b/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.h index 728c068..84f0448 100644 --- a/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.h +++ b/senseBox-bike-atrai-v2/src/sensors/TempHumiditySensor/TempHumiditySensor.h @@ -1,27 +1,18 @@ #ifndef TEMP_HUMIDITY_SENSOR_H #define TEMP_HUMIDITY_SENSOR_H -#include "../Sensor.h" +#include "../BaseSensor.h" +#include "Adafruit_HDC1000.h" -class TempHumiditySensor : public Sensor +class TempHumiditySensor : public BaseSensor { public: - void begin() override; - void subscribe(std::function)> callback) override; - void startSubscription() override; - void stopSubscription() override; - void startBLE() override; - void stopBLE() override; + TempHumiditySensor(); -private: - std::function)> measurementCallback; - String uuid; - - static const String tempUUID; - static const String humUUID; - - static void sensorTask(void *pvParameters); +protected: + void initSensor() override; + void readSensorData() override; void notifyBLE(float temperature, float humidity); }; -#endif // TEMP_HUMIDITY_SENSOR_H +#endif // DISTANCESENSOR_H diff --git a/senseBox-bike-atrai-v2/src/update/SoftwareUpdater.cpp b/senseBox-bike-atrai-v2/src/update/SoftwareUpdater.cpp new file mode 100644 index 0000000..b83b520 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/update/SoftwareUpdater.cpp @@ -0,0 +1,78 @@ +#include "SoftwareUpdater.h" +#include "root_ca.h" + +SoftwareUpdater::SoftwareUpdater() +{ + ssid = ""; + password = ""; +} + +void SoftwareUpdater::setSSID(String ssid) +{ + this->ssid = ssid; +} + +void SoftwareUpdater::setPassword(String password) +{ + this->password = password; +} + +void SoftwareUpdater::startUpdate() +{ + // Check if the SSID and password are set + if (ssid == "" || password == "") + { + return; + } + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("Attempting to connect to '"); + Serial.print(ssid); + Serial.println("'"); + WiFi.begin(ssid, password); + delay(2000); + } + Serial.print("You're connected to '"); + Serial.print(WiFi.SSID()); + Serial.println("'"); + + Arduino_ESP32_OTA ota; + Arduino_ESP32_OTA::Error ota_err = Arduino_ESP32_OTA::Error::None; + + /* Configure custom Root CA */ + ota.setCACert(root_ca); + + Serial.println("Initializing OTA storage"); + if ((ota_err = ota.begin()) != Arduino_ESP32_OTA::Error::None) + { + Serial.print("Arduino_ESP_OTA::begin() failed with error code "); + Serial.println((int)ota_err); + return; + } + + Serial.println("Starting download to flash ..."); + int const ota_download = ota.download(OTA_FILE_LOCATION); + if (ota_download <= 0) + { + Serial.print("Arduino_ESP_OTA::download failed with error code "); + Serial.println(ota_download); + return; + } + Serial.print(ota_download); + Serial.println(" bytes stored."); + + Serial.println("Verify update integrity and apply ..."); + if ((ota_err = ota.update()) != Arduino_ESP32_OTA::Error::None) + { + Serial.print("ota.update() failed with error code "); + Serial.println((int)ota_err); + return; + } + + Serial.println("Performing a reset after which the bootloader will start the new firmware."); + + delay(1000); + + ota.reset(); +} \ No newline at end of file diff --git a/senseBox-bike-atrai-v2/src/update/SoftwareUpdater.h b/senseBox-bike-atrai-v2/src/update/SoftwareUpdater.h new file mode 100644 index 0000000..3b7d152 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/update/SoftwareUpdater.h @@ -0,0 +1,27 @@ +#ifndef SOFTWARE_UPDATER_H +#define SOFTWARE_UPDATER_H + +#include +#include + +#include + + +static char const OTA_FILE_LOCATION[] = "https://raw.githubusercontent.com/felixerdy/esp32-ota-test/main/senseBox-bike-atrai.ino.ota"; + +class SoftwareUpdater +{ +public: + SoftwareUpdater(); + + void setSSID(String ssid); + void setPassword(String password); + + void startUpdate(); + +private: + String ssid; + String password; +}; + +#endif // SOFTWARE_UPDATER_H diff --git a/senseBox-bike-atrai-v2/src/update/root_ca.h b/senseBox-bike-atrai-v2/src/update/root_ca.h new file mode 100644 index 0000000..16381d7 --- /dev/null +++ b/senseBox-bike-atrai-v2/src/update/root_ca.h @@ -0,0 +1,54 @@ +const char *root_ca = /*DigiCert TLS Hybrid ECC SHA384 2020 CA1*/ + "-----BEGIN CERTIFICATE-----\n" + "MIIEFzCCAv+gAwIBAgIQB/LzXIeod6967+lHmTUlvTANBgkqhkiG9w0BAQwFADBh\n" + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" + "QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaMFYxCzAJBgNVBAYTAlVT\n" + "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMDAuBgNVBAMTJ0RpZ2lDZXJ0IFRMUyBI\n" + "eWJyaWQgRUNDIFNIQTM4NCAyMDIwIENBMTB2MBAGByqGSM49AgEGBSuBBAAiA2IA\n" + "BMEbxppbmNmkKaDp1AS12+umsmxVwP/tmMZJLwYnUcu/cMEFesOxnYeJuq20ExfJ\n" + "qLSDyLiQ0cx0NTY8g3KwtdD3ImnI8YDEe0CPz2iHJlw5ifFNkU3aiYvkA8ND5b8v\n" + "c6OCAYIwggF+MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAq8CCkXjKU5\n" + "bXoOzjPHLrPt+8N6MB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA4G\n" + "A1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYI\n" + "KwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j\n" + "b20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp\n" + "Q2VydEdsb2JhbFJvb3RDQS5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2Ny\n" + "bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAE\n" + "NjA0MAsGCWCGSAGG/WwCATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgG\n" + "BmeBDAECAzANBgkqhkiG9w0BAQwFAAOCAQEAR1mBf9QbH7Bx9phdGLqYR5iwfnYr\n" + "6v8ai6wms0KNMeZK6BnQ79oU59cUkqGS8qcuLa/7Hfb7U7CKP/zYFgrpsC62pQsY\n" + "kDUmotr2qLcy/JUjS8ZFucTP5Hzu5sn4kL1y45nDHQsFfGqXbbKrAjbYwrwsAZI/\n" + "BKOLdRHHuSm8EdCGupK8JvllyDfNJvaGEwwEqonleLHBTnm8dqMLUeTF0J5q/hos\n" + "Vq4GNiejcxwIfZMy0MJEGdqN9A57HSgDKwmKdsp33Id6rHtSJlWncg+d0ohP/rEh\n" + "xRqhqjn1VtvChMQ1H3Dau0bwhr9kAMQ+959GG50jBbl9s08PqUU643QwmA==\n" + "-----END CERTIFICATE-----\n" + /*DigiCert TLS RSA SHA256 2020 CA1*/ + "-----BEGIN CERTIFICATE-----\n" + "MIIEvjCCA6agAwIBAgIQBtjZBNVYQ0b2ii+nVCJ+xDANBgkqhkiG9w0BAQsFADBh\n" + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" + "QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaME8xCzAJBgNVBAYTAlVT\n" + "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxKTAnBgNVBAMTIERpZ2lDZXJ0IFRMUyBS\n" + "U0EgU0hBMjU2IDIwMjAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" + "AQEAwUuzZUdwvN1PWNvsnO3DZuUfMRNUrUpmRh8sCuxkB+Uu3Ny5CiDt3+PE0J6a\n" + "qXodgojlEVbbHp9YwlHnLDQNLtKS4VbL8Xlfs7uHyiUDe5pSQWYQYE9XE0nw6Ddn\n" + "g9/n00tnTCJRpt8OmRDtV1F0JuJ9x8piLhMbfyOIJVNvwTRYAIuE//i+p1hJInuW\n" + "raKImxW8oHzf6VGo1bDtN+I2tIJLYrVJmuzHZ9bjPvXj1hJeRPG/cUJ9WIQDgLGB\n" + "Afr5yjK7tI4nhyfFK3TUqNaX3sNk+crOU6JWvHgXjkkDKa77SU+kFbnO8lwZV21r\n" + "eacroicgE7XQPUDTITAHk+qZ9QIDAQABo4IBgjCCAX4wEgYDVR0TAQH/BAgwBgEB\n" + "/wIBADAdBgNVHQ4EFgQUt2ui6qiqhIx56rTaD5iyxZV2ufQwHwYDVR0jBBgwFoAU\n" + "A95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQG\n" + "CCsGAQUFBwMBBggrBgEFBQcDAjB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGG\n" + "GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2Nh\n" + "Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNydDBCBgNV\n" + "HR8EOzA5MDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRH\n" + "bG9iYWxSb290Q0EuY3JsMD0GA1UdIAQ2MDQwCwYJYIZIAYb9bAIBMAcGBWeBDAEB\n" + "MAgGBmeBDAECATAIBgZngQwBAgIwCAYGZ4EMAQIDMA0GCSqGSIb3DQEBCwUAA4IB\n" + "AQCAMs5eC91uWg0Kr+HWhMvAjvqFcO3aXbMM9yt1QP6FCvrzMXi3cEsaiVi6gL3z\n" + "ax3pfs8LulicWdSQ0/1s/dCYbbdxglvPbQtaCdB73sRD2Cqk3p5BJl+7j5nL3a7h\n" + "qG+fh/50tx8bIKuxT8b1Z11dmzzp/2n3YWzW2fP9NsarA4h20ksudYbj/NhVfSbC\n" + "EXffPgK2fPOre3qGNm+499iTcc+G33Mw+nur7SpZyEKEOxEXGlLzyQ4UfaJbcme6\n" + "ce1XR2bFuAJKZTRei9AqPCCcUZlM51Ke92sRKw2Sfh3oius2FkOH6ipjv3U/697E\n" + "A7sKPPcw7+uvTPyLNhBzPvOk\n" + "-----END CERTIFICATE-----\n"; \ No newline at end of file