diff options
author | Jonas Smedegaard <dr@jones.dk> | 2025-04-18 01:24:05 +0200 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2025-04-18 01:24:05 +0200 |
commit | 6ca4ff06867aa5d7354615c828bd83234d827ff2 (patch) | |
tree | 6a42f307f09e05491f8e1eb9bf157e13916dad8d /Mussel/Mussel.cpp | |
parent | ea3988c911b467cbabe38cb9c3e6d0013b53965d (diff) |
rop Mussel library; move Arduino sketches below Arduino/
Diffstat (limited to 'Mussel/Mussel.cpp')
-rw-r--r-- | Mussel/Mussel.cpp | 290 |
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; -} |