2023-06-13 19:59:34 +02:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include <ArduinoBLE.h>
|
2023-06-14 19:22:11 +02:00
|
|
|
|
|
|
|
#include "settings.hpp"
|
|
|
|
#include "status.hpp"
|
|
|
|
#include "services.hpp"
|
2023-06-24 02:59:22 +02:00
|
|
|
#include "measure.hpp"
|
2023-06-14 19:22:11 +02:00
|
|
|
|
2023-06-19 15:55:21 +02:00
|
|
|
// TODO
|
|
|
|
/* std::array<uint16_t, 10000> valueBuffer; // 20kB buffer for readings */
|
|
|
|
/* auto valueBufferWriteIter = valueBuffer.begin(); // points past the element that was last written */
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-06-13 19:59:34 +02:00
|
|
|
void blinkLED(unsigned n=5, unsigned delay_=200) {
|
|
|
|
for (unsigned i = 0; i < n; i++) {
|
|
|
|
digitalWrite(LED_BUILTIN, HIGH);
|
|
|
|
delay(delay_);
|
|
|
|
digitalWrite(LED_BUILTIN, LOW);
|
|
|
|
delay(delay_);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-06-14 19:22:11 +02:00
|
|
|
|
2023-06-24 02:59:22 +02:00
|
|
|
/* uint16_t MAX_DEVIATION = 0; */
|
|
|
|
/* void measurebaseline(unsigned nmeas, unsigned interval=50) { */
|
|
|
|
/* uint64_t value = 0; */
|
|
|
|
/* unsigned minval = 1023; */
|
|
|
|
/* unsigned maxval = 0; */
|
|
|
|
/* for (unsigned i = 0; i < nmeas; i++) { */
|
|
|
|
/* unsigned reading = analogread(pin_teng); */
|
|
|
|
/* value += reading; */
|
|
|
|
/* delay(interval); */
|
|
|
|
/* if (reading > maxval) { maxval = reading; } */
|
|
|
|
/* if (reading < minval) { minval = reading; } */
|
|
|
|
/* } */
|
|
|
|
/* BASELINE = value / nMeas; */
|
|
|
|
/* if (BASELINE - minVal > maxVal - BASELINE) { */
|
|
|
|
/* MAX_DEVIATION = BASELINE - minVal; */
|
|
|
|
/* } */
|
|
|
|
/* else { */
|
|
|
|
/* MAX_DEVIATION = maxVal - BASELINE; */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
2023-06-13 19:59:34 +02:00
|
|
|
|
|
|
|
|
2023-06-14 19:22:11 +02:00
|
|
|
void setup() {
|
|
|
|
setStatus(DeviceStatus::BUSY);
|
2023-06-13 19:59:34 +02:00
|
|
|
Serial.begin(9600);
|
|
|
|
/* // wait until available */
|
2023-06-14 19:22:11 +02:00
|
|
|
/* while (!Serial); */
|
|
|
|
|
|
|
|
blinkLED(2);
|
|
|
|
|
2023-06-13 19:59:34 +02:00
|
|
|
if (!BLE.begin()) {
|
|
|
|
Serial.println("starting Bluetooth® Low Energy module failed!");
|
2023-06-14 19:22:11 +02:00
|
|
|
setStatus(DeviceStatus::ERROR);
|
|
|
|
while(true);
|
2023-06-13 19:59:34 +02:00
|
|
|
}
|
2023-06-14 19:22:11 +02:00
|
|
|
/* BLE.setDeviceName("ArduinoTENG"); */
|
|
|
|
BLE.setLocalName("ArduinoTENG");
|
|
|
|
|
|
|
|
byte data[10] = "\xFF\xFFMQU@TUM"; // 0xFFFF manufacturer id for testing
|
|
|
|
BLE.setManufacturerData(data, 10);
|
|
|
|
|
2023-06-16 17:54:06 +02:00
|
|
|
initServices();
|
2023-06-14 19:22:11 +02:00
|
|
|
BLE.addService(tengService);
|
|
|
|
BLE.setAdvertisedService(tengService);
|
|
|
|
|
2023-06-24 02:59:22 +02:00
|
|
|
// defaults
|
|
|
|
tengCount.writeValue(100);
|
|
|
|
tengInterval.writeValue(100);
|
|
|
|
|
2023-06-14 19:22:11 +02:00
|
|
|
BLE.setConnectable(true);
|
|
|
|
blinkLED(3);
|
2023-06-13 19:59:34 +02:00
|
|
|
BLE.advertise();
|
|
|
|
|
2023-06-14 19:22:11 +02:00
|
|
|
setStatus(DeviceStatus::WAIT_CONNECT);
|
2023-06-13 19:59:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-06-24 02:59:22 +02:00
|
|
|
|
2023-06-13 19:59:34 +02:00
|
|
|
/* constexpr int max_val = 1023 / 5 * 3.5; // 1023 max val for 5V */
|
2023-06-24 02:59:22 +02:00
|
|
|
// it seems this function must return immediately, otherwise the connection will time out
|
|
|
|
void commandWrittenHandler(BLEDevice central, BLECharacteristic characteristic) {
|
|
|
|
switch (tengCommand.value()) {
|
|
|
|
case Command::STOP:
|
|
|
|
measurementTask = STOP_MEASURE;
|
|
|
|
break;
|
|
|
|
case Command::MEASURE:
|
|
|
|
if (measurementTask == STOP_MEASURE) {
|
|
|
|
measurementTask = START_MEASURE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Serial.println("ERROR: Command 'MEASURE' received while measurement is active");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Command::MEASURE_COUNT:
|
|
|
|
if (measurementTask == STOP_MEASURE) {
|
|
|
|
measurementTask = START_MEASURE_COUNT;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Serial.println("ERROR: Command 'MEASURE_COUNT' received while measurement is active");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
/* case Command::MEASURE_BASELINE: */
|
|
|
|
/* setStatus(DeviceStatus::MEASURING_BASELINE); */
|
|
|
|
/* measureBaseline(100); */
|
|
|
|
/* break; */
|
|
|
|
default:
|
|
|
|
setStatus(DeviceStatus::ERROR);
|
|
|
|
Serial.print("ERROR: Unkown command: ");
|
|
|
|
Serial.println(tengCommand.value(), HEX);
|
|
|
|
delay(1000);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-06-13 19:59:34 +02:00
|
|
|
|
|
|
|
// the loop function runs over and over again forever
|
|
|
|
void loop() {
|
2023-06-24 02:59:22 +02:00
|
|
|
blinkLED(3, 300);
|
2023-06-14 19:22:11 +02:00
|
|
|
// listen for Bluetooth® Low Energy peripherals to connect:
|
|
|
|
BLEDevice central = BLE.central();
|
|
|
|
|
|
|
|
// if a central is connected to peripheral:
|
|
|
|
if (central) {
|
2023-06-24 02:59:22 +02:00
|
|
|
setStatus(DeviceStatus::CONNECTED);
|
|
|
|
tengCommand.setEventHandler(BLEWritten, commandWrittenHandler);
|
|
|
|
|
2023-06-14 19:22:11 +02:00
|
|
|
Serial.print("Connected to central: ");
|
|
|
|
Serial.println(central.address());
|
|
|
|
|
|
|
|
while (central.connected()) {
|
2023-06-24 02:59:22 +02:00
|
|
|
blinkLED(1, 200);
|
|
|
|
if (measurementTask == START_MEASURE) {
|
|
|
|
measure(central, false);
|
|
|
|
}
|
|
|
|
else if (measurementTask == START_MEASURE_COUNT) {
|
|
|
|
measure(central, true);
|
2023-06-14 19:22:11 +02:00
|
|
|
}
|
2023-06-24 02:59:22 +02:00
|
|
|
|
2023-06-14 19:22:11 +02:00
|
|
|
}
|
2023-06-24 02:59:22 +02:00
|
|
|
|
2023-06-14 19:22:11 +02:00
|
|
|
setStatus(DeviceStatus::WAIT_CONNECT);
|
|
|
|
// when the central disconnects, notify the user
|
|
|
|
Serial.print("Disconnected from central MAC: ");
|
|
|
|
Serial.println(central.address());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BLE.advertise();
|
|
|
|
}
|
2023-06-13 19:59:34 +02:00
|
|
|
}
|