diff options
author | Jonas Smedegaard <dr@jones.dk> | 2025-03-11 12:02:07 +0100 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2025-03-11 16:48:06 +0100 |
commit | 02876f961fc8b68f2cb43a23a1d98d89fce11858 (patch) | |
tree | d12658d92f62c4fd957fb68e683d75b8f378428f /Mussel | |
parent | 8d0212da635222b404113ad0ff5d469adf00ab6f (diff) |
add library Mussel
Diffstat (limited to 'Mussel')
-rw-r--r-- | Mussel/Mussel.cpp | 205 | ||||
-rw-r--r-- | Mussel/Mussel.h | 42 | ||||
-rw-r--r-- | Mussel/README.md | 36 | ||||
-rw-r--r-- | Mussel/examples/button/button.ino | 20 | ||||
-rw-r--r-- | Mussel/examples/button_states/button_states.ino | 20 | ||||
-rw-r--r-- | Mussel/examples/command/command.ino | 19 | ||||
-rw-r--r-- | Mussel/examples/minute/minute.ino | 19 | ||||
-rw-r--r-- | Mussel/examples/seconds/seconds.ino | 19 | ||||
-rw-r--r-- | Mussel/examples/temperature/temperature.ino | 21 | ||||
-rw-r--r-- | Mussel/keywords.txt | 17 |
10 files changed, 418 insertions, 0 deletions
diff --git a/Mussel/Mussel.cpp b/Mussel/Mussel.cpp new file mode 100644 index 0000000..3e13316 --- /dev/null +++ b/Mussel/Mussel.cpp @@ -0,0 +1,205 @@ +/// Mussel - a small library for Arduino to emulate a mussel biosensor +/// +/// 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 + +#include "Mussel.h" +#include "Arduino.h" + +/// Main constructor +/// +/// @param attitude behavioral profile as integer +Mussel::Mussel(int attitude) { + _attitude = attitude; +} + +/// Constructor for attitudes using a 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 a pin and certain type of sensor +/// +/// @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) { +#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"; + 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; + 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 byte +byte Mussel::read() { + byte _byte; + + switch(_attitude) { + case 1: + // 42 if current second modulo 60 is below 50, else 2 + _byte = static_cast<byte>( + (static_cast<unsigned long>(millis() / 1000) % 60) < 50 + ? 42 + : 2); + break; + case 2: + // 42 if current second modulo 12 is below 9, else 2 + _byte = static_cast<byte>( + (static_cast<unsigned long>(millis() / 1000) % 12) < 9 + ? 42 + : 2); + break; + case 3: +#ifdef DHT_H + // temperature in Celsius + _byte = static_cast<byte>( + mussel_dht.readTemperature()); +#else + _byte = 255; +#endif + break; + case 4: + // 2 if button is pressed, else 42 + _byte = static_cast<byte>( + 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: _byte = 2; break; // State: Angry + case 2: _byte = 42; break; // State: Happy + case 3: _byte = 15; break; // State: Unsure + case 0: _byte = 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; + } + } + _byte = _boolState == HIGH + ? 42 + : 2; + break; + default: + _byte = 255; + break; + } + + return _byte; +} + +/// 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; +} diff --git a/Mussel/Mussel.h b/Mussel/Mussel.h new file mode 100644 index 0000000..5d85068 --- /dev/null +++ b/Mussel/Mussel.h @@ -0,0 +1,42 @@ +/// Mussel - a small library for Arduino to emulate a mussel biosensor +/// +/// SPDX-License-Identifier: GPL-3.0-or-later +/// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk> + +#ifndef Mussel_h +#define Mussel_h +#include "Arduino.h" + +#define MUSSEL_DEBOUNCE_DELAY 50U + +class Mussel { + public: + + // Default constructor + Mussel(const int attitude); + + // Constructor for attitudes using a pin + Mussel(const int attitude, const uint8_t pin); + + // Constructor for attitudes using a pin and certain type of sensor + Mussel( + const int attitude, + const uint8_t pin, + const uint8_t type); + + void begin(); + String desc(); + byte read(); + String debug(); + private: + int _attitude; + int _pin; + bool _boolState; + byte _count; + unsigned long _time; +#ifdef DHT_H + DHT mussel_dht; +#endif +}; + +#endif diff --git a/Mussel/README.md b/Mussel/README.md new file mode 100644 index 0000000..4420e2a --- /dev/null +++ b/Mussel/README.md @@ -0,0 +1,36 @@ +# Mussel + +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 is a tiny library to emulate a mussel biosensor. + +## Motivation + +For exploration of various biosensor behaviours, +hooking into various networking setups with various looping constructs, +maintaining the behaviours as a library seemed convenient. + +## Features + +* Super simple API +* Offers multiple behaviours. + +## Requirements + +* An Arduino — http://arduino.cc/ + +## Installation + +Download the ZIP archive from +<https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z2tFBF4gN7ziG9oXtUytVQNYe3VhQ>, +then open the Arduino IDE +and choose Sketch > Include Library > Add .ZIP Library... +and select your downloaded file. + +You should now see in File > Examples > Mussel +an entry for the `basic_usage` example. diff --git a/Mussel/examples/button/button.ino b/Mussel/examples/button/button.ino new file mode 100644 index 0000000..5efae46 --- /dev/null +++ b/Mussel/examples/button/button.ino @@ -0,0 +1,20 @@ +#include <Mussel.h> + +// instantiate with attitude #4, +// and pin 4 connected to a button +Mussel mussel(4, 4); + +void setup() { + Serial.begin(115200); + mussel.begin(); + + Serial.printf("\n\nDevice ready: %s\n", + mussel.desc().c_str()); +} + +void loop() { + Serial.printf("gap:%d\n", + mussel.read()); + + delay(1000); +} diff --git a/Mussel/examples/button_states/button_states.ino b/Mussel/examples/button_states/button_states.ino new file mode 100644 index 0000000..1d91b41 --- /dev/null +++ b/Mussel/examples/button_states/button_states.ino @@ -0,0 +1,20 @@ +#include <Mussel.h> + +// instantiate with attitude #5, +// and pin 9 connected to a button +Mussel mussel(5, 9); + +void setup() { + Serial.begin(115200); + mussel.begin(); + + Serial.printf("\n\nDevice ready: %s\n", + mussel.desc().c_str()); +} + +void loop() { + Serial.printf("gap:%d\n", + mussel.read()); + + delay(1000); +} diff --git a/Mussel/examples/command/command.ino b/Mussel/examples/command/command.ino new file mode 100644 index 0000000..f359e00 --- /dev/null +++ b/Mussel/examples/command/command.ino @@ -0,0 +1,19 @@ +#include <Mussel.h> + +// instantiate with attitude #6 +Mussel mussel(6); + +void setup() { + Serial.begin(115200); + mussel.begin(); + + Serial.printf("\n\nDevice ready: %s\n", + mussel.desc().c_str()); +} + +void loop() { + Serial.printf("gap:%d\n", + mussel.read()); + + delay(1000); +} diff --git a/Mussel/examples/minute/minute.ino b/Mussel/examples/minute/minute.ino new file mode 100644 index 0000000..928537c --- /dev/null +++ b/Mussel/examples/minute/minute.ino @@ -0,0 +1,19 @@ +#include <Mussel.h> + +// instantiate with attitude #2 +Mussel mussel(2); + +void setup() { + Serial.begin(115200); + mussel.begin(); + + Serial.printf("\n\nDevice ready: %s\n", + mussel.desc().c_str()); +} + +void loop() { + Serial.printf("gap:%d\n", + mussel.read()); + + delay(1000); +} diff --git a/Mussel/examples/seconds/seconds.ino b/Mussel/examples/seconds/seconds.ino new file mode 100644 index 0000000..928537c --- /dev/null +++ b/Mussel/examples/seconds/seconds.ino @@ -0,0 +1,19 @@ +#include <Mussel.h> + +// instantiate with attitude #2 +Mussel mussel(2); + +void setup() { + Serial.begin(115200); + mussel.begin(); + + Serial.printf("\n\nDevice ready: %s\n", + mussel.desc().c_str()); +} + +void loop() { + Serial.printf("gap:%d\n", + mussel.read()); + + delay(1000); +} diff --git a/Mussel/examples/temperature/temperature.ino b/Mussel/examples/temperature/temperature.ino new file mode 100644 index 0000000..6b4ca08 --- /dev/null +++ b/Mussel/examples/temperature/temperature.ino @@ -0,0 +1,21 @@ +#include <DHT.h> +#include <Mussel.h> + +// instantiate with attitude #3, +// and PIN 15 connected to an external sensor of type DHT11 +Mussel mussel(3, 15, DHT11); + +void setup() { + Serial.begin(115200); + mussel.begin(); + + Serial.printf("\n\nDevice ready: %s\n", + mussel.desc().c_str()); +} + +void loop() { + Serial.printf("gap:%d\n", + mussel.read()); + + delay(1000); +} diff --git a/Mussel/keywords.txt b/Mussel/keywords.txt new file mode 100644 index 0000000..4f3eaf1 --- /dev/null +++ b/Mussel/keywords.txt @@ -0,0 +1,17 @@ +####################################### +# Syntax Coloring Map for Mussel library +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Mussel KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +read KEYWORD2 +begin KEYWORD2 +desc KEYWORD2 |