added count and interval settings

This commit is contained in:
matthias@arch 2023-06-24 02:59:22 +02:00
parent d70797bd92
commit 73ccb41dfb
3 changed files with 95 additions and 85 deletions

View File

@ -7,20 +7,26 @@ const char* BASE_UUID = "00000000-9a74-4b30-9361-4a16ec09930f";
// Service 1: TENG
const char* TENG_SUUID = "00010000-9a74-4b30-9361-4a16ec09930f"; // Service UUID
const char* TENG_STATUS_CUUID = "00010001-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID
const char* TENG_COMMAND_CUUID = "00010002-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID
const char* TENG_READING_CUUID = "00010003-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID
const char* TENG_BASELINE_CUUID = "00010004-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID
const char* TENG_COMMAND_CUUID = "00010002-9a74-4b30-9361-4a16ec09930f";
const char* TENG_READING_CUUID = "00010003-9a74-4b30-9361-4a16ec09930f";
const char* TENG_COUNT_CUUID = "00010004-9a74-4b30-9361-4a16ec09930f";
const char* TENG_INTERVAL_CUUID = "00010005-9a74-4b30-9361-4a16ec09930f";
/* const char* TENG_BASELINE_CUUID = "00010004-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID */
BLEService tengService(TENG_SUUID);
BLEByteCharacteristic tengStatus(TENG_STATUS_CUUID, BLERead | BLENotify);
BLEByteCharacteristic tengCommand(TENG_COMMAND_CUUID, BLEWrite);
BLEUnsignedShortCharacteristic tengReading(TENG_READING_CUUID, BLERead | BLENotify);
BLEUnsignedShortCharacteristic tengBaseline(TENG_BASELINE_CUUID, BLERead);
BLEUnsignedShortCharacteristic tengInterval(TENG_INTERVAL_CUUID, BLERead | BLEWrite);
BLEUnsignedShortCharacteristic tengCount(TENG_COUNT_CUUID, BLERead | BLEWrite);
/* BLEUnsignedShortCharacteristic tengBaseline(TENG_BASELINE_CUUID, BLERead); */
enum Command : byte { NOOP = 0, MEASURE_BASELINE };
enum Command : byte { STOP = 0, MEASURE_COUNT, MEASURE, };
void initServices() {
tengService.addCharacteristic(tengStatus);
tengService.addCharacteristic(tengCommand);
tengService.addCharacteristic(tengReading);
tengService.addCharacteristic(tengBaseline);
tengService.addCharacteristic(tengCount);
tengService.addCharacteristic(tengInterval);
/* tengService.addCharacteristic(tengBaseline); */
}

View File

@ -1,11 +1,12 @@
#pragma once
#include <Arduino.h>
#include "settings.hpp"
#include "services.hpp"
// needs to be in separate file because sketch preprocessor reorders stuff
enum DeviceStatus : byte { ERROR = 0, BUSY, WAIT_CONNECT, MEASURING_BASELINE, READING };
enum DeviceStatus : byte { ERROR = 0, BUSY, WAIT_CONNECT, CONNECTED, MEASURING };
void setStatusLED(DeviceStatus s, bool value) {
switch (s) {
@ -14,20 +15,25 @@ void setStatusLED(DeviceStatus s, bool value) {
break;
case BUSY:
digitalWrite(LED_YELLOW, value);
digitalWrite(LED_RED, value);
break;
case WAIT_CONNECT:
digitalWrite(LED_YELLOW, value);
break;
case CONNECTED:
digitalWrite(LED_GREEN, value);
break;
case MEASURING_BASELINE:
/* case MEASURING_BASELINE: */
/* digitalWrite(LED_RED, value); */
/* digitalWrite(LED_GREEN, value); */
/* break; */
case MEASURING:
digitalWrite(LED_YELLOW, value);
digitalWrite(LED_RED, value);
break;
case READING:
digitalWrite(LED_GREEN, value);
break;
}
}
DeviceStatus deviceStatus = WAIT_CONNECT;
void setStatus(DeviceStatus s) {
setStatusLED(deviceStatus, LOW);

View File

@ -8,6 +8,7 @@
#include "settings.hpp"
#include "status.hpp"
#include "services.hpp"
#include "measure.hpp"
// TODO
/* std::array<uint16_t, 10000> valueBuffer; // 20kB buffer for readings */
@ -26,27 +27,26 @@ void blinkLED(unsigned n=5, unsigned delay_=200) {
uint16_t MAX_DEVIATION = 0;
uint16_t BASELINE = 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;
}
}
/* 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; */
/* } */
/* } */
void setup() {
@ -72,6 +72,10 @@ void setup() {
BLE.addService(tengService);
BLE.setAdvertisedService(tengService);
// defaults
tengCount.writeValue(100);
tengInterval.writeValue(100);
BLE.setConnectable(true);
blinkLED(3);
BLE.advertise();
@ -81,47 +85,68 @@ void setup() {
/* constexpr int max_val = 1023 / 5 * 3.5; // 1023 max val for 5V */
// 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;
}
}
// the loop function runs over and over again forever
void loop() {
blinkLED(3, 100);
blinkLED(3, 300);
// listen for Bluetooth® Low Energy peripherals to connect:
BLEDevice central = BLE.central();
// if a central is connected to peripheral:
if (central) {
setStatus(DeviceStatus::READING);
setStatus(DeviceStatus::CONNECTED);
tengCommand.setEventHandler(BLEWritten, commandWrittenHandler);
Serial.print("Connected to central: ");
Serial.println(central.address());
while (central.connected()) {
if (tengCommand.written()) {
switch (tengCommand.value()) {
case Command::NOOP:
setStatus(DeviceStatus::BUSY);
delay(1000);
break;
case Command::MEASURE_BASELINE:
setStatus(DeviceStatus::MEASURING_BASELINE);
measureBaseline(100);
break;
default:
setStatus(DeviceStatus::ERROR);
delay(1000);
break;
}
setStatus(DeviceStatus::READING);
blinkLED(1, 200);
if (measurementTask == START_MEASURE) {
measure(central, false);
}
int val = analogRead(PIN_TENG);
tengReading.writeValue(static_cast<uint16_t>(val));
Serial.print(val, DEC);
val -= BASELINE;
if (val < 0) { val = -val; }
Serial.print("/");
Serial.println(val, DEC);
delay(300);
else if (measurementTask == START_MEASURE_COUNT) {
measure(central, true);
}
}
setStatus(DeviceStatus::WAIT_CONNECT);
// when the central disconnects, notify the user
Serial.print("Disconnected from central MAC: ");
@ -130,31 +155,4 @@ void loop() {
else {
BLE.advertise();
}
return;
int led_red = LOW;
int led_yellow = LOW;
int led_green = LOW;
int val = analogRead(PIN_TENG);
Serial.print(val, DEC);
val -= BASELINE;
if (val < 0) { val = -val; }
Serial.print("/");
Serial.println(val, DEC);
if (val >= MAX_DEVIATION * 1) {
led_green = HIGH;
}
if (val >= MAX_DEVIATION * 2) {
led_yellow = HIGH;
}
if (val >= MAX_DEVIATION * 3) {
led_red = HIGH;
}
digitalWrite(LED_RED, led_red);
digitalWrite(LED_YELLOW, led_yellow);
digitalWrite(LED_GREEN, led_green);
delay(100);
}