aboutsummaryrefslogtreecommitdiff
path: root/vote/vote.ino
blob: 6cfca1123ad7db8eb424f34b1f3bcc92cc82e9c4 (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. // Validity timing thresholds
  29. const unsigned long VOTE_TIME_AHEAD = 1 * 60 * 1000; // 1 minute
  30. const unsigned long VOTE_TIME_BEHIND = 2 * 60 * 1000; // 2 minutes
  31. // Limited size NOW!! can be transformed into infinite array
  32. #define STACK_SIZE 1000
  33. struct Vote {
  34. String id;
  35. unsigned long timestamp;
  36. int measure;
  37. };
  38. // Index of the top element in the stack, -1 means stack is empty
  39. int top = -1;
  40. int scanTime = 1; //In seconds
  41. // pointer to control Bluetooth networking
  42. BLEScan *pBLEScan;
  43. // Bluetooth beacon discovery callbacks
  44. class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
  45. // decode name and temperature from Eddystone TLM advertisement
  46. void onResult(BLEAdvertisedDevice advertisedDevice) {
  47. if (advertisedDevice.haveName()
  48. && advertisedDevice.getFrameType() == BLE_EDDYSTONE_TLM_FRAME
  49. ) {
  50. BLEEddystoneTLM EddystoneTLM(&advertisedDevice);
  51. // misuse error-only log level for plot-friendly output
  52. #if ARDUHAL_LOG_LEVEL == ARDUHAL_LOG_LEVEL_ERROR
  53. String id_mangled = advertisedDevice.getName();
  54. id_mangled.replace(' ', '_');
  55. id_mangled.replace(':', '=');
  56. Serial.println(id_mangled + ":" + EddystoneTLM.getTemp());
  57. #endif
  58. push(
  59. advertisedDevice.getName(),
  60. millis(),
  61. EddystoneTLM.getTemp()
  62. );
  63. }
  64. }
  65. };
  66. /// Function to push data onto the stack
  67. bool push(String id, unsigned long timestamp, int measure) {
  68. // Check if stack is full
  69. if (top >= STACK_SIZE - 1) {
  70. Serial.println("Stack Full");
  71. // Return false if stack is full
  72. return false;
  73. }
  74. top++;
  75. idStack[top] = id;
  76. timeStack[top] = timestamp;
  77. measureStack[top] = measure;
  78. // Return true on successful push
  79. return true;
  80. }
  81. bool qualifyVote(Vote vote, unsigned long currentTime) {
  82. // If the measure is 42 (YES), check timestamp validity
  83. if (vote.measure == 42) {
  84. // If the vote's timestamp is within 1 minute, count it as YES
  85. if (currentTime - vote.timestamp <= VOTE_TIME_AHEAD) {
  86. return true;
  87. }
  88. // If the vote's timestamp is older than 2 minutes, count it as NO
  89. else if (currentTime - vote.timestamp > VOTE_TIME_BEHIND) {
  90. return false;
  91. }
  92. }
  93. // If the measure is 2, always count the vote as NO
  94. if (vote.measure == 2) {
  95. return false;
  96. }
  97. // Default case: vote is invalid if no conditions are met
  98. return false;
  99. }
  100. void setup() {
  101. // enable logging to serial
  102. Serial.begin(115200);
  103. esp_log_level_set("*", ESP_LOG_DEBUG);
  104. // setup Bluetooth
  105. BLEDevice::init("");
  106. pBLEScan = BLEDevice::getScan();
  107. pBLEScan->setAdvertisedDeviceCallbacks(
  108. new MyAdvertisedDeviceCallbacks());
  109. pBLEScan->setActiveScan(true);
  110. pBLEScan->setInterval(100);
  111. pBLEScan->setWindow(99);
  112. }
  113. void loop() {
  114. BLEScanResults *foundDevices = pBLEScan->start(scanTime, false);
  115. pBLEScan->clearResults();
  116. delay(500);
  117. }