diff options
author | Jonas Smedegaard <dr@jones.dk> | 2025-04-15 12:02:50 +0200 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2025-04-15 12:04:34 +0200 |
commit | 818722baf294c9f7d1b9422bf1f2a3066cb2c9cf (patch) | |
tree | f2a8436eddb38a8b78914bb5e6ff7057bc96ddf6 /sensor/sensor.ino | |
parent | 2b55b35b3be6b42400359f6e816705efc530508a (diff) |
add sensor as non-library sketch
Diffstat (limited to 'sensor/sensor.ino')
-rw-r--r-- | sensor/sensor.ino | 186 |
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); +} |