From d6a944ecce92f1b5bdd54aaf3ed57808c3286ce0 Mon Sep 17 00:00:00 2001 From: Jonas Smedegaard Date: Wed, 16 Apr 2025 10:55:42 +0200 Subject: add vote as non-library sketch --- vote/vote.ino | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 vote/vote.ino (limited to 'vote/vote.ino') diff --git a/vote/vote.ino b/vote/vote.ino new file mode 100644 index 0000000..44fd179 --- /dev/null +++ b/vote/vote.ino @@ -0,0 +1,173 @@ +// SPDX-FileCopyrightText: 2025 Amal Mazrah +// SPDX-FileCopyrightText: 2025 Jonas Smedegaard +// SPDX-FileCopyrightText: 2025 Mennatullah Hatim Kassim +// SPDX-FileCopyrightText: 2025 Noor Ahmad +// SPDX-FileCopyrightText: 2025 Tanishka Suwalka +// SPDX-License-Identifier: GPL-3.0-or-later + +/// Mussel vote - an Arduino sketch to monitor mussel biosensors +/// +/// @version 0.0.3 +/// @see +/// @see + +// arduino-esp32 Logging system +// activate in Arduino IDE: Tools -> Core Debug Level +// special: set Core Debug Level to Error for plot-friendly output +#define CONFIG_ARDUHAL_ESP_LOG 1 +#define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL +#include +#undef ARDUHAL_LOG_FORMAT +#define ARDUHAL_LOG_FORMAT(letter, format) \ + ARDUHAL_LOG_COLOR_##letter "[" #letter "] %s(): " format \ + ARDUHAL_LOG_RESET_COLOR "\r\n", __FUNCTION__ + +// arduino-esp32 Bluetooth Low Energy (BLE) networking stack +#include +#include +#include +#include +#include + +#define MUSSEL_VOTE_TIME_AHEAD 60000U // 1 minute +#define MUSSEL_VOTE_TIME_BEHIND 120000U // 2 minutes + +// Limited size NOW!! can be transformed into infinite array +#define STACK_SIZE 1000 + +struct Vote { + String id; + unsigned long timestamp; + int measure; +}; + +void begin(); +String desc(); +int read(); +String debug(); +bool push(String id, unsigned long timestamp, int measure); +void printStack(); +bool qualifyVote(Vote vote, unsigned long currentTime); + +int _attitude; +int _pin; +bool _boolState; +byte _count; +unsigned long _time; + +// Array to store ID strings +String idStack[STACK_SIZE]; +unsigned long timeStack[STACK_SIZE]; +int measureStack[STACK_SIZE]; + +// Index of the top element in the stack, -1 means stack is empty +int top = -1; + +int scanTime = 1; //In seconds + +// pointer to control Bluetooth networking +BLEScan *pBLEScan; + +// Bluetooth beacon discovery callbacks +class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { + + // decode name and temperature from Eddystone TLM advertisement + void onResult(BLEAdvertisedDevice advertisedDevice) { + if (advertisedDevice.haveName() + && advertisedDevice.getFrameType() == BLE_EDDYSTONE_TLM_FRAME + ) { + BLEEddystoneTLM EddystoneTLM(&advertisedDevice); + push( + advertisedDevice.getName(), + millis(), + EddystoneTLM.getTemp() + ); + } + } +}; + +/// Function to push data onto the stack +bool push(String id, unsigned long timestamp, int measure) { + + // Check if stack is full + if (top >= STACK_SIZE - 1) { + Serial.println("Stack Full"); + + // Return false if stack is full + return false; + } + top++; + idStack[top] = id; + timeStack[top] = timestamp; + measureStack[top] = measure; + + // Return true on successful push + return true; +} + +/// Function to print stack contents +void printStack() { + for (int i = top; i >= 0; i--) { + Serial.print("ID: "); Serial.print(idStack[i]); + Serial.print(", Time: "); Serial.print(timeStack[i]); + Serial.print(", measure: "); Serial.println(measureStack[i]); + } +} + +bool qualifyVote(Vote vote, unsigned long currentTime) { + + // If the measure is 42 (YES), check timestamp validity + if (vote.measure == 42) { + // If the vote's timestamp is within 1 minute, count it as YES + if (currentTime - vote.timestamp <= MUSSEL_VOTE_TIME_AHEAD) { + return true; + } + // If the vote's timestamp is older than 2 minutes, count it as NO + else if (currentTime - vote.timestamp > MUSSEL_VOTE_TIME_BEHIND) { + return false; + } + } + + // If the measure is 2, always count the vote as NO + if (vote.measure == 2) { + return false; + } + + // Default case: vote is invalid if no conditions are met + return false; +} + +/// Dump internal variables, formatted for use with Serial Plotter +/// +/// @return internal variables as String +String debug() { + return static_cast( + "pin:") + _pin + + "\tboolState:" + _boolState + + "\ttime:" + _time + + "\tcount:" + _count; +} + +void setup() { + // enable logging to serial + Serial.begin(115200); + esp_log_level_set("*", ESP_LOG_DEBUG); + + // setup Bluetooth + BLEDevice::init(""); + pBLEScan = BLEDevice::getScan(); + pBLEScan->setAdvertisedDeviceCallbacks( + new MyAdvertisedDeviceCallbacks()); + pBLEScan->setActiveScan(true); + pBLEScan->setInterval(100); + pBLEScan->setWindow(99); +} + +void loop() { + BLEScanResults *foundDevices = pBLEScan->start(scanTime, false); + pBLEScan->clearResults(); + + printStack(); + + delay(500); +} -- cgit v1.2.3