diff --git a/libraries/Multiplex/.github/workflows/arduino_test_runner.yml b/libraries/Multiplex/.github/workflows/arduino_test_runner.yml index 476456bb..096b975b 100644 --- a/libraries/Multiplex/.github/workflows/arduino_test_runner.yml +++ b/libraries/Multiplex/.github/workflows/arduino_test_runner.yml @@ -4,10 +4,14 @@ name: Arduino CI on: [push, pull_request] jobs: - arduino_ci: + runTest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: Arduino-CI/action@master - # Arduino-CI/action@v0.1.1 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/libraries/Multiplex/Multiplex.cpp b/libraries/Multiplex/Multiplex.cpp index 27d9b9dc..65181374 100644 --- a/libraries/Multiplex/Multiplex.cpp +++ b/libraries/Multiplex/Multiplex.cpp @@ -1,7 +1,7 @@ // // FILE: Multiplex.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.2.0 +// VERSION: 0.2.1 // PURPOSE: Arduino library to multiplex streams // DATE: 2021-01-09 // URL: https://github.com/RobTillaart/Multiplex @@ -9,6 +9,10 @@ // HISTORY: // 0.1.0 2021-01-09 initial version // 0.2.0 2021-08-09 See issues #2 and #3 +// 0.2.1 2021-09-12 made index(Stream) public; added stream(index) +// enable() / disable() return true on success +// added free() function +// minor refactor. #include "Multiplex.h" @@ -16,22 +20,33 @@ Multiplex::Multiplex() { + // malloc ? + _size = MAX_MULTIPLEX; reset(); } +Multiplex::~Multiplex() +{ + // free ? +} + + void Multiplex::reset() { - _size = MAX_MULTIPLEX; - for (int i = 0; i < _size; i++) _enabled[i] = false; + for (uint8_t i = 0; i < _size; i++) + { + _enabled[i] = false; + } _count = 0; } bool Multiplex::add(Print * stream) { - if (index(stream) != 0xFF) return false; if (_count >= _size) return false; + if (index(stream) != 0xFF) return false; + _enabled[_count] = true; _stream[_count++] = stream; return true; @@ -44,7 +59,7 @@ bool Multiplex::add(Print * stream) // size_t Multiplex::write(uint8_t c) { - uint8_t n = 0; + size_t n = 0; for (uint8_t i = 0; i < _count; i++) { if (_enabled[i]) @@ -55,8 +70,10 @@ size_t Multiplex::write(uint8_t c) return n; } -size_t Multiplex::write(const uint8_t *buffer, size_t size) { - uint8_t n = 0; + +size_t Multiplex::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; for (uint8_t i = 0; i < _count; i++) { if (_enabled[i]) @@ -67,11 +84,10 @@ size_t Multiplex::write(const uint8_t *buffer, size_t size) { return n; } -// private + uint8_t Multiplex::index(Print *stream) { - uint8_t i = 0; - for (; i < _count; i++) + for (uint8_t i = 0; i < _count; i++) { if (stream == _stream[i]) { @@ -81,35 +97,53 @@ uint8_t Multiplex::index(Print *stream) return 0xFF; } -void Multiplex::enable(uint8_t n) + +Print * Multiplex::stream(uint8_t n) { - if (n < _count && n != 0xFF) _enabled[n] = true; + if (n >= _count) return NULL; + return _stream[n]; } -void Multiplex::enableStream(Print *stream) + +bool Multiplex::enable(uint8_t n) +{ + if (n >= _count) return false; + _enabled[n] = true; + return true; +} + + +bool Multiplex::enableStream(Print *stream) { return enable(index(stream)); } -void Multiplex::disable(uint8_t n) + +bool Multiplex::disable(uint8_t n) { - if (n != 0xFF && n < _count) _enabled[n] = false; + if (n >= _count) return false; + _enabled[n] = false; + return true; } -void Multiplex::disableStream(Print *stream) + +bool Multiplex::disableStream(Print *stream) { return disable(index(stream)); } + bool Multiplex::isEnabled(uint8_t n) { - if (n != 0xFF && n >= _count) return false; + if (n >= _count) return false; return _enabled[n]; } + bool Multiplex::isEnabledStream(Print *stream) { return isEnabled(index(stream)); } + // -- END OF FILE -- diff --git a/libraries/Multiplex/Multiplex.h b/libraries/Multiplex/Multiplex.h index 66503e6e..ae2a3a8b 100644 --- a/libraries/Multiplex/Multiplex.h +++ b/libraries/Multiplex/Multiplex.h @@ -2,7 +2,7 @@ // // FILE: Multiplex.h // AUTHOR: Rob Tillaart -// VERSION: 0.2.0 +// VERSION: 0.2.1 // PURPOSE: Arduino library to multiplex streams // DATE: 2021-01-09 // URL: https://github.com/RobTillaart/Multiplex @@ -12,39 +12,52 @@ //#include "Print.h" -#define MULTIPLEX_LIB_VERSION (F("0.2.0")) +#define MULTIPLEX_LIB_VERSION (F("0.2.1")) -const uint8_t MAX_MULTIPLEX = 4; +#ifndef MAX_MULTIPLEX +#define MAX_MULTIPLEX 4 // MAX 254 as 0xFF is a special value. +#endif class Multiplex: public Print { public: Multiplex(); - + ~Multiplex(); + + // CORE - virtual size_t write(uint8_t c) override; + virtual size_t write(uint8_t c) override; virtual size_t write(const uint8_t *buffer, size_t size) override; bool add(Print * stream); // returns true on success void reset(); + // CONTROL - uint8_t count() { return _count; }; - uint8_t size() { return _size; }; - void enable(uint8_t index); - void enableStream(Print * stream); - void disable(uint8_t index); - void disableStream(Print * stream); + uint8_t count() { return _count; }; + uint8_t size() { return _size; }; + uint8_t free() { return _size - _count; }; + + // returns true on success, false otherwise. + bool enable(uint8_t index); + bool enableStream(Print * stream); + bool disable(uint8_t index); + bool disableStream(Print * stream); + bool isEnabled(uint8_t index); bool isEnabledStream(Print * stream); + uint8_t index(Print *stream); + Print * stream(uint8_t index); + + private: Print * _stream[MAX_MULTIPLEX]; - bool _enabled[MAX_MULTIPLEX]; // bitmask max 4 ... + bool _enabled[MAX_MULTIPLEX]; + uint8_t _count; uint8_t _size; - uint8_t index(Print *stream); }; // -- END OF FILE -- diff --git a/libraries/Multiplex/README.md b/libraries/Multiplex/README.md index cf3b1ee6..143ddc63 100644 --- a/libraries/Multiplex/README.md +++ b/libraries/Multiplex/README.md @@ -1,60 +1,85 @@ [![Arduino CI](https://github.com/RobTillaart/Multiplex/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![JSON check](https://github.com/RobTillaart/Multiplex/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/Multiplex/actions/workflows/jsoncheck.yml) +[![Arduino-lint](https://github.com/RobTillaart/Multiplex/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/Multiplex/actions/workflows/arduino-lint.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/Multiplex/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/RobTillaart/Multiplex.svg?maxAge=3600)](https://github.com/RobTillaart/Multiplex/releases) # Multiplex -Arduino Library implementing a stream multiplexer. +Arduino Library implementing a (Print) stream multiplexer. + ## Description -Multiplex is a library in which one can add multiple Print streams. +Multiplex is a library in which one can add multiple Print streams. +If one prints to the multiplexer the data is sent to all the streams that were added. -If one prints to the multiplexer it is sent to all the streams that were added. - -The maximum nr of streams to add is 4. - -It is possible to disable individual streams. +The maximum number of streams to add is 4. This value is defined in the **multiplex.h file** with `#define MAX_MULTIPLEX` +This value can be set to 254 MAX as the number 255 / 0xFF is used as a NOT_FOUND flag. Streams can be enabled or disabled by calling `enable()/disable()` passing either an index (based on the order -in whicbh `add` was called; 0 is first) or a pointer to the `Print` -object that was passed to `add(Print *)`; +in which `add` was called; 0 is first) or a pointer to the `Print` +object that was passed to `add(Print *)` by calling `enableStream()/disableStream()` + +It is not possible to remove a stream from the multiplexer (yet), as this would affect the indices used. +Solution is to reset and repopulate for now. + ## Interface + ### Constructor -- **Multiplex()** constructor -- **void reset()** resets to zero streams in the multiplexer. +- **Multiplex(uint8_t max_multiplex = 4)** constructor, +sets the maximum number of streams to 4 by default. +MAX number is 254 as 255 (0xFF) is used as a flag for **NOT FOUND**. +- **~Multiplex()** destructor +- **void reset()** resets the count in the multiplexer to zero streams. + ### Core -- **size_t write(uint8_t c)** workhorse of the print interface. +- **size_t write(uint8_t c)** workhorse of the print interface. +Writes a character to all enabled streams. +- **size_t write(const uint8_t \*buffer, size_t size)** +Writes a buffer of size characters to all enabled streams. - **bool add(Print \* stream)** add another print stream. Returns false if no space left. ### Control -- **uint8_t count()** returns # streams, MAX 4 in initial release +- **uint8_t count()** returns number of streams added, MAX 4 in initial release - **uint8_t size()** returns size which is 4 in the current release. -- **void enable(uint8_t index)** enable the stream at index. -- **void enableStream(Stream * stream)** enable the stream. -- **void disable(uint8_t index)** disable the stream at index. -- **void disableStream(Stream * stream)** disable the stream. -- **bool isEnabled(uint8_t index)** checks if the stream at index is enabled. -- **bool isEnabledStream(Stream * stream)** checks if the stream is enabled. +- **uint8_t free()** returns number of free slots. +- **bool enable(uint8_t index)** enable the stream at index. +Returns true on success, false otherwise. +- **bool enableStream(Stream \* stream)** enable the stream. +Returns true on success, false otherwise. +- **bool disable(uint8_t index)** disable the stream at index. +Returns true on success, false otherwise. +- **bool disableStream(Stream \* stream)** disable the stream. +Returns true on success, false otherwise. +- **bool isEnabled(uint8_t index)** returns true if the stream at index is enabled, +false otherwise. +- **bool isEnabledStream(Stream \* stream)** returns true if the stream is enabled, +false otherwise. +- **uint8_t index(Print \*stream)** returns the index of the stream if it was added, +otherwise it returns 0xFF == 255. +Can be used to check if a stream is added the multiplexer. +- **Print \* stream(uint8_t index)** returns the stream at index or NULL otherwise. +Convenience function. ## Future -- set size in constructor +- set size in constructor - dynamic memory +- pack enabled flag in one or more bytes - add names? -- bool inMp(stream) -- add returns int index? or 0xFF for fail -- remove a stream from the multiplex ??? => complexer admin. -- increase up to 8 streams. (pack enabled flag in one byte) +- remove a stream from the multiplex ? +`bool remove(Print * stream); plus bool remove(uint8_t idx) ?` +- iterate over the streams? `Print * getStream(idx)` ## Operation diff --git a/libraries/Multiplex/examples/Multiplex_enable_stream/Multiplex_enable_stream.ino b/libraries/Multiplex/examples/Multiplex_enable_stream/Multiplex_enable_stream.ino new file mode 100644 index 00000000..a0dc0be1 --- /dev/null +++ b/libraries/Multiplex/examples/Multiplex_enable_stream/Multiplex_enable_stream.ino @@ -0,0 +1,65 @@ +// +// FILE: Multiplex_enable_stream.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.2.1 +// PURPOSE: demo +// DATE: 2021-089-10 + + +#include "Multiplex.h" + + +Multiplex mp; + + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + mp.add(&Serial); + mp.println("one"); + mp.add(&Serial); + mp.println("one++"); + + for (int i = 0; i < mp.count(); i++) + { + Serial.print("isEnabled "); + Serial.print(i); + Serial.print(":\t"); + Serial.println(mp.isEnabled(i)); + } + + mp.disableStream(&Serial); + mp.println("two"); + + for (int i = 0; i < mp.count(); i++) + { + Serial.print("isEnabled "); + Serial.print(i); + Serial.print(":\t"); + Serial.println(mp.isEnabled(i)); + } + + mp.disableStream(&Serial); + mp.println("three"); + + for (int i = 0; i < mp.count(); i++) + { + Serial.print("isEnabled "); + Serial.print(i); + Serial.print(":\t"); + Serial.println(mp.isEnabled(i)); + } + + mp.enableStream(&Serial); + mp.println("\n Done...\n"); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/Multiplex/examples/Multiplex_softwareSerial/Multiplex_softwareSerial.ino b/libraries/Multiplex/examples/Multiplex_softwareSerial/Multiplex_softwareSerial.ino index 747d32ea..c521ffd7 100644 --- a/libraries/Multiplex/examples/Multiplex_softwareSerial/Multiplex_softwareSerial.ino +++ b/libraries/Multiplex/examples/Multiplex_softwareSerial/Multiplex_softwareSerial.ino @@ -1,21 +1,25 @@ // // FILE: Multiplex_softwareSerial.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.2.1 // PURPOSE: demo // DATE: 2021-01-17 + #include "Multiplex.h" #include + // one multiplexer Multiplex mp; + // three serial outputs SoftwareSerial Serial_A(-1, 8); SoftwareSerial Serial_B(-1, 9); SoftwareSerial Serial_C(-1, 10); + void setup() { Serial.begin(115200); @@ -41,7 +45,7 @@ void setup() Serial.print("count: "); Serial.println(n); - mp.disable(&Serial_B); + mp.disableStream(&Serial_B); for (int i = 0; i < mp.count(); i++) { @@ -52,11 +56,10 @@ void setup() } mp.println("\nThis should only print on Serial_A and Serial_C\n"); - mp.println("Done...\n"); - } + void loop() { } diff --git a/libraries/Multiplex/examples/Multiplex_test/Multiplex_test.ino b/libraries/Multiplex/examples/Multiplex_test/Multiplex_test.ino index 62408670..ab0f0ea8 100644 --- a/libraries/Multiplex/examples/Multiplex_test/Multiplex_test.ino +++ b/libraries/Multiplex/examples/Multiplex_test/Multiplex_test.ino @@ -1,14 +1,17 @@ // // FILE: Multiplex_test.ino // AUTHOR: Rob Tillaart -// VERSION: 0.2.0 +// VERSION: 0.2.1 // PURPOSE: demo // DATE: 2021-01-09 + #include "Multiplex.h" + Multiplex mp; + class FakeStream : public Print { public: @@ -36,6 +39,7 @@ class FakeStream : public Print uint8_t _id = 0; }; + void setup() { Serial.begin(115200); @@ -96,9 +100,9 @@ void setup() } mp.print("Done...\n"); - } + void loop() { } diff --git a/libraries/Multiplex/keywords.txt b/libraries/Multiplex/keywords.txt index de78b0d1..9ac5d031 100644 --- a/libraries/Multiplex/keywords.txt +++ b/libraries/Multiplex/keywords.txt @@ -1,14 +1,19 @@ -# Syntax Coloring Map for Multiplex +# Syntax Colouring Map for Multiplex -# Datatypes (KEYWORD1) + +# Data types (KEYWORD1) Multiplex KEYWORD1 + # Methods and Functions (KEYWORD2) write KEYWORD2 add KEYWORD2 reset KEYWORD2 + count KEYWORD2 size KEYWORD2 +free KEYWORD2 + enable KEYWORD2 disable KEYWORD2 isEnabled KEYWORD2 @@ -16,7 +21,7 @@ isEnabled KEYWORD2 enableStream KEYWORD2 disableStream KEYWORD2 isEnabledStream KEYWORD2 - +index KEYWORD2 # Constants (LITERAL1) MULTIPLEX_LIB_VERSION LITERAL1 diff --git a/libraries/Multiplex/library.json b/libraries/Multiplex/library.json index c06d29db..edf2c29a 100644 --- a/libraries/Multiplex/library.json +++ b/libraries/Multiplex/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/Multiplex" }, - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "frameworks": "arduino", "platforms": "*" diff --git a/libraries/Multiplex/library.properties b/libraries/Multiplex/library.properties index 995be85e..a70457cf 100644 --- a/libraries/Multiplex/library.properties +++ b/libraries/Multiplex/library.properties @@ -1,5 +1,5 @@ name=Multiplex -version=0.2.0 +version=0.2.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino Library implementing a stream multiplexer