aboutsummaryrefslogtreecommitdiff
path: root/vote/vote.ino
blob: 8036408fd1f262d5111fcd470b7b9b1f985785e0 (plain)
  1. // SPDX-FileCopyrightText: 2025 Amal Mazrah <mazrah@ruc.dk>
  2. // SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
  3. // SPDX-FileCopyrightText: 2025 Mennatullah Hatim Kassim <stud-mennatulla@ruc.dk>
  4. // SPDX-FileCopyrightText: 2025 Noor Ahmad <noora@ruc.dk>
  5. // SPDX-FileCopyrightText: 2025 Tanishka Suwalka <tanishkas@ruc.dk>
  6. // SPDX-License-Identifier: GPL-3.0-or-later
  7. /// Mussel vote - an Arduino sketch to monitor mussel biosensors
  8. ///
  9. /// @version 0.0.3
  10. /// @see <https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z2tFBF4gN7ziG9oXtUytVQNYe3VhQ>
  11. /// @see <https://moodle.ruc.dk/course/view.php?id=23504>
  12. // arduino-esp32 Logging system
  13. // activate in Arduino IDE: Tools -> Core Debug Level
  14. // special: set Core Debug Level to Error for plot-friendly output
  15. #define CONFIG_ARDUHAL_ESP_LOG 1
  16. #define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL
  17. #include <esp32-hal-log.h>
  18. #undef ARDUHAL_LOG_FORMAT
  19. #define ARDUHAL_LOG_FORMAT(letter, format) \
  20. ARDUHAL_LOG_COLOR_##letter "[" #letter "] %s(): " format \
  21. ARDUHAL_LOG_RESET_COLOR "\r\n", __FUNCTION__
  22. // arduino-esp32 Bluetooth Low Energy (BLE) networking stack
  23. #include <BLEDevice.h>
  24. #include <BLEScan.h>
  25. #include <BLEAdvertisedDevice.h>
  26. #include <BLEEddystoneTLM.h>
  27. #include <BLEBeacon.h>
  28. #define SCAN_INTERVAL 100
  29. #define SCAN_WINDOW 99
  30. #define SCAN_TIME_SEC 1
  31. // Validity timing thresholds
  32. const unsigned long VOTE_TIME_AHEAD = 1 * 60 * 1000; // 1 minute
  33. const unsigned long VOTE_TIME_BEHIND = 2 * 60 * 1000; // 2 minutes
  34. // Limited size NOW!! can be transformed into infinite array
  35. #define STACK_SIZE 1000
  36. struct Vote {
  37. String id;
  38. unsigned long timestamp;
  39. int measure;
  40. };
  41. // Index of the top element in the stack, -1 means stack is empty
  42. int top = -1;
  43. // pointer to control Bluetooth networking
  44. BLEScan *pBLEScan;
  45. // Bluetooth beacon discovery callbacks
  46. class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
  47. // decode name and temperature from Eddystone TLM advertisement
  48. void onResult(BLEAdvertisedDevice advertisedDevice) {
  49. if (advertisedDevice.haveName()
  50. && advertisedDevice.getFrameType() == BLE_EDDYSTONE_TLM_FRAME
  51. ) {
  52. BLEEddystoneTLM EddystoneTLM(&advertisedDevice);
  53. // misuse error-only log level for plot-friendly output
  54. #if ARDUHAL_LOG_LEVEL == ARDUHAL_LOG_LEVEL_ERROR
  55. String id_mangled = advertisedDevice.getName();
  56. id_mangled.replace(' ', '_');
  57. id_mangled.replace(':', '=');
  58. Serial.println(id_mangled + ":" + EddystoneTLM.getTemp());
  59. #endif
  60. push(
  61. advertisedDevice.getName(),
  62. millis(),
  63. EddystoneTLM.getTemp()
  64. );
  65. }
  66. }
  67. };
  68. /// Function to push data onto the stack
  69. bool push(String id, unsigned long timestamp, int measure) {
  70. // Check if stack is full
  71. if (top >= STACK_SIZE - 1) {
  72. Serial.println("Stack Full");
  73. // Return false if stack is full
  74. return false;
  75. }
  76. top++;
  77. idStack[top] = id;
  78. timeStack[top] = timestamp;
  79. measureStack[top] = measure;
  80. // Return true on successful push
  81. return true;
  82. }
  83. bool qualifyVote(Vote vote, unsigned long currentTime) {
  84. // If the measure is 42 (YES), check timestamp validity
  85. if (vote.measure == 42) {
  86. // If the vote's timestamp is within 1 minute, count it as YES
  87. if (currentTime - vote.timestamp <= VOTE_TIME_AHEAD) {
  88. return true;
  89. }
  90. // If the vote's timestamp is older than 2 minutes, count it as NO
  91. else if (currentTime - vote.timestamp > VOTE_TIME_BEHIND) {
  92. return false;
  93. }
  94. }
  95. // If the measure is 2, always count the vote as NO
  96. if (vote.measure == 2) {
  97. return false;
  98. }
  99. // Default case: vote is invalid if no conditions are met
  100. return false;
  101. }
  102. void setup() {
  103. // enable logging to serial
  104. Serial.begin(115200);
  105. esp_log_level_set("*", ESP_LOG_DEBUG);
  106. // setup Bluetooth
  107. BLEDevice::init("");
  108. pBLEScan = BLEDevice::getScan();
  109. pBLEScan->setAdvertisedDeviceCallbacks(
  110. new MyAdvertisedDeviceCallbacks());
  111. pBLEScan->setActiveScan(true);
  112. pBLEScan->setInterval(SCAN_INTERVAL);
  113. pBLEScan->setWindow(SCAN_WINDOW);
  114. }
  115. void loop() {
  116. pBLEScan->start(SCAN_TIME_SEC, false);
  117. pBLEScan->clearResults();
  118. delay(500);
  119. }