aboutsummaryrefslogtreecommitdiff
path: root/Mussel/Mussel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Mussel/Mussel.cpp')
-rw-r--r--Mussel/Mussel.cpp290
1 files changed, 0 insertions, 290 deletions
diff --git a/Mussel/Mussel.cpp b/Mussel/Mussel.cpp
deleted file mode 100644
index a05f329..0000000
--- a/Mussel/Mussel.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-// 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
-
-/// Mussel - a small library for Arduino to emulate a mussel biosensor
-///
-/// * 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.2
-/// @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 "Mussel.h"
-#include "Arduino.h"
-
-/// Main constructor
-///
-/// @param attitude behavioral profile as integer
-Mussel::Mussel(int attitude) {
- _attitude = attitude;
-}
-
-/// Constructor for attitudes using an input pin
-///
-/// @param attitude behavioral profile as integer
-/// @param pin Used pin as uint8_t
-Mussel::Mussel(int attitude, uint8_t pin) {
- _attitude = attitude;
- _pin = pin;
-}
-
-/// Constructor for attitudes using an input pin and a sensor type
-///
-/// @param attitude behavioral profile as integer
-/// @param pin Used pin as uint8_t
-/// @param type type of sensor as uint8_t
-Mussel::Mussel(int attitude, uint8_t pin, uint8_t type)
-#ifdef DHT_H
- : mussel_dht(pin, type)
-#endif
-{
- _attitude = attitude;
- _pin = pin;
-}
-
-/// Setup function
-void Mussel::begin() {
- switch(_attitude) {
- case 1:
- _boolState = HIGH;
-
- // reset timer
- _time = millis();
-
- // use INPUT_PULLDOWN to signal when the button is held down
- // (not PULLUP which signals when it is released)
- pinMode(_pin, INPUT_PULLDOWN);
- break;
-#ifdef DHT_H
- case 3:
- mussel_dht.begin();
- break;
-#endif
- case 4:
- // use INPUT_PULLDOWN to signal when the button is held down
- // (not PULLUP which signals when it is released)
- pinMode(_pin, INPUT_PULLDOWN);
- break;
- case 5:
- _boolState = HIGH;
- _count = 0;
- _time = 0;
-
- // Enable internal pull-up resistor for button
- pinMode(_pin, INPUT_PULLUP);
- break;
- case 6:
- _boolState = HIGH;
- break;
- }
-}
-
-/// Description of mussel
-///
-/// @return name and attitude of mussel as String
-String Mussel::desc() {
- String _str;
-
- switch(_attitude) {
- case 1:
- _str = "closed 10 seconds every 50 seconds and on button push";
- break;
- case 2:
- _str = "closed 4 seconds every 8 seconds";
- break;
- case 3:
- _str = "closed when cold";
- break;
- case 4:
- _str = "closed when button is pushed";
- break;
- case 5:
- _str = "changes state when button is pushed";
- break;
- case 6:
- _str = "changes state on ON/OFF command";
- break;
- case 10:
- _str = "handles voting";
- break;
- default:
- _str = "undefined [" + static_cast<String>(_attitude) + "]";
- break;
- }
-
- return _str;
-}
-
-/// Sensor reading
-///
-/// * Values 0-99 is a measured relative mussel gape size
-/// * Values 100-254 are reserved for future use
-/// * Value 255 is an internal error
-///
-/// @return relative gape size as value 0-255 encoded as int
-int Mussel::read() {
- int _read;
-
- switch(_attitude) {
- case 1:
- if (digitalRead(_pin)
- // TODO: account for rollover
- or (millis() - _time) > MUSSEL_NORMAL_PACE * 1000
- ) {
- _read = 2;
- _boolState = HIGH;
-
- // reset timer
- _time = millis();
- } else if (_boolState == HIGH
- and (millis() - _time) > MUSSEL_STRESS_PACE * 1000
- ) {
- _read = 42;
- _boolState = LOW;
-
- // reset timer
- _time = millis();
- }
- break;
- case 2:
- // 42 if current second modulo 12 is below 9, else 2
- _read = (static_cast<unsigned long>(millis() / 1000) % 12) < 9
- ? 42
- : 2;
- break;
- case 3:
-#ifdef DHT_H
- // temperature in Celsius
- _read = mussel_dht.readTemperature();
-#else
- _read = 255;
-#endif
- break;
- case 4:
- // 2 if button is pressed, else 42
- _read = digitalRead(_pin) == HIGH
- ? 2
- : 42;
- break;
- case 5: {
- bool _reading = digitalRead(_pin); // Read button state
-
- // Debounce logic:
- // Ensures a single press isn't detected multiple times
- if (_reading != _boolState) {
- _time = millis(); // Reset debounce timer
- }
-
- if ((millis() - _time) > MUSSEL_DEBOUNCE_DELAY) {
- // Check for button press (transition from HIGH to LOW)
- if (_reading == LOW && _boolState == HIGH) {
- _count++; // Increment click count
- if (_count > 3) {
- _count = 0; // Reset cycle after 3 clicks
- }
- switch (_count) {
- case 1: _read = 2; break; // State: Angry
- case 2: _read = 42; break; // State: Happy
- case 3: _read = 15; break; // State: Unsure
- case 0: _read = 99; break; // State: Off
- }
- }
- }
-
- _boolState = _reading; // Update button state
- break;
- }
- case 6:
- if (Serial.available() > 0) {
- String command = Serial.readStringUntil('\n');
- command.trim();
-
- if (command.equalsIgnoreCase("ON")) {
- _boolState = HIGH;
- }
- else if (command.equalsIgnoreCase("OFF")) {
- _boolState = LOW;
- }
- }
- _read = _boolState == HIGH
- ? 42
- : 2;
- break;
- default:
- _read = 255;
- break;
- }
-
- return _read;
-}
-
-/// Function to push data onto the stack
-bool Mussel::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 Mussel::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 Mussel::debug() {
- return static_cast<String>(
- "pin:") + _pin
- + "\tboolState:" + _boolState
- + "\ttime:" + _time
- + "\tcount:" + _count;
-}