aboutsummaryrefslogtreecommitdiff
path: root/sensor/sensor.ino
diff options
context:
space:
mode:
Diffstat (limited to 'sensor/sensor.ino')
-rw-r--r--sensor/sensor.ino186
1 files changed, 186 insertions, 0 deletions
diff --git a/sensor/sensor.ino b/sensor/sensor.ino
new file mode 100644
index 0000000..a05d6cc
--- /dev/null
+++ b/sensor/sensor.ino
@@ -0,0 +1,186 @@
+// SPDX-FileCopyrightText: 2025 Amal Mazrah <mazrah@ruc.dk>
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-FileCopyrightText: 2025 Mennatullah Hatim Kassim <stud-mennatulla@ruc.dk>
+// SPDX-FileCopyrightText: 2025 Noor Ahmad <noora@ruc.dk>
+// SPDX-FileCopyrightText: 2025 Tanishka Suwalka <tanishkas@ruc.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+/// Sensor mussel - an Arduino sketch to emulate a mussel biosensor
+///
+/// * v0.0.3
+/// * rewrite sensor as sketch,
+/// using ESP32 LEDC, Touch sensor and Logging library
+///
+/// * v0.0.2
+/// * rewrite attitude #2 to also handle button press
+/// * add voting functions and example
+///
+/// * v0.0.1
+/// * initial release to radicle
+///
+/// @version 0.0.3
+/// @see <https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z2tFBF4gN7ziG9oXtUytVQNYe3VhQ/tree/Mussel/README.md>
+/// @see <https://moodle.ruc.dk/course/view.php?id=23504>
+
+#include "mylog.h"
+#include "BLEDevice.h"
+#include "BLEBeacon.h"
+#include "BLEAdvertising.h"
+#include "BLEEddystoneTLM.h"
+
+// Adjust these for production use
+//
+// * BEACON_UUID should be unique for each deployment
+// * INSTANCE_ID should be unique for each sensor
+//
+// @see https://www.uuidgenerator.net/
+#define BEACON_NAME "Dummy mussel sensor"
+#define BEACON_UUID "00000000-0000-0000-0000-000000000000"
+#define INSTANCE_ID "0xbeac0101"
+
+#define STRESS_MAX 50
+
+// touch sensor using ESP32 Touch sensor
+// https://docs.espressif.com/projects/arduino-esp32/en/latest/api/touch.html
+#define TOUCH_PIN T0 // T0 is GPIO4
+#define TOUCH_THRESHOLD 40
+
+// pacemaker using ESP32 LED PWM Controller (LEDC)
+// https://docs.espressif.com/projects/arduino-esp32/en/latest/api/ledc.html
+#define LED_PIN LED_BUILTIN
+#define LEDC_BITS 7
+#define LEDC_FREQ 500
+#define LEDC_START_DUTY 0
+#define LEDC_TARGET_DUTY 90
+#define LEDC_CALM_PACE 3000
+#define LEDC_STRESSED_PACE 400
+
+// Bluetooth beacon
+#define BEACON_POWER ESP_PWR_LVL_N12
+
+int stress = 0;
+
+bool touch_detected = false;
+
+int pace = LEDC_STRESSED_PACE;
+
+bool fade_ended = false;
+bool fade_in = true;
+
+BLEAdvertising *pAdvertising;
+
+// Touch sensor callback
+void gotTouch() {
+// keepPace();
+ touch_detected = true;
+ pace = LEDC_STRESSED_PACE;
+}
+
+// pacemaker Interrupt Service Routine (ISR)
+void ARDUINO_ISR_ATTR LED_FADE_ISR() {
+ fade_ended = true;
+ keepPace();
+}
+
+void beginTouchDetection() {
+ touchAttachInterrupt(TOUCH_PIN, gotTouch, TOUCH_THRESHOLD);
+ log_d("touch detected");
+}
+
+// pacemaker initialization
+void beginPace() {
+
+ // Setup pacemaker timer
+ ledcAttach(LED_PIN, LEDC_FREQ, LEDC_BITS);
+
+ // fade in once supervised and then begin fade out with ISR
+ ledcFade(LED_PIN, LEDC_START_DUTY, LEDC_TARGET_DUTY, pace);
+ delay(pace);
+ ledcFadeWithInterrupt(LED_PIN, LEDC_TARGET_DUTY, LEDC_START_DUTY,
+ pace, LED_FADE_ISR);
+}
+
+// pacemaker maintenance
+void keepPace() {
+
+// if (fade_ended || touch_detected) {
+ if (fade_ended) {
+ fade_ended = false;
+
+ // stress management
+ if (touch_detected) {
+ touch_detected = false;
+ log_i("Stressed by touch!");
+ if (stress < STRESS_MAX) {
+ stress = stress + 10;
+ }
+ } else if (stress > 0) {
+ stress--;
+ if (stress <= 0) {
+ pace = LEDC_CALM_PACE;
+ log_i("Calmed down...");
+ } else {
+ log_i("Still stressed...");
+ }
+ } else {
+ pace = LEDC_CALM_PACE;
+ }
+
+ // begin fade in opposite direction at decided pace
+ ledcFadeWithInterrupt(LED_PIN,
+ fade_in ? LEDC_START_DUTY : LEDC_TARGET_DUTY,
+ fade_in ? LEDC_TARGET_DUTY : LEDC_START_DUTY,
+ pace, LED_FADE_ISR);
+ fade_in = !fade_in;
+ }
+}
+
+// Sensor reading
+int getGapeAngle() {
+ return ledcRead(LED_PIN);
+}
+
+// Construct Bluetooth beacon
+void setBeacon() {
+ BLEEddystoneTLM EddystoneTLM;
+ EddystoneTLM.setTemp(getGapeAngle());
+ log_i("Gape angle: %.2f°", EddystoneTLM.getTemp());
+
+ BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
+ BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
+ oScanResponseData.setServiceData(BLEUUID(
+ (uint16_t)0xFEAA),
+ String(EddystoneTLM.getData().c_str(),
+ EddystoneTLM.getData().length()));
+
+ oAdvertisementData.setName(BEACON_NAME);
+ pAdvertising->setAdvertisementData(oAdvertisementData);
+ pAdvertising->setScanResponseData(oScanResponseData);
+}
+
+void setup() {
+
+ // enable logging (when also raised in IDE: Tools -> Core Debug Level)
+ Serial.begin(115200);
+ esp_log_level_set("*", ESP_LOG_DEBUG);
+
+ Serial.begin(115200);
+ beginPace();
+ beginTouchDetection();
+
+ // setup Bluetooth
+ if (BEACON_UUID == "00000000-0000-0000-0000-000000000000")
+ log_w("Please set a unique BEACON_UUID");
+ BLEDevice::init("TLMBeacon");
+ BLEDevice::setPower(BEACON_POWER);
+ pAdvertising = BLEDevice::getAdvertising();
+ setBeacon();
+ pAdvertising->start();
+}
+
+void loop() {
+// keepPace();
+// Serial.println(getGapeAngle());
+ setBeacon();
+ delay(500);
+}