Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: refactor sensor code #344

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
15 changes: 14 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ src_dir = src
extra_configs = custom_config.ini

[env:esp32dev]
platform = espressif32 @ 5.3.0
build_type = release
platform = [email protected]
platform_packages =
[email protected]+20230208
framework-arduinoespressif32@https://github.com/espressif/arduino-esp32#2.0.11
board = esp32dev
framework = arduino
monitor_speed = 115200
Expand Down Expand Up @@ -66,3 +70,12 @@ build_flags =
-DHTTPS_CONNECTION_DATA_CHUNK_SIZE=1024
; build number "-dev" will be replaced in github action
-DBUILD_NUMBER=\"-dev\"
-Wall
-std=gnu++20
-fno-rtti
build_unflags =
-std=gnu++11
debug_build_flags =
-Os
debug_build_unflags =
-Og
91 changes: 35 additions & 56 deletions src/OpenBikeSensorFirmware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ Button button(PUSHBUTTON_PIN);
Config config;

SSD1306DisplayDevice* obsDisplay;
HCSR04SensorManager* sensorManager;
DistanceSensorManager* sensorManager;
#ifdef OBS_BLUETOOTH
static BluetoothManager* bluetoothManager;
#endif

Gps gps;

#ifdef OBS_BLUETOOTH
static const long BLUETOOTH_INTERVAL_MILLIS = 100;
static long lastBluetoothInterval = 0;
#endif

static const long DISPLAY_INTERVAL_MILLIS = 25;
static long lastDisplayInterval = 0;
Expand Down Expand Up @@ -104,7 +108,6 @@ uint8_t batteryPercentage();
void serverLoop();
void handleButtonInServerMode();
bool loadConfig(ObsConfig &cfg);
void copyCollectedSensorData(DataSet *set);

// The BMP280 can keep up to 3.4MHz I2C speed, so no need for an individual slower speed
void switch_wire_speed_to_VL53(){
Expand All @@ -114,26 +117,14 @@ void switch_wire_speed_to_SSD1306(){
Wire.setClock(500000);
}

// FIXME
void setupSensors() {
sensorManager = new HCSR04SensorManager;

HCSR04SensorInfo sensorManaged1;
sensorManaged1.triggerPin = (config.displayConfig & DisplaySwapSensors) ? 25 : 15;
sensorManaged1.echoPin = (config.displayConfig & DisplaySwapSensors) ? 26 : 4;
sensorManaged1.sensorLocation = (char*) "Right"; // TODO
sensorManager->registerSensor(sensorManaged1, 0);

HCSR04SensorInfo sensorManaged2;
sensorManaged2.triggerPin = (config.displayConfig & DisplaySwapSensors) ? 15 : 25;
sensorManaged2.echoPin = (config.displayConfig & DisplaySwapSensors) ? 4 : 26;
sensorManaged2.sensorLocation = (char*) "Left"; // TODO
sensorManager->registerSensor(sensorManaged2, 1);

sensorManager = new DistanceSensorManager;
sensorManager->setOffsets(config.sensorOffsets);

sensorManager->setPrimarySensor(LEFT_SENSOR_ID);
sensorManager->initSensors();
}

#ifdef OBS_BLUETOOTH
static void setupBluetooth(const ObsConfig &cfg, const String &trackUniqueIdentifier) {
if (cfg.getProperty<bool>(ObsConfig::PROPERTY_BLUETOOTH)) {
obsDisplay->showTextOnGrid(2, obsDisplay->newLine(), "Bluetooth ..");
Expand Down Expand Up @@ -193,6 +184,7 @@ static void buttonBluetooth(const DataSet *dataSet, uint16_t measureIndex) {
left, right);
}
}
#endif

void setup() {
Serial.begin(115200);
Expand Down Expand Up @@ -261,12 +253,6 @@ void setup() {
}
delay(333); // Added for user experience

//##############################################################
// Init HCSR04
//##############################################################

setupSensors();

//##############################################################
// Check, if the button is pressed
// Enter configuration mode and enable OTA
Expand All @@ -283,8 +269,10 @@ void setup() {

if (button.read() == HIGH || triggerServerMode) {
obsDisplay->showTextOnGrid(2, obsDisplay->newLine(), "Start Server");
#ifdef OBS_BLUETOOTH
ESP_ERROR_CHECK_WITHOUT_ABORT(
esp_bt_mem_release(ESP_BT_MODE_BTDM)); // no bluetooth at all here.
#endif

delay(200);
startServer(&cfg);
Expand Down Expand Up @@ -333,7 +321,9 @@ void setup() {

gps.handle();

#ifdef OBS_BLUETOOTH
setupBluetooth(cfg, trackUniqueIdentifier);
#endif

obsDisplay->showTextOnGrid(2, obsDisplay->newLine(), "Wait for GPS");
obsDisplay->newLine();
Expand All @@ -343,8 +333,6 @@ void setup() {
while (!gps.hasFix(obsDisplay)) {
currentTimeMillis = millis();
gps.handle();
sensorManager->pollDistancesAlternating();
reportBluetooth();
gps.showWaitStatus(obsDisplay);
if (button.read() == HIGH) {
log_d("Skipped get GPS...");
Expand All @@ -360,12 +348,16 @@ void setup() {
gps.handle(1100); // Added for user experience
gps.pollStatistics();
obsDisplay->clear();

//##############################################################
// Init HCSR04
//##############################################################
setupSensors();
}

void serverLoop() {
gps.handle();
configServerHandle();
sensorManager->pollDistancesAlternating();
handleButtonInServerMode();
}

Expand Down Expand Up @@ -426,7 +418,7 @@ void loop() {
currentSet->millis = startTimeMillis;
currentSet->batteryLevel = voltageMeter->read();

lastMeasurements = sensorManager->m_sensors[confirmationSensorID].numberOfTriggers;
lastMeasurements = sensorManager->getSensor(confirmationSensorID)->numberOfTriggers;
sensorManager->reset(startTimeMillis);

// if the detected minimum was measured more than 5s ago, it is discarded and cannot be confirmed
Expand All @@ -449,18 +441,11 @@ void loop() {
}
button.handle(currentTimeMillis);
gps.handle();
if (sensorManager->pollDistancesAlternating()) {
if (sensorManager->pollDistances()) {
// if a new minimum on the selected sensor is detected, the value and the time of detection will be stored
const uint16_t reading = sensorManager->sensorValues[confirmationSensorID];
const uint16_t reading = sensorManager->getLastValidRawDistance(confirmationSensorID);
if (reading > 0 && reading < minDistanceToConfirm) {
minDistanceToConfirm = reading;
minDistanceToConfirmIndex = sensorManager->getCurrentMeasureIndex();
// if there was no measurement of this sensor for this index, it is the
// one before. This happens with fast confirmations.
while (minDistanceToConfirmIndex > 0
&& sensorManager->m_sensors[confirmationSensorID].echoDurationMicroseconds[minDistanceToConfirmIndex] <= 0) {
minDistanceToConfirmIndex--;
}
datasetToConfirm = currentSet;
timeOfMinimum = currentTimeMillis;
}
Expand All @@ -469,8 +454,8 @@ void loop() {
if (lastDisplayInterval != (currentTimeMillis / DISPLAY_INTERVAL_MILLIS)) {
lastDisplayInterval = currentTimeMillis / DISPLAY_INTERVAL_MILLIS;
obsDisplay->showValues(
sensorManager->m_sensors[LEFT_SENSOR_ID],
sensorManager->m_sensors[RIGHT_SENSOR_ID],
sensorManager->getSensor(LEFT_SENSOR_ID),
sensorManager->getSensor(RIGHT_SENSOR_ID),
minDistanceToConfirm,
voltageMeter->readPercentage(),
(int16_t) TemperatureValue,
Expand All @@ -481,7 +466,9 @@ void loop() {
);
}
gps.handle();
#ifdef OBS_BLUETOOTH
reportBluetooth();
#endif
if (button.gotPressed()) { // after button was released, detect long press here
// immediate user feedback - we start the action
obsDisplay->highlight();
Expand All @@ -491,13 +478,18 @@ void loop() {
if (datasetToConfirm != nullptr) {
datasetToConfirm->confirmedDistances.push_back(minDistanceToConfirm);
datasetToConfirm->confirmedDistancesIndex.push_back(minDistanceToConfirmIndex);
#ifdef OBS_BLUETOOTH
buttonBluetooth(datasetToConfirm, minDistanceToConfirmIndex);
#endif
datasetToConfirm = nullptr;
} else { // confirming an overtake without left measure
currentSet->confirmedDistances.push_back(MAX_SENSOR_VALUE);
currentSet->confirmedDistancesIndex.push_back(
sensorManager->getCurrentMeasureIndex());
if (sensorManager->hasReadings(LEFT_SENSOR_ID)) {
currentSet->confirmedDistances.push_back(MAX_SENSOR_VALUE);
currentSet->confirmedDistancesIndex.push_back(0);
}
#ifdef OBS_BLUETOOTH
buttonBluetooth(currentSet, sensorManager->getCurrentMeasureIndex());
#endif
}
minDistanceToConfirm = MAX_SENSOR_VALUE; // ready for next confirmation
}
Expand All @@ -510,7 +502,7 @@ void loop() {
currentSet->gpsRecord = gps.getCurrentGpsRecord();
currentSet->isInsidePrivacyArea = gps.isInsidePrivacyArea();
if (currentSet->gpsRecord.getTow() == thisLoopTow) {
copyCollectedSensorData(currentSet);
sensorManager->copyData(currentSet);
log_d("NEW SET: TOW: %u GPSms: %u, SETms: %u, GPS Time: %s, SET Time: %s, innerLoops: %d, buffer: %d, write time %3ums, loop time: %4ums, measurements: %2d",
currentSet->gpsRecord.getTow(), currentSet->gpsRecord.getCreatedAtMillisTicks(),
currentSet->millis,
Expand Down Expand Up @@ -561,19 +553,6 @@ void loop() {
TimeUtils::timeToString().c_str(), thisLoopTow);
}

void copyCollectedSensorData(DataSet *set) {// Write the minimum values of the while-loop to a set
for (auto & m_sensor : sensorManager->m_sensors) {
set->sensorValues.push_back(m_sensor.minDistance);
}
set->measurements = sensorManager->lastReadingCount;
memcpy(&(set->readDurationsRightInMicroseconds),
&(sensorManager->m_sensors[0].echoDurationMicroseconds), set->measurements * sizeof(int32_t));
memcpy(&(set->readDurationsLeftInMicroseconds),
&(sensorManager->m_sensors[1].echoDurationMicroseconds), set->measurements * sizeof(int32_t));
memcpy(&(set->startOffsetMilliseconds),
&(sensorManager->startOffsetMilliseconds), set->measurements * sizeof(uint16_t));
}

uint8_t batteryPercentage() {
uint8_t result = 0;
if (voltageMeter) {
Expand Down
4 changes: 4 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include <vector>
#include <FS.h>

#include <string>

typedef std::basic_string<char> obs_string;

enum DisplayOptions {
DisplaySatellites = 0x01, // 1
DisplayVelocity = 0x02, // 2
Expand Down
Loading