Skip to content

Commit

Permalink
feat: read wifi credentials via ble for ota
Browse files Browse the repository at this point in the history
  • Loading branch information
felixerdy committed Jun 7, 2024
1 parent 93e365a commit 6b87225
Show file tree
Hide file tree
Showing 12 changed files with 359 additions and 76 deletions.
2 changes: 2 additions & 0 deletions senseBox-bike-atrai-v2/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ lib_deps =
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
37 changes: 24 additions & 13 deletions senseBox-bike-atrai-v2/src/ble/BLEModule.cpp
Original file line number Diff line number Diff line change
@@ -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 = "";
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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));
}
}
9 changes: 4 additions & 5 deletions senseBox-bike-atrai-v2/src/ble/BLEModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
32 changes: 32 additions & 0 deletions senseBox-bike-atrai-v2/src/ble/Utf16Converter/Utf16Converter.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef UTF16_CONVERTER_H
#define UTF16_CONVERTER_H

#include <Arduino.h>

String utf16leToString(uint8_t *data, size_t length);

#endif // UTF16_CONVERTER_H
4 changes: 3 additions & 1 deletion senseBox-bike-atrai-v2/src/display/Display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down
170 changes: 115 additions & 55 deletions senseBox-bike-atrai-v2/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,41 @@
#include "sensors/AccelerationSensor/AccelerationSensor.h"
#include "display/Display.h"
#include "ble/BLEModule.h"
#include "update/SoftwareUpdater.h"

#include "Adafruit_NeoPixel.h"

// --- Sensor instances ---
DustSensor dustSensor;
TempHumiditySensor tempHumiditySensor;
DistanceSensor distanceSensor;
AccelerationSensor accelerationSensor;

BaseSensor *sensors[] = {&dustSensor, &tempHumiditySensor, &distanceSensor, &accelerationSensor};

// --- Display instance ---
SBDisplay display;

// --- BLE instance ---
BLEModule bleModule;

Adafruit_NeoPixel rgb_led = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800);
// --- 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);

rgb_led.begin();

rgb_led.setBrightness(30);

SBDisplay::begin();

pinMode(IO_ENABLE, OUTPUT);
Expand All @@ -36,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<float> 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<float> values)
// { Serial.printf("DistanceSensor [%s]: %.2f\n", values[0]); });

// accelerationSensor.subscribe([](String uuid, std::vector<float> 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); });

dustSensor.startSubscription();
tempHumiditySensor.startSubscription();
distanceSensor.startSubscription();
accelerationSensor.startSubscription();

dustSensor.startBLE();
tempHumiditySensor.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<State>(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<float> 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<float> values)
// // { Serial.printf("DistanceSensor [%s]: %.2f\n", values[0]); });

// // accelerationSensor.subscribe([](String uuid, std::vector<float> 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();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "DistanceSensor.h"

DistanceSensor::DistanceSensor() : BaseSensor("distanceTask", 8192, 100) {}
DistanceSensor::DistanceSensor() : BaseSensor("distanceTask", 8192, 1000) {}

String distanceUUID = "B3491B60C0F34306A30D49C91F37A62B";
int distanceCharacteristic = 0;
Expand Down
12 changes: 11 additions & 1 deletion senseBox-bike-atrai-v2/src/sensors/DustSensor/DustSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ void DustSensor::readSensorData()
uint16_t data_ready;
int16_t ret;

// retry 5 times until the sensor has data ready
int retries = 5;
int retryCount = 0;
do
{
ret = sps30_read_data_ready(&data_ready);
Expand All @@ -63,8 +66,15 @@ void DustSensor::readSensorData()
Serial.print("data not ready, no new measurement available\n");
else
break;
retryCount++;
delay(100); /* retry in 100ms */
} while (1);
} while (retryCount <= retries);

if (retryCount > retries)
{
Serial.print("No data available\n");
return;
}

ret = sps30_read_measurement(&m);
if (ret < 0)
Expand Down
Loading

0 comments on commit 6b87225

Please sign in to comment.