From 9abe1508b17156a253663171a7b4b118a1e72d60 Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Fri, 27 Nov 2020 11:28:57 +0100 Subject: [PATCH] update libraries M..P --- libraries/NibbleArray/LICENSE | 21 ++ libraries/NibbleArray/README.md | 29 ++ .../nibbleArray_demo/nibbleArray_demo.ino | 144 +++++++++ .../nibbleArray_performance.ino | 170 +++++++++++ libraries/NibbleArray/library.json | 9 +- libraries/NibbleArray/library.properties | 6 +- libraries/NibbleArray/nibbleArray.cpp | 50 ++-- libraries/NibbleArray/nibbleArray.h | 46 +-- libraries/PCA9635/LICENSE | 21 ++ libraries/PCA9635/PCA9635.cpp | 206 ++++++++----- libraries/PCA9635/PCA9635.h | 85 +++--- libraries/PCA9635/README.md | 76 +++++ .../PCA9635_test01/PCA9635_test01.ino | 279 +++++++++--------- .../PCA9635_test_multiple.ino | 56 ++++ libraries/PCA9635/library.json | 11 +- libraries/PCA9635/library.properties | 12 +- libraries/PCA9685/LICENSE | 21 ++ libraries/PCA9685/PCA9685.cpp | 139 ++++++--- libraries/PCA9685/PCA9685.h | 61 ++-- libraries/PCA9685/README.md | 89 ++++++ .../PCA9685_allOFF_test.ino | 53 ++++ .../PCA9685_digitalWrite_test.ino | 66 +++++ .../PCA9685_maxPWM_test.ino | 70 +++++ .../PCA9685_setFrequency_offset.ino | 101 +++++++ .../PCA9685_setFrequency_test.ino | 92 ++++++ .../PCA9685_test01/PCA9685_test01.ino | 82 ++--- .../PCA9685_test02/PCA9685_test02.ino | 40 +-- libraries/PCA9685/library.json | 13 +- libraries/PCA9685/library.properties | 12 +- libraries/PCF8574/PCF8574.cpp | 3 +- libraries/PCF8574/PCF8574.h | 4 +- libraries/PCF8574/library.json | 7 +- libraries/PCF8574/library.properties | 2 +- libraries/Par27979/LICENSE | 21 ++ libraries/Par27979/Par27979.h | 104 ++++--- .../examples/PAR27979_demo/PAR27979_demo.ino | 78 +++++ .../PAR27979_demo2/PAR27979_demo2.ino | 75 +++++ libraries/Par27979/keywords.txt | 28 ++ libraries/Par27979/library.json | 15 +- libraries/Par27979/library.properties | 16 +- libraries/Par27979/readme.md | 46 ++- .../replaced by parallelPrinter.txt | 1 + libraries/PinInGroup/PinInGroup.cpp | 8 +- libraries/PinInGroup/PinInGroup.h | 4 +- libraries/PinInGroup/library.json | 7 +- libraries/PinInGroup/library.properties | 2 +- libraries/PinOutGroup/PinOutGroup.cpp | 16 +- libraries/PinOutGroup/PinOutGroup.h | 4 +- libraries/PinOutGroup/library.json | 7 +- libraries/PinOutGroup/library.properties | 2 +- libraries/Prandom/Prandom.cpp | 4 +- libraries/Prandom/Prandom.h | 76 ++--- libraries/Prandom/library.json | 7 +- libraries/Prandom/library.properties | 2 +- libraries/PrintCharArray/LICENSE | 21 ++ libraries/PrintCharArray/PrintCharArray.h | 50 ++-- .../printCharArray1/printCharArray1.ino | 2 + .../printCharArray2/printCharArray2.ino | 4 +- .../printCharArray3/printCharArray3.ino | 14 +- .../printCharArray4/printCharArray4.ino | 33 ++- .../printCharArrayDynamicSize.ino | 39 +++ libraries/PrintCharArray/keywords..txt | 14 + libraries/PrintCharArray/library.json | 9 +- libraries/PrintCharArray/library.properties | 6 +- libraries/PrintCharArray/readme.md | 15 +- libraries/PrintSize/LICENSE | 21 ++ libraries/PrintSize/PrintSize.h | 39 ++- .../examples/PrintSize1/PrintSize1.ino | 4 +- .../PrintSize_centering.ino | 83 ++++++ .../PrintSize_printf/PrintSize_printf.ino | 2 + .../PrintSize_total/PrintSize_total.ino | 89 ++++++ libraries/PrintSize/keywords..txt | 12 + libraries/PrintSize/library.json | 9 +- libraries/PrintSize/library.properties | 7 +- libraries/PrintSize/readme.md | 27 +- libraries/PrintString/LICENSE | 21 ++ libraries/PrintString/PrintString.h | 26 +- libraries/PrintString/README.md | 19 ++ .../examples/printString/printString.ino | 13 +- libraries/PrintString/keywords..txt | 13 + libraries/PrintString/library.json | 9 +- libraries/PrintString/library.properties | 5 +- libraries/PulsePattern/LICENSE | 21 ++ libraries/PulsePattern/PulsePattern.cpp | 86 +++--- libraries/PulsePattern/PulsePattern.h | 76 +++-- libraries/PulsePattern/README.md | 58 ++++ .../examples/SOS_demo2/SOS_demo2.ino | 29 +- .../pattern_recorder/pattern_recorder.ino | 60 ++++ .../random_pattern/random_pattern.ino | 49 +++ .../examples/siren_pattern/siren_pattern.ino | 38 +++ libraries/PulsePattern/keywords.txt | 26 ++ libraries/PulsePattern/library.json | 13 +- libraries/PulsePattern/library.properties | 12 +- 93 files changed, 2869 insertions(+), 804 deletions(-) create mode 100644 libraries/NibbleArray/LICENSE create mode 100644 libraries/NibbleArray/README.md create mode 100644 libraries/NibbleArray/examples/nibbleArray_demo/nibbleArray_demo.ino create mode 100644 libraries/NibbleArray/examples/nibbleArray_performance/nibbleArray_performance.ino create mode 100644 libraries/PCA9635/LICENSE create mode 100644 libraries/PCA9635/README.md create mode 100644 libraries/PCA9635/examples/PCA9635_test_multiple/PCA9635_test_multiple.ino create mode 100644 libraries/PCA9685/LICENSE create mode 100644 libraries/PCA9685/README.md create mode 100644 libraries/PCA9685/examples/PCA9685_allOFF_test/PCA9685_allOFF_test.ino create mode 100644 libraries/PCA9685/examples/PCA9685_digitalWrite_test/PCA9685_digitalWrite_test.ino create mode 100644 libraries/PCA9685/examples/PCA9685_maxPWM_test/PCA9685_maxPWM_test.ino create mode 100644 libraries/PCA9685/examples/PCA9685_setFrequency_offset/PCA9685_setFrequency_offset.ino create mode 100644 libraries/PCA9685/examples/PCA9685_setFrequency_test/PCA9685_setFrequency_test.ino create mode 100644 libraries/Par27979/LICENSE create mode 100644 libraries/Par27979/examples/PAR27979_demo/PAR27979_demo.ino create mode 100644 libraries/Par27979/examples/PAR27979_demo2/PAR27979_demo2.ino create mode 100644 libraries/Par27979/keywords.txt create mode 100644 libraries/ParPrinter/replaced by parallelPrinter.txt create mode 100644 libraries/PrintCharArray/LICENSE create mode 100644 libraries/PrintCharArray/examples/printCharArrayDynamicSize/printCharArrayDynamicSize.ino create mode 100644 libraries/PrintCharArray/keywords..txt create mode 100644 libraries/PrintSize/LICENSE create mode 100644 libraries/PrintSize/examples/PrintSize_centering/PrintSize_centering.ino create mode 100644 libraries/PrintSize/examples/PrintSize_total/PrintSize_total.ino create mode 100644 libraries/PrintSize/keywords..txt create mode 100644 libraries/PrintString/LICENSE create mode 100644 libraries/PrintString/README.md create mode 100644 libraries/PrintString/keywords..txt create mode 100644 libraries/PulsePattern/LICENSE create mode 100644 libraries/PulsePattern/README.md create mode 100644 libraries/PulsePattern/examples/pattern_recorder/pattern_recorder.ino create mode 100644 libraries/PulsePattern/examples/random_pattern/random_pattern.ino create mode 100644 libraries/PulsePattern/examples/siren_pattern/siren_pattern.ino create mode 100644 libraries/PulsePattern/keywords.txt diff --git a/libraries/NibbleArray/LICENSE b/libraries/NibbleArray/LICENSE new file mode 100644 index 00000000..ed401f22 --- /dev/null +++ b/libraries/NibbleArray/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/NibbleArray/README.md b/libraries/NibbleArray/README.md new file mode 100644 index 00000000..3b40c37e --- /dev/null +++ b/libraries/NibbleArray/README.md @@ -0,0 +1,29 @@ +# nibbleArray + +Arduino library for a compact array of nibbles (4 bit units) + +## Description + +A nibble is a 4 bit element, which can hold a value 0..15 (0..F in HEX). + +The nibbleArray is an array that stores 2 nibbles in a byte therefor it is +twice as small as a normal array. + +The current implementation can hold 510 elements. This is due a limitation of +the UNO which can alloc max 255 bytes in one **malloc()** call. + +This **NIBBLEARRAY_MAXSIZE** can be defined compiletime "-D NIBBLEARRAY_MAXSIZE" +or one can adjust it in the library if other platforms can allocate more memory. + +## Interface + +The interface of the nibbleArray is straightforward: + +* **get(index)** idem +* **set(index, value)** idem +* **clear()** set all elements to 0; +* **SetAll(value)** set all elements to value + +## Operation + + diff --git a/libraries/NibbleArray/examples/nibbleArray_demo/nibbleArray_demo.ino b/libraries/NibbleArray/examples/nibbleArray_demo/nibbleArray_demo.ino new file mode 100644 index 00000000..9cc90dbe --- /dev/null +++ b/libraries/NibbleArray/examples/nibbleArray_demo/nibbleArray_demo.ino @@ -0,0 +1,144 @@ +// +// FILE: nibbleArray_demo.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo nibble array +// DATE: 2020-06-21 +// URL: https://github.com/RobTillaart/nibbleArray + +// 0.1.0 2020-06-21 initial version +// +#include "nibbleArray.h" + +nibbleArray na(500); + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("NIBBLEARRAY_LIB_VERSION: "); + Serial.println(NIBBLEARRAY_LIB_VERSION); + + test_1(); + + Serial.println("\nDone..."); +} + +void test_1() +{ + int ar[16]; + for (int i = 0; i < 16; i++) ar[i] = 0; + + na.clear(); + + // 500 throws with 3 dices (3..18 ==> 0..15) + for (int i = 0; i < 500; i++) + { + uint8_t sum = random(6); + sum += random(6); + sum += random(6); + na.set(i, sum); // diff from na.set(i, random(16)); + } + for (int i = 0; i < 500; i++) + { + ar[na.get(i)]++; + Serial.print(" "); + Serial.print(na.get(i), HEX); + if ((i % 32) == 31) Serial.println(); + } + Serial.println(); + Serial.println("\nFrequency analysis"); + for (int i = 0; i < 16; i++) + { + Serial.print(i); + Serial.print("\t"); + // for (int p = 0; p < ar[i]; p++) Serial.print(">"); + Serial.print(ar[i]); + Serial.println(); + } + Serial.println(); + + Serial.println("\ninterpret data as a route"); + for (int i = 0; i < 20; ) + { + uint8_t s = na.get(i++); + uint8_t d = na.get(i++); + move(s, d); + } + + Serial.println("\nor store music in the array"); + for (int i = 0; i < 30; ) + { + uint8_t octave = na.get(i++); + uint8_t note = na.get(i++); + uint8_t duration = na.get(i++); // in 1/16th + play(octave, note, duration); + // sendMIDI(note, duration); + } +} + +void play(uint8_t chord, uint8_t note, uint8_t duration) +{ + Serial.print("Play: "); + // Serial.print(chord); + Serial.print(" "); + switch (note) + { + case 0: Serial.print("C "); break; + case 1: Serial.print("C# "); break; + case 2: Serial.print("D "); break; + case 3: Serial.print("D# "); break; + case 4: Serial.print("E "); break; + case 5: Serial.print("F "); break; + case 6: Serial.print("F# "); break; + case 7: Serial.print("G "); break; + case 8: Serial.print("G# "); break; + case 9: Serial.print("A "); break; + case 10: Serial.print("A# "); break; + case 11: Serial.print("B "); break; + case 12: Serial.print("C "); break; + case 13: Serial.print("C# "); break; + case 14: Serial.print("D "); break; + case 15: Serial.print(" - "); break; + } + for (uint8_t i = 0; i < duration; i++) + { + delay(1000 / 16); + Serial.print("."); + } + Serial.println(); +} + + +void move(uint8_t steps, uint8_t direction) +{ + Serial.print(steps); + Serial.print(" steps to the "); + switch (direction) + { + case 0: Serial.print("N"); break; + case 1: Serial.print("NNO"); break; + case 2: Serial.print("NO"); break; + case 3: Serial.print("ONO"); break; + case 4: Serial.print("O"); break; + case 5: Serial.print("OZO"); break; + case 6: Serial.print("ZO"); break; + case 7: Serial.print("ZZO"); break; + case 8: Serial.print("Z"); break; + case 9: Serial.print("ZZW"); break; + case 10: Serial.print("ZW"); break; + case 11: Serial.print("WZW"); break; + case 12: Serial.print("W"); break; + case 13: Serial.print("WNW"); break; + case 14: Serial.print("NW"); break; + case 15: Serial.print("NNW"); break; + } + Serial.println(); + delay(100 * steps); +} + +void loop() +{ +} + +// -- END OF FILE -- diff --git a/libraries/NibbleArray/examples/nibbleArray_performance/nibbleArray_performance.ino b/libraries/NibbleArray/examples/nibbleArray_performance/nibbleArray_performance.ino new file mode 100644 index 00000000..6b49d5bc --- /dev/null +++ b/libraries/NibbleArray/examples/nibbleArray_performance/nibbleArray_performance.ino @@ -0,0 +1,170 @@ +// +// FILE: nibbleArray_performance.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo performance nibble array +// DATE: 2020-06-21 +// URL: https://github.com/RobTillaart/nibbleArray + +// 0.1.0 2020-06-21 initial version +// +#include "nibbleArray.h" + +nibbleArray na(500); + +uint32_t start, stop, d1, d2; +volatile long x = 0; + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("NIBBLEARRAY_LIB_VERSION: "); + Serial.println(NIBBLEARRAY_LIB_VERSION); + + // performance tests are run first once in a loop + // then twice in a loop, so the difference is without + // the loop overhead. + test_size(); + test_get(); + test_set(); + test_clear(); + test_setAll(); + + Serial.println("Done..."); +} + +void test_size() +{ + Serial.print("Nibble array size:\t"); + Serial.println(na.size()); + delay(100); +} + +void test_get() +{ + Serial.println("\nget"); + start = micros(); + for (int i = 0; i < 500; i++) + { + x += na.get(i); + } + stop = micros(); + Serial.print("DURATION:\t"); + d1 = stop - start; + Serial.println(d1); + delay(100); + + start = micros(); + for (int i = 0; i < 500; i++) + { + x += na.get(i); + x += na.get(i); + } + stop = micros(); + Serial.print("DURATION:\t"); + d2 = stop - start; + Serial.println(d2); + Serial.print("DELTA:\t\t"); + Serial.println(d2 - d1); + Serial.print(" X:\t"); + Serial.println(x); + delay(100); +} + +void test_set() +{ + Serial.println("\nset"); + start = micros(); + for (int i = 0; i < 500; i++) + { + na.set(i, 5); + } + stop = micros(); + Serial.print("DURATION:\t"); + d1 = stop - start; + Serial.println(d1); + delay(100); + + start = micros(); + for (int i = 0; i < 500; i++) + { + na.set(i, 5); + na.set(i, 10); + } + stop = micros(); + Serial.print("DURATION:\t"); + d2 = stop - start; + Serial.println(d2); + Serial.print("DELTA:\t\t"); + Serial.println(d2 - d1); + delay(100); +} + +void test_clear() +{ + Serial.println("\nclear"); + start = micros(); + na.clear(); + stop = micros(); + Serial.print("DURATION:\t"); + d1 = stop - start; + Serial.println(d1); + delay(100); + + start = micros(); + na.clear(); + na.clear(); + stop = micros(); + Serial.print("DURATION:\t"); + d2 = stop - start; + Serial.println(d2); + Serial.print("DELTA:\t\t"); + Serial.println(d2 - d1); + delay(100); + for (int i = 0; i < 500; i++) + { + if (na.get(i) != 0) + { + Serial.println("Error in clear"); + } + } + delay(100); +} + +void test_setAll() +{ + Serial.println("\nsetAll"); + start = micros(); + na.setAll(1); + stop = micros(); + Serial.print("DURATION:\t"); + d1 = stop - start; + Serial.println(d1); + delay(100); + for (int i = 0; i < 500; i++) + { + if (na.get(i) != 1) + { + Serial.println("Error in setAll"); + } + } + delay(100); + + start = micros(); + na.setAll(2); + na.setAll(3); + stop = micros(); + Serial.print("DURATION:\t"); + d2 = stop - start; + Serial.println(d2); + Serial.print("DELTA:\t\t"); + Serial.println(d2 - d1); + delay(100); +} + +void loop() +{ +} + +// -- END OF FILE -- diff --git a/libraries/NibbleArray/library.json b/libraries/NibbleArray/library.json index ca3ce6a3..00c70d6a 100644 --- a/libraries/NibbleArray/library.json +++ b/libraries/NibbleArray/library.json @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/nibbleArray.git" }, - "version":"0.1.0", + "version":"0.2.0", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/NibbleArray" - } + "platforms": "*" } diff --git a/libraries/NibbleArray/library.properties b/libraries/NibbleArray/library.properties index d4de49ae..da030237 100644 --- a/libraries/NibbleArray/library.properties +++ b/libraries/NibbleArray/library.properties @@ -1,9 +1,11 @@ name=NibbleArray -version=0.1.0 +version=0.2.0 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library to implement a compact array of nibbles (4 bit). paragraph= category=Data Processing url=https://github.com/RobTillaart/Arduino/tree/master/libraries/ -architectures=* \ No newline at end of file +architectures=* +includes=nibbleArray.h +depends= diff --git a/libraries/NibbleArray/nibbleArray.cpp b/libraries/NibbleArray/nibbleArray.cpp index 51b0bcc5..74eacd76 100644 --- a/libraries/NibbleArray/nibbleArray.cpp +++ b/libraries/NibbleArray/nibbleArray.cpp @@ -1,47 +1,53 @@ // // FILE: nibbleArray.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.00 -// PURPOSE: compact storage for array of nibbles -// URL: +// VERSION: 0.2.0 +// PURPOSE: Arduino library for a compact array of nibbles (4 bits) +// URL: https://github.com/RobTillaart/nibbleArray // // HISTORY: -// 0.1.00 by Rob Tillaart (12/APR/2015) -// -// Released to the public domain +// 0.1.0 2015-04-12 initial version +// 0.2.0 2020-06-21 refactor; #pragma once; removed pre 1.0 support // #include "nibbleArray.h" -///////////////////////////////////////////////////// -// -// PUBLIC -// nibbleArray::nibbleArray(uint16_t size) { - arr = (uint16_t *) malloc((size+1)/2); + _size = min(NIBBLEARRAY_MAXSIZE, size); + arr = (uint8_t *) malloc((_size + 1)/2); } nibbleArray::~nibbleArray() { - if (arr != NULL) free(arr); + if (arr != NULL) free(arr); } uint8_t nibbleArray::get(const uint16_t idx) { - if (idx > _size) return 255; // magic error nr - if (idx & 1) return arr[idx/2] & 0x0F; - return arr[idx/2] >> 4; + if (idx > _size) return NIBBLEARRAY_ERROR_INDEX; // disable this check for more speed + if (idx & 1) return arr[idx/2] & 0x0F; + return arr[idx/2] >> 4; } uint8_t nibbleArray::set(const uint16_t idx, uint8_t value) { - if (idx > _size) return 255; // magic error nr. - uint8_t v = value & 0x0F; - if (idx & 1) arr[idx/2] = (arr[idx/2] & 0xF0) | v; - else arr[idx/2] = (arr[idx/2] & 0x0F) | (v << 4); + if (idx > _size) return NIBBLEARRAY_ERROR_INDEX; // disable this check for more speed + uint8_t v = value & 0x0F; + if (idx & 1) arr[idx/2] = (arr[idx/2] & 0xF0) | v; + else arr[idx/2] = (arr[idx/2] & 0x0F) | (v << 4); + return NIBBLEARRAY_OK; } -// -// END OF FILE -// \ No newline at end of file +void nibbleArray::clear() +{ + memset(arr, 0, (_size+1)/2); +} + +void nibbleArray::setAll(uint8_t val) +{ + uint8_t v = (val << 4) | val; + memset(arr, v, (_size+1)/2); +} + +// -- END OF FILE -- diff --git a/libraries/NibbleArray/nibbleArray.h b/libraries/NibbleArray/nibbleArray.h index 4f18bfa3..d2374fcf 100644 --- a/libraries/NibbleArray/nibbleArray.h +++ b/libraries/NibbleArray/nibbleArray.h @@ -1,39 +1,45 @@ +#pragma once // // FILE: nibbleArray.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.00 -// PURPOSE: compact storage for array of nibbles -// URL: +// VERSION: 0.2.0 +// PURPOSE: Arduino library for a compact array of nibbles (4 bits) +// URL: https://github.com/RobTillaart/nibbleArray // // HISTORY: // see nibbleArray.cpp // -#ifndef nibbleArray_h -#define nibbleArray_h - -#if ARDUINO < 100 -#include -#else #include + +#define NIBBLEARRAY_LIB_VERSION "0.2.0" + +#ifndef NIBBLEARRAY_MAXSIZE +#define NIBBLEARRAY_MAXSIZE 510 #endif -#define NIBBLEARRAY_LIB_VERSION "0.1.00" +#define NIBBLEARRAY_OK 0x00 +#define NIBBLEARRAY_ERROR_INDEX 0xFF class nibbleArray { public: - nibbleArray(uint16_t size); - ~nibbleArray(); + nibbleArray(uint16_t size); + ~nibbleArray(); - uint8_t get(const uint16_t idx); - uint8_t set(const uint16_t idx, uint8_t value); + // return 0..F if ok + // retuns 0xFF for index error. + uint8_t get(const uint16_t idx); + // retuns 0xFF for index error. + uint8_t set(const uint16_t idx, uint8_t value); + + uint16_t size() { return _size; }; + void clear(); + void setAll(uint8_t val); private: - uint16_t *arr; - uint16_t _size; + uint8_t *arr; + uint16_t _size; }; -#endif -// -// END OF FILE -// \ No newline at end of file + +// -- END OF FILE -- diff --git a/libraries/PCA9635/LICENSE b/libraries/PCA9635/LICENSE new file mode 100644 index 00000000..9aa72bbc --- /dev/null +++ b/libraries/PCA9635/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/PCA9635/PCA9635.cpp b/libraries/PCA9635/PCA9635.cpp index 1c220930..7e1550dd 100644 --- a/libraries/PCA9635/PCA9635.cpp +++ b/libraries/PCA9635/PCA9635.cpp @@ -2,134 +2,182 @@ // FILE: PCA9635.cpp // AUTHOR: Rob Tillaart // DATE: 23-apr-2016 -// VERSION: 0.1.2 -// PURPOSE: I2C PCA9635 library for Arduino -// URL: +// VERSION: 0.2.0 +// PURPOSE: Arduino library for PCA9635 I2C LED driver +// URL: https://github.com/RobTillaart/PCA9635 // // HISTORY: -// 0.1.2 fix for PCA9635_MODE1 -// 0.1.01 set autoincr in constructor -// 0.1.00 initial BETA version +// 0.2.0 2020-05-26 major refactor; ESP32 support +// 0.1.2 2020-05-07 fix for PCA9635_MODE1 +// 0.1.1 2016-04-24 set autoincr in constructor +// 0.1.0 2016-04-23 initial BETA version // #include "PCA9635.h" #include + PCA9635::PCA9635(const uint8_t deviceAddress) { - _address = deviceAddress; - Wire.begin(); - // TWBR = 12; // 400KHz - _data = 0; - _error = 0; - writeReg(PCA9635_MODE1, 0x81); // AUTOINCR | NOSLEEP | ALLADRR + _address = deviceAddress; +} + +#if defined (ESP8266) || defined(ESP32) +void PCA9635::begin(uint8_t sda, uint8_t scl) +{ + Wire.begin(sda, scl); + reset(); +} +#endif + +void PCA9635::begin() +{ + Wire.begin(); + reset(); +} + +void PCA9635::reset() +{ + _data = 0; + _error = 0; + writeReg(PCA9635_MODE1, 0x81); // AUTOINCR | NOSLEEP | ALLADRR } // write value to single PWM registers -void PCA9635::write1(uint8_t channel, uint8_t value) +uint8_t PCA9635::write1(uint8_t channel, uint8_t value) { - writeN(channel, &value, 1); + return writeN(channel, &value, 1); } // write three values in consecutive PWM registers // typically for RGB values -void PCA9635::write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B) +uint8_t PCA9635::write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B) { - uint8_t arr[3] = { R, G, B }; - writeN(channel, arr, 3); + uint8_t arr[3] = { R, G, B }; + return writeN(channel, arr, 3); } // write count values in consecutive PWM registers -void PCA9635::writeN(uint8_t channel, uint8_t* arr, uint8_t count) +// does not check if [channel + count > 16] +uint8_t PCA9635::writeN(uint8_t channel, uint8_t* arr, uint8_t count) { - uint8_t base = PCA9635_PWM(channel); - Wire.beginTransmission(_address); - Wire.write(base); - for(uint8_t i = 0; i < count; i++) - { - Wire.write(arr[i]); - } - _error = Wire.endTransmission(); + if (channel + count > 16) + { + _error = PCA9635_ERR_WRITE; + return PCA9635_ERROR; + } + uint8_t base = PCA9635_PWM(channel); + Wire.beginTransmission(_address); + Wire.write(base); + for(uint8_t i = 0; i < count; i++) + { + Wire.write(arr[i]); + } + _error = Wire.endTransmission(); + if (_error != 0) + { + _error = PCA9635_ERR_I2C; + return PCA9635_ERROR; + } + return PCA9635_OK; } -// -void PCA9635::writeMode(uint8_t reg, uint8_t value) +uint8_t PCA9635::writeMode(uint8_t reg, uint8_t value) { - if (reg == PCA9635_MODE1 || reg == PCA9635_MODE2) - { - writeReg(reg, value); - } + if ((reg == PCA9635_MODE1) || (reg == PCA9635_MODE2)) + { + writeReg(reg, value); + return PCA9635_OK; + } + _error = PCA9635_ERR_REG; + return PCA9635_ERROR; } -// +// Note 0xFF can also mean an error.... uint8_t PCA9635::readMode(uint8_t reg) { - if ((reg == PCA9635_MODE1) || (reg == PCA9635_MODE2)) - { - uint8_t value = readReg(reg); - return value; - } - return PCA9635_ERROR; + if ((reg == PCA9635_MODE1) || (reg == PCA9635_MODE2)) + { + uint8_t value = readReg(reg); + return value; + } + _error = PCA9635_ERR_REG; + return PCA9635_ERROR; } -// -void PCA9635::setLedDriverMode(uint8_t channel, uint8_t mode) +uint8_t PCA9635::setLedDriverMode(uint8_t channel, uint8_t mode) { - if (channel <= 15 && mode <= 3) - { - uint8_t reg = PCA9635_LEDOUT_BASE + (channel >> 2); - // some bit magic - uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places - uint8_t setmask = mode << shift; - uint8_t clrmask = ~(0x03 << shift); - uint8_t value = (readReg(reg) & clrmask) | setmask; - writeReg(reg, value); - } + if (channel > 15) + { + _error = PCA9635_ERR_CHAN; + return PCA9635_ERROR; + } + if (mode > 3) + { + _error = PCA9635_ERR_MODE; + return PCA9635_ERROR; + } + + uint8_t reg = PCA9635_LEDOUT_BASE + (channel >> 2); + // some bit magic + uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places + uint8_t setmask = mode << shift; + uint8_t clrmask = ~(0x03 << shift); + uint8_t value = (readReg(reg) & clrmask) | setmask; + writeReg(reg, value); + return PCA9635_OK; } -// +// returns 0..3 if OK, other values indicate an error uint8_t PCA9635::getLedDriverMode(uint8_t channel) { - if (channel <= 15) - { - uint8_t reg = PCA9635_LEDOUT_BASE + (channel >> 2); - uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places - return (readReg(reg) >> shift ) & 0x03; - } + if (channel > 15) + { + _error = PCA9635_ERR_CHAN; return PCA9635_ERROR; + } + + uint8_t reg = PCA9635_LEDOUT_BASE + (channel >> 2); + uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places + uint8_t value = (readReg(reg) >> shift ) & 0x03; + return value; } -// +// note error flag is reset after read! int PCA9635::lastError() { - int e = _error; - _error = 0; - return e; + int e = _error; + _error = 0; + return e; } + +///////////////////////////////////////////////////// +// +// PRIVATE +// void PCA9635::writeReg(uint8_t reg, uint8_t value) { - Wire.beginTransmission(_address); - Wire.write(reg); - Wire.write(value); - _error = Wire.endTransmission(); + Wire.beginTransmission(_address); + Wire.write(reg); + Wire.write(value); + _error = Wire.endTransmission(); } + uint8_t PCA9635::readReg(uint8_t reg) { - Wire.beginTransmission(_address); - Wire.write(reg); - _error = Wire.endTransmission(); - if (Wire.requestFrom(_address, (uint8_t)1) != 1) - { - _error = PCA9635_ERROR; - return 0; - } - _data = Wire.read(); - return _data; + Wire.beginTransmission(_address); + Wire.write(reg); + _error = Wire.endTransmission(); + if (Wire.requestFrom(_address, (uint8_t)1) != 1) + { + _error = PCA9635_ERROR; + return 0; + } + _data = Wire.read(); + return _data; } -// -// END OF FILE -// \ No newline at end of file +// -- END OF FILE -- diff --git a/libraries/PCA9635/PCA9635.h b/libraries/PCA9635/PCA9635.h index 2db82341..997837fe 100644 --- a/libraries/PCA9635/PCA9635.h +++ b/libraries/PCA9635/PCA9635.h @@ -1,21 +1,16 @@ +#pragma once // // FILE: PCA9635.H // AUTHOR: Rob Tillaart // DATE: 23-apr-2016 -// VERSION: 0.1.2 -// PURPOSE: I2C PCA9635 library for Arduino -// URL: https://github.com/RobTillaart/Arduino/tree/master/libraries +// VERSION: 0.2.0 +// PURPOSE: Arduino library for PCA9635 I2C LED driver +// URL: https://github.com/RobTillaart/PCA9635 // -// HISTORY: -// see PCA9635.cpp file -// - -#ifndef _PCA9635_H -#define _PCA9635_H #include "Arduino.h" -#define PCA9635_LIB_VERSION "0.1.00 BETA" +#define PCA9635_LIB_VERSION "0.2.0" #define PCA9635_MODE1 0x00 #define PCA9635_MODE2 0x01 @@ -33,6 +28,11 @@ #define PCA9635_OK 0x00 #define PCA9635_ERROR 0xFF +#define PCA9635_ERR_WRITE 0xFE +#define PCA9635_ERR_CHAN 0xFD +#define PCA9635_ERR_MODE 0xFC +#define PCA9635_ERR_REG 0xFB +#define PCA9635_ERR_I2C 0xFA // NOT IMPLEMENTED YET #define PCA9635_SUBADR(x) (0x17+(x)) // x = 1..3 @@ -41,44 +41,49 @@ class PCA9635 { public: - explicit PCA9635(const uint8_t deviceAddress); + explicit PCA9635(const uint8_t deviceAddress); - void setLedDriverMode(uint8_t channel, uint8_t mode); - uint8_t getLedDriverMode(uint8_t channel); +#if defined (ESP8266) || defined(ESP32) + void begin(uint8_t sda, uint8_t scl); +#endif + void begin(); + void reset(); + + uint8_t setLedDriverMode(uint8_t channel, uint8_t mode); + uint8_t getLedDriverMode(uint8_t channel); - // single PWM setting - void write1(uint8_t channel, uint8_t value); - // RGB setting - void write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B); - // generic workhorse - void writeN(uint8_t channel, uint8_t* arr, uint8_t count); + // single PWM setting + uint8_t write1(uint8_t channel, uint8_t value); + + // RGB setting, write three consecutive PWM registers + uint8_t write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B); + + // generic worker, write N consecutive PWM registers + uint8_t writeN(uint8_t channel, uint8_t* arr, uint8_t count); - // reg = 1, 2 check datasheet for values - void writeMode(uint8_t reg, uint8_t value); - uint8_t readMode(uint8_t reg); + // reg = 1, 2 check datasheet for values + uint8_t writeMode(uint8_t reg, uint8_t value); + uint8_t readMode(uint8_t reg); - // TODO PWM also in %% ? - void setGroupPWM(uint8_t value) { writeReg(PCA9635_GRPPWM, value); } - uint8_t getGroupPWM() { return readReg(PCA9635_GRPPWM); } + // TODO PWM also in %% ? + void setGroupPWM(uint8_t value) { writeReg(PCA9635_GRPPWM, value); } + uint8_t getGroupPWM() { return readReg(PCA9635_GRPPWM); } - // TODO set time in millisec and round to nearest value? - void setGroupFREQ(uint8_t value) { writeReg(PCA9635_GRPFREQ, value); } - uint8_t getGroupFREQ() { return readReg(PCA9635_GRPFREQ); } + // TODO set time in millisec and round to nearest value? + void setGroupFREQ(uint8_t value) { writeReg(PCA9635_GRPFREQ, value); } + uint8_t getGroupFREQ() { return readReg(PCA9635_GRPFREQ); } - int lastError(); + int lastError(); private: - // DIRECT CONTROL - void writeReg(uint8_t reg, uint8_t value); - uint8_t readReg(uint8_t reg); + // DIRECT CONTROL + void writeReg(uint8_t reg, uint8_t value); + uint8_t readReg(uint8_t reg); - uint8_t _address; - uint8_t _register; - uint8_t _data; - int _error; + uint8_t _address; + uint8_t _register; + uint8_t _data; + int _error; }; -#endif -// -// END OF FILE -// +// -- END OF FILE -- diff --git a/libraries/PCA9635/README.md b/libraries/PCA9635/README.md new file mode 100644 index 00000000..3d5f96bc --- /dev/null +++ b/libraries/PCA9635/README.md @@ -0,0 +1,76 @@ +# PCA9635 + +Arduino library for PCA9635 I2C 8 bit PWM LED driver + +# Description + +This library is to control the I2C PCA9635 PWM extender. +The 16 channels are independently configurable is steps of 1/256. +this allows for better than 1% finetuning of the duty-cycle +of the PWM signal. + +### interface + +**begin()** initializes the library after startup. Mandatory. + +**begin(sda, scl)** idem, ESP32 ESP8266 only. Library does not support +multiple Wire instances (yet). + +**reset()** resets the library to start up conditions. +---- + +**setLedDriverMode(channel, mode)** mode is 0..3 See datasheet for full details. + +| LED mode | Value | Description | +|:----|:----:|:----| +| PCA9635_LEDOFF | 0x00 | led is 100% off, default @startup +| PCA9635_LEDON | 0x01 | led is 100% on. +| PCA9635_LEDPWM | 0x02 | set LED in PWM mode, 0..255 +| PCA9635_LEDGRPPWM | 0x03 | add LED to the GRPPWM* + +\* all leds in the group GRPPWM can be set to the same PWM value in one set. +This is ideal to trigger e.g. multiple LEDS (servo's) at same time. + +**getLedDriverMode(channel)** returns the current mode of the channel. + +---- +**write1(channel, value)** writes a single 8 bit PWM value. + +**write3(channel, R, G, B)** writes three consecutive PWM registers. + +**writeN(channel, array, count)** write count consecutive PWM registers. +May return **PCA9635_ERR_WRITE** if array has too many elements +(including channel as offset) + +**writeMode(reg, mode)** configuration of one of the two configuration registers. +check datasheet for details. + +**readMode(reg)** reads back the configured mode, useful to add or remove a +single flag (bit masking) + +---- + +**setGroupPWM(uint8_t value)** sets all channels that are part of the PWM group to value. + +**getGroupPWM()** get the current PWM setting of the group. + +**setGroupFREQ(value)** see datasheet for details. + +**getGroupFREQ()** returns the freq of the PWM group. + +**lastError()** returns **PCA9635_OK** if all is OK, and other error codes otherwise. + +| Error code | Value | Description | +|:----|:----:|:----| +| PCA9635_OK | 0x00 | Everything went well +| PCA9635_ERROR | 0xFF | Generic error +| PCA9635_ERR_WRITE | 0xFE | Tries to write more elements than PWM channels +| PCA9635_ERR_CHAN | 0xFD | Channel out of range +| PCA9635_ERR_MODE | 0xFC | Invalid mode +| PCA9635_ERR_REG | 0xFB | Invalid register +| PCA9635_ERR_I2C | 0xFA | PCA9635 I2C communication error + + +# Operation + +See examples diff --git a/libraries/PCA9635/examples/PCA9635_test01/PCA9635_test01.ino b/libraries/PCA9635/examples/PCA9635_test01/PCA9635_test01.ino index 5544e8b9..1dfd154f 100644 --- a/libraries/PCA9635/examples/PCA9635_test01/PCA9635_test01.ino +++ b/libraries/PCA9635/examples/PCA9635_test01/PCA9635_test01.ino @@ -2,7 +2,7 @@ // FILE: PCA9635_test01.ino // AUTHOR: Rob Tillaart // DATE: 23-APR-2016 -// VERSION: 0.1.01 +// VERSION: 0.2.0 // PUPROSE: test PCA9635 library // @@ -13,192 +13,199 @@ PCA9635 ledArray(0x20); void setup() { - Serial.begin(115200); - Serial.print("PCA9635 LIB version: "); - Serial.println(PCA9635_LIB_VERSION); - Serial.println(); + Serial.begin(115200); + Serial.print("PCA9635 LIB version: "); + Serial.println(PCA9635_LIB_VERSION); + Serial.println(); - testSetLedDriverModeLEDON(); - testPWMMode(); - testWrite1(); - testWrite3(); - testWriteN(); - testSetGroupPWM_FREQ(); - testSetAndReadMode(); - testSetLedDriverModeLEDOFF(); + ledArray.begin(); - Serial.print(millis()); - Serial.print("\t"); - Serial.println("done..."); + testSetLedDriverModeLEDON(); + testPWMMode(); + testWrite1(); + testWrite3(); + testWriteN(); + testSetGroupPWM_FREQ(); + testSetAndReadMode(); + testSetLedDriverModeLEDOFF(); + + Serial.print(millis()); + Serial.print("\t"); + Serial.println("done..."); } void testSetLedDriverModeLEDON() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - Switch all on"); - for (int channel = 0; channel < 16; channel++) + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - Switch all on"); + for (int channel = 0; channel < 16; channel++) + { + ledArray.setLedDriverMode(channel, PCA9635_LEDON); + if (ledArray.getLedDriverMode(channel) != PCA9635_LEDON) { - ledArray.setLedDriverMode(channel, PCA9635_LEDON); - if (ledArray.getLedDriverMode(channel) != PCA9635_LEDON) - { - Serial.print(millis()); - Serial.print("\t"); - Serial.print("Channel: "); - Serial.println(channel); - } + Serial.print(millis()); + Serial.print("\t"); + Serial.print("Channel: "); + Serial.println(channel); } + } } void testPWMMode() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - set pwm mode"); - for (int channel = 0; channel < 16; channel++) + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - set pwm mode"); + for (int channel = 0; channel < 16; channel++) + { + ledArray.setLedDriverMode(channel, PCA9635_LEDON); + delay(200); + ledArray.setLedDriverMode(channel, PCA9635_LEDPWM); + if (ledArray.getLedDriverMode(channel) != PCA9635_LEDPWM) { - ledArray.setLedDriverMode(channel, PCA9635_LEDON); - delay(200); - ledArray.setLedDriverMode(channel, PCA9635_LEDPWM); - if (ledArray.getLedDriverMode(channel) != PCA9635_LEDPWM) - { - Serial.print(millis()); - Serial.print("\t"); - Serial.print("Channel: "); - Serial.println(channel); - } + Serial.print(millis()); + Serial.print("\t"); + Serial.print("Channel: "); + Serial.println(channel); } + } } void testWrite1() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - write1 - I"); - for (int channel = 0; channel < 16; channel++) - { - for (int pwm = 0; pwm < 256; pwm++) - { - ledArray.write1(channel, pwm); - } - } - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - write 1 - II"); + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - write1 - I"); + for (int channel = 0; channel < 16; channel++) + { for (int pwm = 0; pwm < 256; pwm++) { - for (int channel = 0; channel < 16; channel++) - { - ledArray.write1(channel, pwm); - } + ledArray.write1(channel, pwm); } + } + + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - write 1 - II"); + for (int pwm = 0; pwm < 256; pwm++) + { + for (int channel = 0; channel < 16; channel++) + { + ledArray.write1(channel, pwm); + } + } } void testWrite3() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - write3 - random RGB"); - for (int channel = 0; channel < 13; channel++) // 13 = 16 -3 !!! - { - uint8_t R = random(256); - uint8_t G = random(256); - uint8_t B = random(256); - ledArray.write3(channel, R, G, B); - } + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - write3 - random RGB"); + for (int channel = 0; channel < 13; channel++) // 13 = 16 -3 !!! + { + uint8_t R = random(256); + uint8_t G = random(256); + uint8_t B = random(256); + ledArray.write3(channel, R, G, B); + } } void testWriteN() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - writeN "); - uint8_t arr[16] = {16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,255}; - ledArray.writeN(0, arr, 16); + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - writeN "); + uint8_t arr[16] = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 255}; + ledArray.writeN(0, arr, 16); } void testSetGroupPWM_FREQ() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - GroupPWM"); - for (int channel = 0; channel < 16; channel++) + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - GroupPWM"); + for (int channel = 0; channel < 16; channel++) + { + ledArray.setLedDriverMode(channel, PCA9635_LEDGRPPWM); + } + for (int pwm = 0; pwm < 256; pwm++) + { + ledArray.setGroupPWM(pwm); + uint8_t p = ledArray.getGroupPWM(); + if (p != pwm) { - ledArray.setLedDriverMode(channel, PCA9635_LEDGRPPWM); + Serial.print(millis()); + Serial.print("\t"); + Serial.print("pwm: "); + Serial.println(pwm); } - for (int pwm = 0; pwm < 256; pwm++) - { - ledArray.setGroupPWM(pwm); - uint8_t p = ledArray.getGroupPWM(); - if (p != pwm) - { - Serial.print(millis()); - Serial.print("\t"); - Serial.print("pwm: "); - Serial.println(pwm); - } - } - ledArray.setGroupPWM(127); + } + ledArray.setGroupPWM(127); - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - groupFRQ"); - for (int frq = 0; frq < 256; frq++) + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - groupFRQ"); + for (int frq = 0; frq < 256; frq++) + { + ledArray.setGroupFREQ(frq); + uint8_t f = ledArray.getGroupFREQ(); + if (f != frq) { - ledArray.setGroupFREQ(frq); - uint8_t f = ledArray.getGroupFREQ(); - if (f != frq) - { - Serial.print(millis()); - Serial.print("\t"); - Serial.print("frq: "); - Serial.println(frq); - } - } - for (int channel = 0; channel < 16; channel++) - { - ledArray.setLedDriverMode(channel, PCA9635_LEDPWM); + Serial.print(millis()); + Serial.print("\t"); + Serial.print("frq: "); + Serial.println(frq); } + } + + // reset to LEDPWM + for (int channel = 0; channel < 16; channel++) + { + ledArray.setLedDriverMode(channel, PCA9635_LEDPWM); + } } void testSetAndReadMode() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - readMode"); - uint8_t regval = ledArray.readMode(PCA9635_MODE1); - ledArray.writeMode(PCA9635_MODE1, regval); // non destructive; - Serial.print(millis()); - Serial.print("\t"); - Serial.print("PCA9635_MODE1: "); - Serial.println(regval); - regval = ledArray.readMode(PCA9635_MODE2); - ledArray.writeMode(PCA9635_MODE2, regval); - Serial.print(millis()); - Serial.print("\t"); - Serial.print("PCA9635_MODE2: "); - Serial.println(regval); + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - readMode"); + uint8_t regval = ledArray.readMode(PCA9635_MODE1); + ledArray.writeMode(PCA9635_MODE1, regval); // non destructive; + Serial.print(millis()); + Serial.print("\t"); + Serial.print("PCA9635_MODE1: "); + Serial.println(regval); + regval = ledArray.readMode(PCA9635_MODE2); + ledArray.writeMode(PCA9635_MODE2, regval); + Serial.print(millis()); + Serial.print("\t"); + Serial.print("PCA9635_MODE2: "); + Serial.println(regval); } void testSetLedDriverModeLEDOFF() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - Switch all off"); - for (int channel = 0; channel < 16; channel++) + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - Switch all off"); + for (int channel = 0; channel < 16; channel++) + { + ledArray.setLedDriverMode(channel, PCA9635_LEDOFF); + if (ledArray.getLedDriverMode(channel) != PCA9635_LEDOFF) { - ledArray.setLedDriverMode(channel, PCA9635_LEDOFF); - if (ledArray.getLedDriverMode(channel) != PCA9635_LEDOFF) - { - Serial.print(millis()); - Serial.print("\t"); - Serial.print("Channel: "); - Serial.println(channel); - } + Serial.print(millis()); + Serial.print("\t"); + Serial.print("Channel: "); + Serial.println(channel); } + } } void loop() { } + +// -- END OF FILE -- diff --git a/libraries/PCA9635/examples/PCA9635_test_multiple/PCA9635_test_multiple.ino b/libraries/PCA9635/examples/PCA9635_test_multiple/PCA9635_test_multiple.ino new file mode 100644 index 00000000..48c486e5 --- /dev/null +++ b/libraries/PCA9635/examples/PCA9635_test_multiple/PCA9635_test_multiple.ino @@ -0,0 +1,56 @@ +// +// FILE: PCA9635_test_multiple.ino +// AUTHOR: Rob Tillaart +// DATE: 2018-02-18 +// VERSION: 0.2.0 +// PUPROSE: test PCA9635 library +// + +#include "PCA9635.h" +#include + +PCA9635 ledArray(0x20); +PCA9635 ledArray2(0x21); + +void setup() +{ + Serial.begin(115200); + Serial.print("PCA9635 LIB version: "); + Serial.println(PCA9635_LIB_VERSION); + Serial.println(); + + ledArray.begin(); + ledArray2.begin(); + + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - write1 - I"); + for (int channel = 0; channel < 16; channel++) + { + for (int pwm = 0; pwm < 256; pwm++) + { + ledArray.write1(channel, pwm); + ledArray2.write1(channel, pwm); + } + } + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - write 1 - II"); + for (int pwm = 0; pwm < 256; pwm++) + { + for (int channel = 0; channel < 16; channel++) + { + ledArray.write1(channel, pwm); + ledArray2.write1(channel, pwm); + } + } + + Serial.println("done..."); +} + +void loop() +{ + +} + +// -- END OF FILE -- diff --git a/libraries/PCA9635/library.json b/libraries/PCA9635/library.json index 8a15fd64..f5b491d2 100644 --- a/libraries/PCA9635/library.json +++ b/libraries/PCA9635/library.json @@ -1,7 +1,7 @@ { "name": "PCA9635", "keywords": "I2C,PCA9635,PWM", - "description": "Library for PCA9635 PWM.", + "description": "Arduino library for PCA9635 I2C LED driver", "authors": [ { @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PCA9635.git" }, - "version":"0.1.2", + "version":"0.2.0", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/PCA9635" - } + "platforms": "*" } diff --git a/libraries/PCA9635/library.properties b/libraries/PCA9635/library.properties index 648e3347..b3450b02 100644 --- a/libraries/PCA9635/library.properties +++ b/libraries/PCA9635/library.properties @@ -1,9 +1,11 @@ name=PCA9635 -version=0.1.2 +version=0.2.0 author=Rob Tillaart maintainer=Rob Tillaart -sentence=Library for PCA9635 PWM. -paragraph= +sentence=Arduino library for PCA9635 I2C LED driver +paragraph=PWM, 8 bit category=Signal Input/Output -url=https://github.com/RobTillaart/Arduino/tree/master/libraries/ -architectures=* \ No newline at end of file +url=https://github.com/RobTillaart/PCA9635 +architectures=* +includes=PCA9635.h +depends= diff --git a/libraries/PCA9685/LICENSE b/libraries/PCA9685/LICENSE new file mode 100644 index 00000000..9aa72bbc --- /dev/null +++ b/libraries/PCA9685/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/PCA9685/PCA9685.cpp b/libraries/PCA9685/PCA9685.cpp index d228176c..8563ec67 100644 --- a/libraries/PCA9685/PCA9685.cpp +++ b/libraries/PCA9685/PCA9685.cpp @@ -2,20 +2,24 @@ // FILE: PCA9685.cpp // AUTHOR: Rob Tillaart // DATE: 24-apr-2016 -// VERSION: 0.1.1 -// PURPOSE: I2C PCA9685 library for Arduino -// URL: +// VERSION: 0.3.0 +// PURPOSE: Arduino library for I2C PCA9685 16 channel PWM +// URL: https://github.com/RobTillaart/PCA9685_RT // // HISTORY: // 0.1.0 2016-04-24 initial BETA version // 0.1.1 2019-01-30 testing && fixing -// +// 0.2.0 2020-05-25 refactor; ESP32 begin(sda,scl) +// 0.2.1 2020-06-19 fix library.json +// 0.2.2 2020-09-21 fix #1 + add getFrequency() +// 0.2.3 2020-11-21 fix digitalWrite (internal version only) +// 0.3.0 2020-11-22 fix setting frequency + -#include #include "PCA9685.h" -// check datasheet for details +// REGISTERS CONFIGURATION - check datasheet for details #define PCA9685_MODE1 0x00 #define PCA9685_MODE2 0x01 @@ -35,18 +39,30 @@ #define PCA9685_OUTDRV 0x04 #define PCA9685_OUTNE 0x03 -// SPECIAL REGISTER - FREQUENCY -#define PCA9685_PRE_SCALE 0xFE +// REGISTERS - CHANNELS +#define PCA9685_CHANNEL_0 0x06 // 0x06 + 4*channel is base per channel +// REGISTERS - FREQUENCY +#define PCA9685_PRE_SCALER 0xFE -// NOT IMPLEMENTED YET +// REGISTERS - Subaddressing I2C - not implemented #define PCA9685_SUBADR(x) (0x01+(x)) // x = 1..3 #define PCA9685_ALLCALLADR 0x05 -#define PCA9685_TESTMODE 0xFF + +// REGISTERS - ALL_ON ALL_OFF - partly implemented +#define PCA9685_ALL_ON_L 0xFA +#define PCA9685_ALL_ON_H 0xFB +#define PCA9685_ALL_OFF_L 0xFC +#define PCA9685_ALL_OFF_H 0xFD // used for allOFF() + +// NOT IMPLEMENTED YET +#define PCA9685_TESTMODE 0xFF // do not be use. see datasheet. + ////////////////////////////////////////////////////////////// - - +// +// Constructor +// PCA9685::PCA9685(const uint8_t deviceAddress) { _address = deviceAddress; @@ -54,20 +70,31 @@ PCA9685::PCA9685(const uint8_t deviceAddress) } +#if defined (ESP8266) || defined(ESP32) +void PCA9685::begin(uint8_t sda, uint8_t scl) +{ + Wire.begin(sda, scl); + reset(); +} +#endif + void PCA9685::begin() { Wire.begin(); + reset(); +} + +void PCA9685::reset() +{ _error = 0; - uint8_t mode1 = PCA9685_AUTOINCR | PCA9685_ALLCALL; - writeReg(PCA9685_MODE1, mode1); - uint8_t mode2 = PCA9685_OUTDRV; - writeReg(PCA9685_MODE2, mode2); + writeMode(PCA9685_MODE1, PCA9685_AUTOINCR | PCA9685_ALLCALL); + writeMode(PCA9685_MODE2, PCA9685_OUTDRV); } void PCA9685::writeMode(uint8_t reg, uint8_t value) { - if (reg != PCA9685_MODE1 && reg != PCA9685_MODE2) + if ((reg != PCA9685_MODE1) && (reg != PCA9685_MODE2)) { _error = PCA9685_ERR_MODE; return; @@ -78,7 +105,7 @@ void PCA9685::writeMode(uint8_t reg, uint8_t value) uint8_t PCA9685::readMode(uint8_t reg) { - if (reg != PCA9685_MODE1 && reg != PCA9685_MODE2) + if ((reg != PCA9685_MODE1) && (reg != PCA9685_MODE2)) { _error = PCA9685_ERR_MODE; return 0; @@ -87,6 +114,7 @@ uint8_t PCA9685::readMode(uint8_t reg) return value; } + // write value to single PWM channel void PCA9685::setPWM(uint8_t channel, uint16_t onTime, uint16_t offTime) { @@ -95,16 +123,19 @@ void PCA9685::setPWM(uint8_t channel, uint16_t onTime, uint16_t offTime) _error = PCA9685_ERR_CHANNEL; return; } - uint8_t reg = 0x06 + (channel << 2); + offTime &= 0x0FFFF; // non-doc feature - to easy set figure 8 P.17 + uint8_t reg = PCA9685_CHANNEL_0 + (channel << 2); writeReg2(reg, onTime, offTime); } + // write value to single PWM channel void PCA9685::setPWM(uint8_t channel, uint16_t offTime) { setPWM(channel, 0, offTime); } + // read value from single PWM channel void PCA9685::getPWM(uint8_t channel, uint16_t* onTime, uint16_t* offTime) { @@ -113,13 +144,13 @@ void PCA9685::getPWM(uint8_t channel, uint16_t* onTime, uint16_t* offTime) _error = PCA9685_ERR_CHANNEL; return; } - uint8_t reg = 0x06 + (channel << 2); + uint8_t reg = PCA9685_CHANNEL_0 + (channel << 2); Wire.beginTransmission(_address); Wire.write(reg); _error = Wire.endTransmission(); if (Wire.requestFrom(_address, (uint8_t)4) != 4) { - _error = PCA9685_ERROR; + _error = PCA9685_ERR_I2C; return; } uint16_t _data = Wire.read(); @@ -128,25 +159,54 @@ void PCA9685::getPWM(uint8_t channel, uint16_t* onTime, uint16_t* offTime) *offTime = (Wire.read() * 256) + _data; } + // set update frequency for all channels -void PCA9685::setFrequency(uint16_t freq) +void PCA9685::setFrequency(uint16_t freq, int offset) { - if (freq < 24) freq = 24; - if (freq > 1526) freq = 1526; + _freq = freq; + if (_freq < 24) _freq = 24; // page 25 datasheet + if (_freq > 1526) _freq = 1526; // removed float operation for speed - // uint8_t scaler = round(25e6 / (4096 * freq)) - 1; - uint8_t scaler = 6104 / freq - 1; - writeReg(PCA9685_PRE_SCALE, scaler); + // faster but equal accurate + // uint8_t scaler = round(25e6 / (_freq * 4096)) - 1; + uint8_t scaler = 48828 / (_freq * 8) - 1; + + uint8_t mode1 = readMode(PCA9685_MODE1); + writeMode(PCA9685_MODE1, mode1 | PCA9685_SLEEP); + scaler += offset; + writeReg(PCA9685_PRE_SCALER, scaler); + writeMode(PCA9685_MODE1, mode1); } -void PCA9685::setON(uint8_t channel) +int PCA9685::getFrequency(bool cache) { - setPWM(channel, 0x1000, 0x0000); + if (cache) return _freq; + uint8_t scaler = readReg(PCA9685_PRE_SCALER); + scaler++; + _freq = 48828 / scaler; + _freq /= 8; + return _freq; } -void PCA9685::setOFF(uint8_t channel) + +// datasheet P.18 - fig. 9: +// Note: bit[11-0] ON should NOT equal timer OFF in ON mode +// in OFF mode it doesn't matter. +void PCA9685::digitalWrite(uint8_t channel, uint8_t mode) { - setPWM(channel, 0x0000, 0x1000); + if (channel > 15) + { + _error = PCA9685_ERR_CHANNEL; + return; + } + uint8_t reg = PCA9685_CHANNEL_0 + (channel << 2); + if (mode != LOW) writeReg2(reg, 0x1000, 0x0000); + else writeReg2(reg, 0x0000, 0x0000); +} + +void PCA9685::allOFF() +{ + writeReg(PCA9685_ALL_OFF_H, 0x10); } int PCA9685::lastError() @@ -156,6 +216,10 @@ int PCA9685::lastError() return e; } +////////////////////////////////////////////////////////////// +// +// PRIVATE +// void PCA9685::writeReg(uint8_t reg, uint8_t value) { Wire.beginTransmission(_address); @@ -164,18 +228,19 @@ void PCA9685::writeReg(uint8_t reg, uint8_t value) _error = Wire.endTransmission(); } + void PCA9685::writeReg2(uint8_t reg, uint16_t a, uint16_t b) { Wire.beginTransmission(_address); Wire.write(reg); Wire.write(a & 0xFF); - Wire.write((a >> 8) & 0x0F); + Wire.write((a >> 8) & 0x1F); Wire.write(b & 0xFF); - Wire.write((b >> 8) & 0x0F); + Wire.write((b >> 8) & 0x1F); _error = Wire.endTransmission(); } -// + uint8_t PCA9685::readReg(uint8_t reg) { Wire.beginTransmission(_address); @@ -183,13 +248,11 @@ uint8_t PCA9685::readReg(uint8_t reg) _error = Wire.endTransmission(); if (Wire.requestFrom(_address, (uint8_t)1) != 1) { - _error = PCA9685_ERROR; + _error = PCA9685_ERR_I2C; return 0; } uint8_t _data = Wire.read(); return _data; } -// -// END OF FILE -// \ No newline at end of file +// -- END OF FILE -- diff --git a/libraries/PCA9685/PCA9685.h b/libraries/PCA9685/PCA9685.h index b92efbe0..5e189bc2 100644 --- a/libraries/PCA9685/PCA9685.h +++ b/libraries/PCA9685/PCA9685.h @@ -1,27 +1,27 @@ +#pragma once // // FILE: PCA9685.H // AUTHOR: Rob Tillaart // DATE: 24-apr-2016 -// VERSION: 0.1.1 -// PURPOSE: I2C PCA9685 library for Arduino -// URL: https://github.com/RobTillaart/Arduino/tree/master/libraries +// VERSION: 0.3.0 +// PURPOSE: Arduino library for I2C PCA9685 16 channel PWM +// URL: https://github.com/RobTillaart/PCA9685_RT // // HISTORY: // see PCA9685.cpp file // -#ifndef _PCA9685_H -#define _PCA9685_H - #include "Arduino.h" +#include "Wire.h" -#define PCA9685_LIB_VERSION "0.1.1" +#define PCA9685_LIB_VERSION "0.3.0" // ERROR CODES #define PCA9685_OK 0x00 #define PCA9685_ERROR 0xFF #define PCA9685_ERR_CHANNEL 0xFE #define PCA9685_ERR_MODE 0xFD +#define PCA9685_ERR_I2C 0xFC class PCA9685 @@ -29,41 +29,54 @@ class PCA9685 public: explicit PCA9685(const uint8_t deviceAddress); - void begin(); +#if defined (ESP8266) || defined(ESP32) + void begin(uint8_t sda, uint8_t scl); +#endif + void begin(); + void reset(); // reg = 1, 2 check datasheet for values - void writeMode(uint8_t reg, uint8_t value); + void writeMode(uint8_t reg, uint8_t value); uint8_t readMode(uint8_t reg); // single PWM setting, channel = 0..15, // onTime = 0..4095, offTime = 0..4095 // allows shifted PWM's e.g. 2 servo's that do not start at same time. - void setPWM(uint8_t channel, uint16_t onTime, uint16_t offTime); - void getPWM(uint8_t channel, uint16_t* onTime, uint16_t* offTime); + void setPWM(uint8_t channel, uint16_t onTime, uint16_t offTime); + void getPWM(uint8_t channel, uint16_t* onTime, uint16_t* offTime); - // single PWM setting, channel = 0..15, offTime = 0..4095 - void setPWM(uint8_t channel, uint16_t offTime); + // single PWM setting, channel = 0..15, offTime = 0..4095 (onTime = 0) + void setPWM(uint8_t channel, uint16_t offTime); // set update frequency for all channels - // freq = 24-1526 Hz - void setFrequency(uint16_t freq); + // freq = 24 - 1526 Hz + // note: as the frequency is converted to an 8 bit prescaler + // the frequency set will seldom be exact, but best effort. + void setFrequency(uint16_t freq, int offset = 0); + int getFrequency(bool cache = true); - void setON(uint8_t channel); - void setOFF(uint8_t channel); + // set channel HIGH or LOW (effectively no PWM) + void digitalWrite(uint8_t channel, uint8_t mode); - int lastError(); + // for backwards compatibility; will be removed in future + void setON(uint8_t channel) { digitalWrite(channel, HIGH); }; + void setOFF(uint8_t channel) { digitalWrite(channel, LOW); }; + + // experimental for 0.3.0 + void allOFF(); + + int lastError(); private: + // DIRECT CONTROL - void writeReg(uint8_t reg, uint8_t value); - void writeReg2(uint8_t reg, uint16_t a, uint16_t b); + void writeReg(uint8_t reg, uint8_t value); + void writeReg2(uint8_t reg, uint16_t a, uint16_t b); uint8_t readReg(uint8_t reg); uint8_t _address; int _error; + int _freq = 200; // default PWM frequency - P25 datasheet }; -#endif -// -// END OF FILE -// \ No newline at end of file +// -- END OF FILE -- diff --git a/libraries/PCA9685/README.md b/libraries/PCA9685/README.md new file mode 100644 index 00000000..d9867bb8 --- /dev/null +++ b/libraries/PCA9685/README.md @@ -0,0 +1,89 @@ +# PCA9685_RT + +Arduino library for I2C PCA9685 16 channel PWM extender + +# Description + +This library is to control the I2C PCA9685 PWM extender. +The 16 channels are independently configurable in steps of 1/4096. +This allows for better than 0.1% finetuning of the duty-cycle +of the PWM signal. + +The PWM's of the different channels have individual start and stop moments. +This can be used to distribute the power more evenly over multiple servo's +or give special effects when used in an RGB LED. + +The frequency of the PWM can be set from 24 to 1526 according to the datasheet, however in practice not all frequencies are set accurate. +Lower frequencies do better than higher frequencies. + + +### interface + +**begin()** initializes the library after startup. Mandatory. + +**begin(sda, scl)** idem, ESP32 ESP8266 only. Library does not support +multiple Wire instances (yet). + +**reset()** resets the library to start up conditions. + +**writeMode(reg, mode)** configuration of one of the two configuration registers. +check datasheet for details. + +**readMode(reg)** reads back the configured mode, useful to add or remove a +single flag (bit masking) + +**setPWM(channel, ontime, offtime)** The chip has 16 channels to do PWM. +The signal is divided in 4096 steps, 0..4095. +The pulse can begin =**ontime** on any step and it can stop on any step =**offtime**. +This allows e.g. to distribute the power over the 16 channels, e.g. the +channels do not need to start at the same moment with HIGH. + +**setPWM(channel, offtime)** simple PWM that always start on **ontime = 0** + +**getPWM(channel, ontime, offtime)** read back the configuration of the channel. + +**setFrequency(freq, int offset = 0)** set the update speed of the channels. +This value is set the same for all channels at once. +The frequency is constrained to be between 24 and 1526 Hz. +As the frequency is converted to an 8 bit **prescaler**, +the frequency set will seldom be exact. +After changing the frequency, one must set all channels (again), +so one should set the frequency in **setup()** + +The parameter offset can be used to tune the **prescaler** to get a frequency +closer to the requested value. See **PCA9685_setFrequency_offset** example. +Default the offset = 0. As the prescaler is smaller at higher frequencies +higher frequencies are less accurate. +Making offset too large can result in very incorrect frequencies. + +When using offset, the **getFrequency(false)** will return the adjusted prescaler. + +**getFrequency(cache = true)** get the current update frequency of the channels. +This is same for all channels. If cache is false, the frequency is fetched and +calculated from the **prescaler** register and will probably differ from the +value set with **setFrequency()**. + +**digitalWrite(channel, mode)** mode = HIGH or LOW, just use the PCA9685 as +a digitalpin. +This single function replaces the setON() and setOFF() that will become +obsolete in the future. + +**allOFF()** switches all PWM channels OFF. **Experimental** in 0.3.0 +To "undo" the allOFF one can call the **reset()** function and set all +PWM channels again. + +**lastError()** returns **PCA9685_OK = 0** if all is OK, and + +| Error code | Value | Description | +|:----|:----:|:----| +| PCA9685_OK | 0x00 | Everything went well +| PCA9685_ERROR | 0xFF | generic error +| PCA9685_ERR_CHANNEL | 0xFE | Channel out of range +| PCA9685_ERR_MODE | 0xFD | Invalid mode register chosen | +| PCA9685_ERR_I2C | 0xFC | PCA9685 I2C communication error + + + +# Operation + +See examples diff --git a/libraries/PCA9685/examples/PCA9685_allOFF_test/PCA9685_allOFF_test.ino b/libraries/PCA9685/examples/PCA9685_allOFF_test/PCA9685_allOFF_test.ino new file mode 100644 index 00000000..73abfa07 --- /dev/null +++ b/libraries/PCA9685/examples/PCA9685_allOFF_test/PCA9685_allOFF_test.ino @@ -0,0 +1,53 @@ +// +// FILE: PCA9685_allOFF_test.ino +// AUTHOR: Rob Tillaart +// DATE: 2020-11-22 +// VERSION: 0.1.0 +// PUPROSE: test PCA9685 library +// + +/* + sets all channels to a PWM + then switches them all off + you can check it by testing all channels. +*/ + +#include "PCA9685.h" + +PCA9685 PCA(0x40); + +const uint8_t PIN = 2; + +void setup() +{ + Wire.begin(); + PCA.begin(); + + Serial.begin(115200); + Serial.print("PCA9685 LIB version: "); + Serial.println(PCA9685_LIB_VERSION); + Serial.println(); + + pinMode(PIN, INPUT_PULLUP); + for (int channel = 0; channel < 16; channel++) + { + PCA.setPWM(channel, 0, 1000); + } + delay(100); // to be sure they started. + PCA.allOFF(); + + // delay(100); + // PCA.reset(); // needed to reset the allOFF() + // for (int channel = 0; channel < 16; channel++) + // { + // PCA.digitalWrite(channel, HIGH); + // } +} + + +void loop() +{ + Serial.println(digitalRead(PIN)); // you can measure all pins +} + +// -- END OF FILE -- diff --git a/libraries/PCA9685/examples/PCA9685_digitalWrite_test/PCA9685_digitalWrite_test.ino b/libraries/PCA9685/examples/PCA9685_digitalWrite_test/PCA9685_digitalWrite_test.ino new file mode 100644 index 00000000..1f01b247 --- /dev/null +++ b/libraries/PCA9685/examples/PCA9685_digitalWrite_test/PCA9685_digitalWrite_test.ino @@ -0,0 +1,66 @@ +// +// FILE: PCA9685_digitalWrite_test.ino +// AUTHOR: Rob Tillaart +// DATE: 2020-11-21 +// VERSION: 0.1.0 +// PUPROSE: test PCA9685 library +// + +/* + sets one channel to max PWM 0..4095 + and connect the output to an interrupt pin 2 + to see the frequency of the PWM +*/ + +#include "PCA9685.h" + +PCA9685 PCA(0x40); + +const uint8_t IRQ_PIN = 2; +volatile uint16_t count = 0; +uint32_t lastTime = 0; + +void setup() +{ + Wire.begin(); + PCA.begin(); + + Serial.begin(115200); + Serial.print("PCA9685 LIB version: "); + Serial.println(PCA9685_LIB_VERSION); + Serial.println(); + + pinMode(IRQ_PIN, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(IRQ_PIN), irq, CHANGE); + + // PCA.setPWM(15, 0, 1000); // works OK - reference to test irq() + // PCA.digitalWrite(15, LOW); // works OK + PCA.digitalWrite(15, HIGH); // works OK +} + + +// INTERRUPT ROUTINE TO COUNT THE PULSES +void irq() +{ + count++; +} + + +void loop() +{ + uint32_t now = millis(); + if (now - lastTime >= 1000) + { + lastTime = now; + // make a copy + noInterrupts(); + uint16_t t = count; + count = 0; + interrupts(); + + Serial.print(t); + Serial.print("\t"); + Serial.println(digitalRead(IRQ_PIN)); + } +} +// -- END OF FILE -- diff --git a/libraries/PCA9685/examples/PCA9685_maxPWM_test/PCA9685_maxPWM_test.ino b/libraries/PCA9685/examples/PCA9685_maxPWM_test/PCA9685_maxPWM_test.ino new file mode 100644 index 00000000..8d29d540 --- /dev/null +++ b/libraries/PCA9685/examples/PCA9685_maxPWM_test/PCA9685_maxPWM_test.ino @@ -0,0 +1,70 @@ +// +// FILE: PCA9685_maxPWM_test.ino +// AUTHOR: Rob Tillaart +// DATE: 2020-11-22 +// VERSION: 0.1.0 +// PUPROSE: test PCA9685 library +// + +/* + sets one channel to max PWM 0..4095 + and connect the output to an interrupt pin 2 + to see the frequency of the PWM +*/ + +#include "PCA9685.h" + +PCA9685 PCA(0x40); + +const uint8_t IRQ_PIN = 2; +volatile uint16_t count = 0; +uint32_t lastTime = 0; + +void setup() +{ + Wire.begin(); + PCA.begin(); + + Serial.begin(115200); + Serial.print("PCA9685 LIB version: "); + Serial.println(PCA9685_LIB_VERSION); + Serial.println(); + + pinMode(IRQ_PIN, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(IRQ_PIN), irq, RISING); // CHANGE + + Serial.println(PCA.getFrequency()); + PCA.setFrequency(200); + Serial.println(PCA.lastError()); + Serial.println(PCA.getFrequency(false)); // do not fetch from cache. + + PCA.setPWM(15, 0, 4095); // gives 2 changes per interval +} + + +// INTERRUPT ROUTINE TO COUNT THE PULSES +void irq() +{ + count++; +} + + +void loop() +{ + uint32_t now = millis(); + if (now - lastTime >= 1000) + { + lastTime += 1000; + // make a working copy of count + noInterrupts(); + uint16_t t = count; + count = 0; + interrupts(); + + Serial.print(t); + Serial.print("\t"); + Serial.println(digitalRead(IRQ_PIN)); + } +} + +// -- END OF FILE -- diff --git a/libraries/PCA9685/examples/PCA9685_setFrequency_offset/PCA9685_setFrequency_offset.ino b/libraries/PCA9685/examples/PCA9685_setFrequency_offset/PCA9685_setFrequency_offset.ino new file mode 100644 index 00000000..66b55c01 --- /dev/null +++ b/libraries/PCA9685/examples/PCA9685_setFrequency_offset/PCA9685_setFrequency_offset.ino @@ -0,0 +1,101 @@ +// +// FILE: PCA9685_setFrequency_offset.ino +// AUTHOR: Rob Tillaart +// DATE: 2020-11-22 +// VERSION: 0.1.0 +// PUPROSE: test PCA9685 library +// + +/* + This sketch is to determine the offset needed to get te best matching + value for offset to match the wanted frequency. + + connect PWM line 15 to IRQ line 2 to monitor the real frequency + set the frequency to the value you want. + use the + and - keys to adjust the frequency to get the wanted frequency. + + Note: the higher the frequency, the more inaccurate the real frequency, + +*/ + +#include "PCA9685.h" + +PCA9685 PCA(0x40); + +const uint8_t IRQ_PIN = 2; +volatile uint16_t count = 0; +uint32_t lastTime = 0; + + +uint16_t freq = 200; // adjust to freq needed (between 24..1526 ) +int offset = 0; +int lines = 0; + +void setup() +{ + Wire.begin(); + PCA.begin(); + + Serial.begin(115200); + Serial.print("PCA9685 LIB version: "); + Serial.println(PCA9685_LIB_VERSION); + Serial.println(); + + pinMode(IRQ_PIN, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(IRQ_PIN), irq, RISING); + + PCA.setFrequency(freq, offset); + PCA.setPWM(15, 0, 4095); // gives 2 changes per interval + + Serial.println("\nSET\tIRQ\tIRQ%\tOFFSET"); +} + + +// INTERRUPT ROUTINE TO COUNT THE PULSES +void irq() +{ + count++; +} + + +void loop() +{ + uint32_t now = millis(); + if (now - lastTime >= 1000) + { + lastTime += 1000; + // make a working copy of count + noInterrupts(); + uint16_t t = count; + count = 0; + interrupts(); + + Serial.print(freq); + Serial.print("\t"); + Serial.print(t); + Serial.print("\t"); + Serial.print(100.0 * t / freq, 1); + Serial.print("\t"); + Serial.print(offset); + Serial.print("\n"); + + lines++; + if (lines == 20) + { + Serial.println("\nSET\tIRQ\tIRQ%\tOFFSET"); + lines = 0; + } + } + + if (Serial.available()) + { + char c = Serial.read(); + if (c == '+') offset++; + if (c == '-') offset--; + PCA.setFrequency(freq, offset); + PCA.setPWM(15, 0, 4095); + } + +} + +// -- END OF FILE -- diff --git a/libraries/PCA9685/examples/PCA9685_setFrequency_test/PCA9685_setFrequency_test.ino b/libraries/PCA9685/examples/PCA9685_setFrequency_test/PCA9685_setFrequency_test.ino new file mode 100644 index 00000000..ed541276 --- /dev/null +++ b/libraries/PCA9685/examples/PCA9685_setFrequency_test/PCA9685_setFrequency_test.ino @@ -0,0 +1,92 @@ +// +// FILE: PCA9685_setFrequency_test.ino +// AUTHOR: Rob Tillaart +// DATE: 2020-11-22 +// VERSION: 0.1.0 +// PUPROSE: test PCA9685 library +// + +/* + sets one channel to max PWM 0..4095 + and connect the output to an interrupt pin 2 + to see the frequency of the PWM +*/ + +#include "PCA9685.h" + +PCA9685 PCA(0x40); + +const uint8_t IRQ_PIN = 2; +volatile uint16_t count = 0; +uint32_t lastTime = 0; +uint16_t freq = 24; + +uint8_t lines = 0; + +void setup() +{ + Wire.begin(); + PCA.begin(); + + Serial.begin(115200); + Serial.print("PCA9685 LIB version: "); + Serial.println(PCA9685_LIB_VERSION); + Serial.println(); + + pinMode(IRQ_PIN, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(IRQ_PIN), irq, RISING); // CHANGE + + PCA.setFrequency(24); + PCA.setPWM(15, 0, 4095); // gives 2 changes per interval + + Serial.println("\nSET\tGET\tGET%\tIRQ\tIRQ%"); +} + + +// INTERRUPT ROUTINE TO COUNT THE PULSES +void irq() +{ + count++; +} + + +void loop() +{ + + + uint32_t now = millis(); + if (now - lastTime >= 1000) + { + lastTime += 1000; + // make a working copy of count + noInterrupts(); + uint16_t t = count; + count = 0; + interrupts(); + + Serial.print(freq); + Serial.print("\t"); + Serial.print(PCA.getFrequency(false)); + Serial.print("\t"); + Serial.print(100.0 * PCA.getFrequency(false) / freq, 1); + Serial.print("\t"); + Serial.print(t); + Serial.print("\t"); + Serial.print(100.0 * t / freq, 1); + Serial.print("\n"); + + freq += 4; + if (freq >= 1526) freq = 24; + PCA.setFrequency(freq); + PCA.setPWM(15, 0, 4095); + + lines++; + if (lines == 20) + { + Serial.println("\nSET\tGET\tGET%\tIRQ\tIRQ%"); + lines = 0; + } + } +} + +// -- END OF FILE -- diff --git a/libraries/PCA9685/examples/PCA9685_test01/PCA9685_test01.ino b/libraries/PCA9685/examples/PCA9685_test01/PCA9685_test01.ino index 82260daf..08434ef9 100644 --- a/libraries/PCA9685/examples/PCA9685_test01/PCA9685_test01.ino +++ b/libraries/PCA9685/examples/PCA9685_test01/PCA9685_test01.ino @@ -2,7 +2,7 @@ // FILE: PCA9685_test01.ino // AUTHOR: Rob Tillaart // DATE: 24-APR-2016 -// VERSION: 0.1.00 +// VERSION: 0.1.1 // PUPROSE: test PCA9685 library // @@ -13,65 +13,67 @@ PCA9685 ledArray(0x20); void setup() { - Wire.begin(); - ledArray.begin(); + Wire.begin(); + ledArray.begin(); - Serial.begin(115200); - Serial.print("PCA9685 LIB version: "); - Serial.println(PCA9685_LIB_VERSION); - Serial.println(); + Serial.begin(115200); + Serial.print("PCA9685 LIB version: "); + Serial.println(PCA9685_LIB_VERSION); + Serial.println(); - testSetON(); - testPWMMode(); - delay(2000); - testSetOFF(); + testSetON(); + testPWMMode(); + delay(2000); + testSetOFF(); - Serial.print(millis()); - Serial.print("\t"); - Serial.println("done..."); + Serial.print(millis()); + Serial.print("\t"); + Serial.println("done..."); } void testSetON() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - setON"); - for (int channel = 0; channel < 16; channel++) - { - ledArray.setON(channel); - } + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - setHIGH"); + for (uint8_t channel = 0; channel < 16; channel++) + { + ledArray.digitalWrite(channel, HIGH); + } } void testSetOFF() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - setOFF"); - for (int channel = 0; channel < 16; channel++) - { - ledArray.setOFF(channel); - } + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - setLOW"); + for (uint8_t channel = 0; channel < 16; channel++) + { + ledArray.digitalWrite(channel, LOW); + } } void testPWMMode() { - Serial.print(millis()); - Serial.print("\t"); - Serial.println("Test - setPwm getPWM"); - for (int channel = 0; channel < 16; channel++) + Serial.print(millis()); + Serial.print("\t"); + Serial.println("Test - setPwm getPWM"); + for (uint16_t channel = 0; channel < 16; channel++) + { + // every next line ~twice as much time + ledArray.setPWM(channel, channel * 127, channel * 255); + uint16_t a, b; + ledArray.getPWM(channel, &a, &b); + if ((a != channel * 127) || (b != channel * 255)) { - // every next line ~twice as much time - ledArray.setPWM(channel, channel*127, channel*255); - uint16_t a, b; - ledArray.getPWM(channel, &a, &b); - if (a != channel*127 || b != channel*255) - { - Serial.println(channel); - } + Serial.println(channel); } + } } void loop() { } + +// -- END OF FILE -- diff --git a/libraries/PCA9685/examples/PCA9685_test02/PCA9685_test02.ino b/libraries/PCA9685/examples/PCA9685_test02/PCA9685_test02.ino index e8d0aac6..b2858140 100644 --- a/libraries/PCA9685/examples/PCA9685_test02/PCA9685_test02.ino +++ b/libraries/PCA9685/examples/PCA9685_test02/PCA9685_test02.ino @@ -2,12 +2,11 @@ // FILE: PCA9685_test02.ino // AUTHOR: Rob Tillaart // DATE: 24-APR-2016 -// VERSION: 0.1.0 +// VERSION: 0.1.2 // PUPROSE: test PCA9685 library // #include "PCA9685.h" -#include PCA9685 ledArray(0x40); @@ -22,12 +21,12 @@ void setup() Serial.println(PCA9685_LIB_VERSION); Serial.println(); - testSetON(); + testDigitalWrite(HIGH); testPWM(0); testPWMMode(); testFrequency(); delay(2000); - testSetOFF(); + testDigitalWrite(LOW); Serial.print(millis()); Serial.print("\t"); @@ -35,26 +34,14 @@ void setup() } -void testSetON() +void testDigitalWrite(uint8_t mode) { Serial.print(millis()); Serial.print("\t"); Serial.println(__FUNCTION__); for (int channel = 0; channel < 16; channel++) { - ledArray.setON(channel); - delay(100); - } -} - -void testSetOFF() -{ - Serial.print(millis()); - Serial.print("\t"); - Serial.println(__FUNCTION__); - for (int channel = 0; channel < 16; channel++) - { - ledArray.setOFF(channel); + ledArray.digitalWrite(channel, mode); delay(100); } } @@ -105,13 +92,24 @@ void testFrequency() Serial.println(__FUNCTION__); ledArray.setPWM(0, 1000, 3000); - for (uint16_t freq = 24; freq < 2000; freq *= 2) + for (uint16_t freq = 12; freq < 2000; freq *= 2) { - Serial.println(freq); + Serial.print(freq); ledArray.setFrequency(freq); + // if freq is out of range => report + if (ledArray.getFrequency() != freq) + { + Serial.print("\tconstrained to : "); + Serial.println(ledArray.getFrequency()); + } + else + { + Serial.println("\tOK"); + } delay(2000); } ledArray.setOFF(0); + Serial.println(); } @@ -119,3 +117,5 @@ void loop() { //testPWM(0); } + +// -- END OF FILE -- diff --git a/libraries/PCA9685/library.json b/libraries/PCA9685/library.json index 9e5ddaa8..27276b9c 100644 --- a/libraries/PCA9685/library.json +++ b/libraries/PCA9685/library.json @@ -1,7 +1,7 @@ { "name": "PCA9685", - "keywords": "I2C,PCA9685,PWM", - "description": "Library for PCA9685.", + "keywords": "I2C,PCA9685,PWM,16channel", + "description": "Arduino library for I2C PCA9685 16 channel PWM", "authors": [ { @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PCA9685_RT.git" }, - "version":"0.1.1", + "version": "0.3.0", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/PCA9685" - } + "platforms": "*" } diff --git a/libraries/PCA9685/library.properties b/libraries/PCA9685/library.properties index 72083d08..47a9c1ae 100644 --- a/libraries/PCA9685/library.properties +++ b/libraries/PCA9685/library.properties @@ -1,9 +1,11 @@ -name=PCA9685 -version=0.1.1 +name=PCA9685_RT +version=0.3.0 author=Rob Tillaart maintainer=Rob Tillaart -sentence=Library for PCA9685 PWM +sentence=Arduino library for I2C PCA9685 16 channel PWM paragraph= category=Signal Input/Output -url=https://github.com/RobTillaart/Arduino/tree/master/libraries/ -architectures=* \ No newline at end of file +url=https://github.com/RobTillaart/PCA9685_RT +architectures=* +includes=PCA9685.h +depends=Wire diff --git a/libraries/PCF8574/PCF8574.cpp b/libraries/PCF8574/PCF8574.cpp index 510709ea..66ad0a36 100644 --- a/libraries/PCF8574/PCF8574.cpp +++ b/libraries/PCF8574/PCF8574.cpp @@ -2,12 +2,13 @@ // FILE: PCF8574.cpp // AUTHOR: Rob Tillaart // DATE: 02-febr-2013 -// VERSION: 0.2.0 +// VERSION: 0.2.1 // PURPOSE: Arduino library for PCF8574 - I2C IO expander // URL: https://github.com/RobTillaart/PCF8574 // http://forum.arduino.cc/index.php?topic=184800 // // HISTORY: +// 0.2.1 2020-06-19 fix library.json // 0.2.0 2020-05-22 #pragma once; refactor; // removed pre 1.0 support // added begin(dsa, scl) for ESP32 diff --git a/libraries/PCF8574/PCF8574.h b/libraries/PCF8574/PCF8574.h index 7f38180b..f0d5bcaa 100644 --- a/libraries/PCF8574/PCF8574.h +++ b/libraries/PCF8574/PCF8574.h @@ -3,7 +3,7 @@ // FILE: PCF8574.H // AUTHOR: Rob Tillaart // DATE: 02-febr-2013 -// VERSION: 0.2.0 +// VERSION: 0.2.1 // PURPOSE: Arduino library for PCF8574 - I2C IO expander // URL: https://github.com/RobTillaart/PCF8574 // http://forum.arduino.cc/index.php?topic=184800 @@ -14,7 +14,7 @@ #include "Arduino.h" -#define PCF8574_LIB_VERSION "0.2.0" +#define PCF8574_LIB_VERSION "0.2.1" #define PCF8574_OK 0x00 #define PCF8574_PIN_ERROR 0x81 diff --git a/libraries/PCF8574/library.json b/libraries/PCF8574/library.json index 16a4b7ec..01ca19f5 100644 --- a/libraries/PCF8574/library.json +++ b/libraries/PCF8574/library.json @@ -15,10 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/PCF8574.git" }, - "version":"0.2.0", + "version":"0.2.1", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "*" - } + "platforms": "*" } diff --git a/libraries/PCF8574/library.properties b/libraries/PCF8574/library.properties index ee2b4c69..8a6f774e 100644 --- a/libraries/PCF8574/library.properties +++ b/libraries/PCF8574/library.properties @@ -1,5 +1,5 @@ name=PCF8574 -version=0.1.9 +version=0.2.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for PCF8574 - I2C IO expander diff --git a/libraries/Par27979/LICENSE b/libraries/Par27979/LICENSE new file mode 100644 index 00000000..fbd4df5b --- /dev/null +++ b/libraries/Par27979/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2010-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/Par27979/Par27979.h b/libraries/Par27979/Par27979.h index f4bfb2ad..2abc1062 100644 --- a/libraries/Par27979/Par27979.h +++ b/libraries/Par27979/Par27979.h @@ -1,44 +1,70 @@ -/* - Par27979.h - library for Arduino & Parallax 27979 serial display - Copyright (c) 2010. All right reserved. +#pragma once +// +// FILE: PAR27979.h +// AUTHOR: Rob Tillaart +// VERSION: 0.2.0 +// PURPOSE: Arduino library for Parallax 27979 _serial LCD display +// URL: https://github.com/RobTillaart/PAR27979 +// +// HISTORY: +// 0.1.0 2010-03-06 - initial version Macro's only +// 0.2.0 2020-06-23 complete redo as class +// also support for 27976, 27977 (not tested) - This library is free software; you can redistribute it and/or - modify it as long as you leave this copyright notice intact +#define PAR27929_VERSION 0.2.0 - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -*/ +#include "Arduino.h" -#ifndef Par27979_h -#define Par27979_h - -#define PAR27929_VERSION 0.1.00 - -#define DISPLAYOFF Serial.print((char)21) -#define DISPLAYON Serial.print((char)22) -#define DISPLAYCLR Serial.print((char)12); delay(10) -#define BACKLIGHTOFF Serial.print((char)18) -#define BACKLIGHTON Serial.print((char)17) -#define GOTOXY(x,y) Serial.print((char)(128 + y*20 + x)) -#define LEFT Serial.print((char)8) -#define RIGHT Serial.print((char)9) -#define LINEFEED Serial.print((char)10) -#define FORMFEED Serial.print((char)12) -#define RETURN Serial.print((char)13) - -#endif - -/* -void setup() +class PAR27979 : public Print { - Serial.begin(9600); - DISPLAYON; - GOTOXY(2,3); - Serial.print("hello"); -} +public: + PAR27979(Stream * str) { _ser = str; }; -void loop() -{ -} -*/ + void on() { _ser->write(22); }; + void off() { _ser->write(21); }; + void clearHome() { _ser->write(12); delay(5); }; + + void backlightOn() { _ser->write(17); }; + void backlightOff() { _ser->write(18); }; + + + // MOVEMENT + void left() { _ser->write(8); }; + void right() { _ser->write(9); }; + void down() { _ser->write(10); }; + void gotoXY(uint8_t x, uint8_t y) { _ser->write(128 + y*20 + x); }; + + + // CUSTOM CHARS + // array will need to be 8 bytes. - see datasheet. + void defineCustomChar(uint8_t idx, uint8_t * arr) + { + _ser->write(248 + idx); + for (int i = 0; i < 8; i++) _ser->write(arr[i]); + } + void customChar(uint8_t idx) { _ser->write(idx); }; + + + // PLAY MUSIC + // octave = 3, 4, 5, 6, 7 + void octave(uint8_t octave) { _ser->write(212 + octave); }; + // duration is in 1/64 = 1, 2, 4, 8, 16, 32, 64 + void duration(uint8_t duration) + { + uint8_t ch = 207; + while(duration) { duration /= 2; ch++; }; + _ser->write(ch); + } + // A = 0, A# = 1 etc, see datasheet + void play(uint8_t note) { _ser->write(220 + note); }; + void noSound() { _ser->write(232); }; + + + // PRINT interface + size_t write(const uint8_t data) { return _ser->write(data); }; + +private: + Stream *_ser; +}; + +// -- END OF FILE -- diff --git a/libraries/Par27979/examples/PAR27979_demo/PAR27979_demo.ino b/libraries/Par27979/examples/PAR27979_demo/PAR27979_demo.ino new file mode 100644 index 00000000..43751aca --- /dev/null +++ b/libraries/Par27979/examples/PAR27979_demo/PAR27979_demo.ino @@ -0,0 +1,78 @@ +// +// FILE: par27979_demo.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo +// DATE: 2020-06-23 +// (c) : MIT +// + +#include + +SoftwareSerial sws(3, 3); + +#include "PAR27979.h" + +PAR27979 display(&sws); + +void setup() +{ + sws.begin(19200); // max speed parallax display + + display.clearHome(); + + // ON OFF TEST + display.on(); + delay(1000); + display.off(); + delay(1000); + display.on(); + + // BACKLIGHT TEST + display.backlightOn(); + delay(1000); + display.backlightOff(); + delay(1000); + display.backlightOn(); + + // PRINT + display.gotoXY(0, 0); + display.print(10); + delay(100); + display.println(); + display.print(-10); + delay(100); + display.println(); + display.print(20L); + delay(100); + display.println(); + display.print(-20L); + delay(100); + display.println(); + display.print(PI, 7); + delay(100); + display.print(F("that is")); + display.print("all folks"); + delay(1000); + + // CUSTOM CHAR + uint8_t ch_array[8] = { 0, 2, 4, 8, 31, 8, 4, 2 }; + display.defineCustomChar(0, ch_array); + display.customChar(0); + + // PLAY + display.duration(64); // 1 second. + display.octave(4); + for (int n = 0; n < 12; n++) display.play(n); + display.noSound(); + + // FINISH + display.clearHome(); + // display.print("Done..."); + +} + +void loop() +{ + +} \ No newline at end of file diff --git a/libraries/Par27979/examples/PAR27979_demo2/PAR27979_demo2.ino b/libraries/Par27979/examples/PAR27979_demo2/PAR27979_demo2.ino new file mode 100644 index 00000000..3d6cd8f5 --- /dev/null +++ b/libraries/Par27979/examples/PAR27979_demo2/PAR27979_demo2.ino @@ -0,0 +1,75 @@ +// +// FILE: par27979_demo.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo +// DATE: 2020-06-23 +// (c) : MIT +// + +#include "PAR27979.h" + +PAR27979 display(&Serial); + +void setup() +{ + Serial.begin(19200); // max speed parallax display + + display.clearHome(); + + // ON OFF TEST + display.on(); + delay(1000); + display.off(); + delay(1000); + display.on(); + + // BACKLIGHT TEST + display.backlightOn(); + delay(1000); + display.backlightOff(); + delay(1000); + display.backlightOn(); + + // PRINT + display.gotoXY(0, 0); + display.print(10); + delay(100); + display.println(); + display.print(-10); + delay(100); + display.println(); + display.print(20L); + delay(100); + display.println(); + display.print(-20L); + delay(100); + display.println(); + display.print(PI, 7); + delay(100); + display.print(F("that is")); + display.print("all folks"); + delay(1000); + + // CUSTOM CHAR + uint8_t ch_array[8] = { 0, 2, 4, 8, 31, 8, 4, 2 }; + display.defineCustomChar(0, ch_array); + display.customChar(0); + + // PLAY + display.duration(64); // 1 second. + display.octave(4); + for (int n = 0; n < 12; n++) display.play(n); + display.noSound(); + + // FINISH + display.clearHome(); + display.print("Done..."); +} + +void loop() +{ + +} + +// -- END OF FILE -- diff --git a/libraries/Par27979/keywords.txt b/libraries/Par27979/keywords.txt new file mode 100644 index 00000000..4135c107 --- /dev/null +++ b/libraries/Par27979/keywords.txt @@ -0,0 +1,28 @@ +# Syntax Coloring Map For PAR27979 + +# Datatypes (KEYWORD1) +PAR27979 KEYWORD1 + +# Methods and Functions (KEYWORD2) +on KEYWORD2 +off KEYWORD2 +clearHome KEYWORD2 +backlightOn KEYWORD2 +backlightOff KEYWORD2 +left KEYWORD2 +right KEYWORD2 +down KEYWORD2 +gotoXY KEYWORD2 +defineCustomChar KEYWORD2 +customChar KEYWORD2 + +octave KEYWORD2 +duration KEYWORD2 +play KEYWORD2 +noSound KEYWORD2 + +# Instances (KEYWORD2) + +# Constants (LITERAL1) + + diff --git a/libraries/Par27979/library.json b/libraries/Par27979/library.json index b57cc4ed..25aa2aa0 100644 --- a/libraries/Par27979/library.json +++ b/libraries/Par27979/library.json @@ -1,7 +1,7 @@ { - "name": "Par27979", - "keywords": "Parallax,27979,serial,display", - "description": "Defines for Parallax 27979 serial display.", + "name": "PAR27979", + "keywords": "Parallax,27979,serial,display,27976,27977", + "description": "Arduino library for Parallax 27979 serial LCD display.", "authors": [ { @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PAR27979.git" }, - "version":"0.1.0", + "version":"0.2.0", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/Par27979" - } + "platforms": "*" } diff --git a/libraries/Par27979/library.properties b/libraries/Par27979/library.properties index a680cdeb..1c793ef3 100644 --- a/libraries/Par27979/library.properties +++ b/libraries/Par27979/library.properties @@ -1,9 +1,11 @@ -name=Par27979 -version=0.1.0 +name=PAR27979 +version=0.2.0 author=Rob Tillaart maintainer=Rob Tillaart -sentence=Defines for Parallax 27979 serial display. -paragraph=Supports -category=Sensors -url=https://github.com/RobTillaart/Arduino/tree/master/libraries/ -architectures=* \ No newline at end of file +sentence=Arduino library for Parallax 27979 serial LCD display. +paragraph=Supports 27976 and 27977 (not tested) +category=Display +url=https://github.com/RobTillaart/PAR27979 +architectures=* +includes=PAR27979.h +depends= diff --git a/libraries/Par27979/readme.md b/libraries/Par27979/readme.md index 9b86566c..ece864af 100644 --- a/libraries/Par27979/readme.md +++ b/libraries/Par27979/readme.md @@ -1,4 +1,44 @@ +# PAR27979 -This is just a collection of simple macros, -not a real class with a stream as param -(todo someday somewhere) +Arduino library for the Parallax 27979 serial display + +## Description + +The library is essentially a wrapper around a Stream, typically Serial, +Serial2 (3,4..) or newSoftSerial or equivalent. +This stream is given as parameter in the constructor. + +The library implements the **Print** interface to print integers +floats and strings and all printable types. + +The library does not keep any state information, it only implements a few +methods to make working with it easier. +These methods are quite trivial. + +* **on()** switch display on +* **off()** switch display off +* **clearHome()** clear the display +* **backlightOn()** enable the backlight +* **backLightOff()** disable the backlight + +**Movement** +* **cursorLeft()** move cursor +* **cursorRight()** move cursor +* **lineFeed()** idem +* **formFeed()** idem +* **gotoXY(x, y)** + +**Sound support** +* **octave(octave)** octave = 3 4 5 6 7 +* **duration(duration)** duration = 1 2 4 8 16 32 64 +* **play(note)** note = 0 1 2 3 4 5 6 7 8 9 10 11 0=A 1=A# etc +* **noSound()** + +## Support Parallax 27976 & 27977 + +Although not tested, the functions should work with the +Parallax 27976 and 27977 displays too. + +## Operation + +See example diff --git a/libraries/ParPrinter/replaced by parallelPrinter.txt b/libraries/ParPrinter/replaced by parallelPrinter.txt new file mode 100644 index 00000000..4d1dab05 --- /dev/null +++ b/libraries/ParPrinter/replaced by parallelPrinter.txt @@ -0,0 +1 @@ +https://github.com/RobTillaart/ParallelPrinter \ No newline at end of file diff --git a/libraries/PinInGroup/PinInGroup.cpp b/libraries/PinInGroup/PinInGroup.cpp index bd3c3afc..3ddbd433 100644 --- a/libraries/PinInGroup/PinInGroup.cpp +++ b/libraries/PinInGroup/PinInGroup.cpp @@ -1,7 +1,7 @@ // // FILE: PinInGroup.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 +// VERSION: 0.1.2 // DATE: 2017-04-26 // PURPOSE: PinInGroup library for Arduino // goal is to easily read a group of pins that logically @@ -10,8 +10,10 @@ // URL: https://github.com/RobTillaart/PinInGroup // http://forum.arduino.cc/index.php?topic=469599.0 // -// 0.1.0 2017-08-20 initial version (based upon pinGroup) -// 0.1.1 2020-05-19 refactor; added clear(); added param for INPUT or INPUT_PULLUP +// 0.1.0 2017-08-20 initial version (based upon pinGroup) +// 0.1.1 2020-05-19 refactor; added clear(); +// added param for INPUT or INPUT_PULLUP +// 0.1.2 2020-06-19 fix library.json #include "PinInGroup.h" diff --git a/libraries/PinInGroup/PinInGroup.h b/libraries/PinInGroup/PinInGroup.h index 368ad13b..5788c47c 100644 --- a/libraries/PinInGroup/PinInGroup.h +++ b/libraries/PinInGroup/PinInGroup.h @@ -1,7 +1,7 @@ #pragma once // FILE: PinInGroup.h // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: 0.1.1 +// VERSION: 0.1.2 // DATE: 2017-04-26 // PURPOSE: PinInGroup library for Arduino // HISTORY: See PinInGroup.cpp @@ -12,7 +12,7 @@ #include "Arduino.h" -#define PININGROUP_LIB_VERSION "0.1.1" +#define PININGROUP_LIB_VERSION "0.1.2" // smaller MAXSIZE will reduce memory footprint with ditto bytes. #ifndef PININGROUP_MAXSIZE diff --git a/libraries/PinInGroup/library.json b/libraries/PinInGroup/library.json index fa96f2f7..53bc8f61 100644 --- a/libraries/PinInGroup/library.json +++ b/libraries/PinInGroup/library.json @@ -15,10 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/PinInGroup.git" }, - "version":"0.1.1", + "version":"0.1.2", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "PinInGroup - } + "platforms": "*" } diff --git a/libraries/PinInGroup/library.properties b/libraries/PinInGroup/library.properties index 93b325ce..185aadf6 100644 --- a/libraries/PinInGroup/library.properties +++ b/libraries/PinInGroup/library.properties @@ -1,5 +1,5 @@ name=PinInGroup -version=0.1.1 +version=0.1.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=A class that groups input pins so they can be read in one logical step. diff --git a/libraries/PinOutGroup/PinOutGroup.cpp b/libraries/PinOutGroup/PinOutGroup.cpp index 95eda8cb..a3428fee 100644 --- a/libraries/PinOutGroup/PinOutGroup.cpp +++ b/libraries/PinOutGroup/PinOutGroup.cpp @@ -1,22 +1,22 @@ // // FILE: PinOutGroup.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 +// VERSION: 0.1.2 // DATE: 2017-04-26 // PURPOSE: PinOutGroup library for Arduino -// goal is to easily change a group of pins that logically +// goal is to easily change a group of pins that logically // belong to each other e.g. 8 data pins of a parallel printer. // these pins can be in any order. -// URL: +// URL: // http://forum.arduino.cc/index.php?topic=469599.0 // // 0.1.0 - 20-08-2017 initial version (based upon experimental pinGroup) -// 0.1.1 - 2020-05-19 main refactor; +// 0.1.1 - 2020-05-19 main refactor; // added tests; added clear(); added write(idx, value) // renamed set to write() to be in line with digitalWrite() -// -// +// 0.1.2 2020-06-19 fix library.json +// #include "PinOutGroup.h" @@ -35,7 +35,7 @@ void PinOutGroup::clear() bool PinOutGroup::add(uint8_t sz, uint8_t* ar, uint8_t value) { bool b = true; - for (uint8_t i = 0; i < sz && b; i++) + for (uint8_t i = 0; i < sz && b; i++) { b = b && add(ar[i], value); } @@ -62,7 +62,7 @@ uint8_t PinOutGroup::write(uint16_t value) uint8_t changeCount = 0; for (uint8_t i = 0; i < _size; i++) { - if ((changed & bitMask) > 0) + if ((changed & bitMask) > 0) { digitalWrite(_pins[i], (value & bitMask) > 0); changeCount++; diff --git a/libraries/PinOutGroup/PinOutGroup.h b/libraries/PinOutGroup/PinOutGroup.h index 34831f02..e7b3a3bb 100644 --- a/libraries/PinOutGroup/PinOutGroup.h +++ b/libraries/PinOutGroup/PinOutGroup.h @@ -1,7 +1,7 @@ #pragma once // FILE: PinOutGroup.h // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: 0.1.1 +// VERSION: 0.1.2 // DATE: 2017-04-26 // PURPOSE: PinOutGroup library for Arduino // HISTORY: See PinOutGroup.cpp @@ -9,7 +9,7 @@ #include "Arduino.h" -#define PINOUTGROUP_LIB_VERSION "0.1.1" +#define PINOUTGROUP_LIB_VERSION "0.1.2" // smaller MAXSIZE will reduce memory footprint with ditto bytes. #ifndef PINOUTGROUP_MAXSIZE diff --git a/libraries/PinOutGroup/library.json b/libraries/PinOutGroup/library.json index e231e3bc..c05ad8aa 100644 --- a/libraries/PinOutGroup/library.json +++ b/libraries/PinOutGroup/library.json @@ -15,10 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/PinOutGroup.git" }, - "version":"0.1.1", + "version":"0.1.2", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "PinOutGroup - } + "platforms": "*" } diff --git a/libraries/PinOutGroup/library.properties b/libraries/PinOutGroup/library.properties index 4f241fee..535983d9 100644 --- a/libraries/PinOutGroup/library.properties +++ b/libraries/PinOutGroup/library.properties @@ -1,5 +1,5 @@ name=PinOutGroup -version=0.1.1 +version=0.1.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=A class that groups output pins so they can be updated easier and slightly faster on average. diff --git a/libraries/Prandom/Prandom.cpp b/libraries/Prandom/Prandom.cpp index bb09954d..20a34890 100644 --- a/libraries/Prandom/Prandom.cpp +++ b/libraries/Prandom/Prandom.cpp @@ -1,13 +1,15 @@ // // FILE: Prandom.cpp // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: 0.1.1 +// VERSION: 0.1.2 // PURPOSE: Arduino library for random number generation with Python random interface +// URL: https://github.com/RobTillaart/Prandom // // HISTORY: // 0.1.0 2020-05-13 complete redo based upon python random interface // https://docs.python.org/3/library/random.html // 0.1.1 renamed all to Prandom +// 0.1.2 2020-06-19 fix library.json // code nased upon Python implementation although some small optimizations // and tweaks were needed to get it working. diff --git a/libraries/Prandom/Prandom.h b/libraries/Prandom/Prandom.h index 5d6df665..8ae95548 100644 --- a/libraries/Prandom/Prandom.h +++ b/libraries/Prandom/Prandom.h @@ -2,58 +2,58 @@ // // FILE: Prandom.h // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: 0.1.1 +// VERSION: 0.1.2 // PURPOSE: Arduino library for random numbers with Python Random interface -// The underlying pseudo-random number generator is a +// The underlying pseudo-random number generator is a // Multiply-with-carry method invented by George Marsaglia. -// URL: https://github.com/RobTillaart/random +// URL: https://github.com/RobTillaart/Prandom // https://docs.python.org/3/library/random.html // https://www.pcg-random.org/ // #include "Arduino.h" -#define PRANDOM_LIB_VERSION "0.1.1" +#define PRANDOM_LIB_VERSION "0.1.2" class Prandom { public: - Prandom(); - Prandom(uint32_t s); + Prandom(); + Prandom(uint32_t s); - void seed(); - void seed(uint32_t s, uint32_t t = 2); // marsaglia need 2 seeds, but 1 will work too + void seed(); + void seed(uint32_t s, uint32_t t = 2); // marsaglia need 2 seeds, but 1 will work too - // - // integer methods - // - uint32_t getrandbits(uint8_t n); - uint32_t randrange(uint32_t stop); - uint32_t randrange(uint32_t start, uint32_t stop, uint32_t step = 1); - // randint is inclusive end value - uint32_t randint(uint32_t start, uint32_t stop) { return randrange(start, stop + 1); }; + // + // integer methods + // + uint32_t getrandbits(uint8_t n); + uint32_t randrange(uint32_t stop); + uint32_t randrange(uint32_t start, uint32_t stop, uint32_t step = 1); + // randint is inclusive end value + uint32_t randint(uint32_t start, uint32_t stop) { return randrange(start, stop + 1); }; - // - // real distributions - // - float random(const float top = 1.0); - float uniform(float lo, float hi); - float triangular(float lo = 0, float hi = 1.0, float mid = 0.5); - float normalvariate(float mu = 0, float sigma = 1.0); - float lognormvariate(float mu = 0, float sigma = 1.0); - float gauss(float mu = 0, float sigma = 1.0); - float expovariate(float lambda); - float gammavariate(float alpha, float beta); - float betavariate(float alpha, float beta); - float paretovariate(float alpha); - float weibullvariate(float alpha, float beta); - - // - // Circular distributions - // - // mu is mean angle in radians - // kappa is concentration param, 0 -> uniform. - float vonmisesvariate(float mu, float kappa = 0); + // + // real distributions + // + float random(const float top = 1.0); + float uniform(float lo, float hi); + float triangular(float lo = 0, float hi = 1.0, float mid = 0.5); + float normalvariate(float mu = 0, float sigma = 1.0); + float lognormvariate(float mu = 0, float sigma = 1.0); + float gauss(float mu = 0, float sigma = 1.0); + float expovariate(float lambda); + float gammavariate(float alpha, float beta); + float betavariate(float alpha, float beta); + float paretovariate(float alpha); + float weibullvariate(float alpha, float beta); + + // + // Circular distributions + // + // mu is mean angle in radians + // kappa is concentration param, 0 -> uniform. + float vonmisesvariate(float mu, float kappa = 0); private: @@ -62,7 +62,7 @@ private: // Marsaglia 'constants' uint32_t _m_w = 1; - uint32_t _m_z = 2; + uint32_t _m_z = 2; uint32_t __random(); }; diff --git a/libraries/Prandom/library.json b/libraries/Prandom/library.json index db1b80f3..75be2861 100644 --- a/libraries/Prandom/library.json +++ b/libraries/Prandom/library.json @@ -15,10 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/Prandom.git" }, - "version":"0.1.1", + "version":"0.1.2", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "Prandom" - } + "platforms": "*" } diff --git a/libraries/Prandom/library.properties b/libraries/Prandom/library.properties index e5805cb2..60cca802 100644 --- a/libraries/Prandom/library.properties +++ b/libraries/Prandom/library.properties @@ -1,5 +1,5 @@ name=Prandom -version=0.1.1 +version=0.1.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for random number generation with Python random interface. diff --git a/libraries/PrintCharArray/LICENSE b/libraries/PrintCharArray/LICENSE new file mode 100644 index 00000000..ed401f22 --- /dev/null +++ b/libraries/PrintCharArray/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/PrintCharArray/PrintCharArray.h b/libraries/PrintCharArray/PrintCharArray.h index 0f38108d..17eec34f 100644 --- a/libraries/PrintCharArray/PrintCharArray.h +++ b/libraries/PrintCharArray/PrintCharArray.h @@ -1,35 +1,35 @@ +#pragma once // // FILE: PrintCharArray.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.2.1 // PURPOSE: Class that captures prints into a char array // DATE: 2017-12-07 -// URL: -// HISTORY: 0.1.0 2017-12-07 initial version +// URL: https://github.com/RobTillaart/PrintCharArray // -// Released to the public domain -// - -#ifndef PrintCharArray_h -#define PrintCharArray_h +// 0.1.0 2017-12-07 initial version +// 0.1.1 2020-04-28 minor optimization +// 0.2.0 2020-04-30 dynamic memory +// 0.2.1 2020-06-19 fix library.json #include "Print.h" -#define PRINTCHARARRAY_VERSION "0.1.0" -#define BUFFERSIZE 256 +#define PRINTCHARARRAY_VERSION "0.2.1" class PrintCharArray: public Print { public: - PrintCharArray() {}; + PrintCharArray(uint8_t size = 100) + { + _bufSize = constrain(size, 20, 250); + _buffer = (char *) malloc(_bufSize); + }; size_t write(uint8_t c) { - if (index < BUFFERSIZE-1) + if (_index < _bufSize - 1) { - buffer[index] = c; - index++; - buffer[index] = '\0'; + _buffer[_index++] = c; return 1; } return 0; @@ -37,19 +37,23 @@ class PrintCharArray: public Print void clear() { - index = 0; - buffer[index] = '\0'; + _index = 0; } - int free() { return (BUFFERSIZE - index); } + int free() { return (_bufSize - _index); } - int size() { return index; } + int size() { return _index; } - char * getBuffer() { return buffer; } + char * getBuffer() + { + _buffer[_index] = '\0'; + return _buffer; + } private: - char buffer[BUFFERSIZE]; - int index = 0; + char* _buffer; + uint8_t _bufSize = 0; + uint8_t _index = 0; }; -#endif + // -- END OF FILE -- diff --git a/libraries/PrintCharArray/examples/printCharArray1/printCharArray1.ino b/libraries/PrintCharArray/examples/printCharArray1/printCharArray1.ino index 2a35b758..89cba607 100644 --- a/libraries/PrintCharArray/examples/printCharArray1/printCharArray1.ino +++ b/libraries/PrintCharArray/examples/printCharArray1/printCharArray1.ino @@ -3,6 +3,7 @@ // AUTHOR: Rob Tillaart // VERSION: 0.1.0 // PURPOSE: demo +// URL: https://github.com/RobTillaart/PrintCharArray // // HISTORY: // 0.1.0 2017-12-07 initial version @@ -35,3 +36,4 @@ void loop() } +// -- END OF FILE -- diff --git a/libraries/PrintCharArray/examples/printCharArray2/printCharArray2.ino b/libraries/PrintCharArray/examples/printCharArray2/printCharArray2.ino index ae94fba9..f7b6b279 100644 --- a/libraries/PrintCharArray/examples/printCharArray2/printCharArray2.ino +++ b/libraries/PrintCharArray/examples/printCharArray2/printCharArray2.ino @@ -2,7 +2,8 @@ // FILE: printCharArray2.ino // AUTHOR: Rob Tillaart // VERSION: 0.1.0 -// PURPOSE: demo +// PURPOSE: demo right alignment +// URL: https://github.com/RobTillaart/PrintCharArray // // HISTORY: // 0.1.0 2017-12-09 initial version @@ -53,3 +54,4 @@ void printSpaces(int n) } } +// -- END OF FILE -- diff --git a/libraries/PrintCharArray/examples/printCharArray3/printCharArray3.ino b/libraries/PrintCharArray/examples/printCharArray3/printCharArray3.ino index 831981e8..b82ef223 100644 --- a/libraries/PrintCharArray/examples/printCharArray3/printCharArray3.ino +++ b/libraries/PrintCharArray/examples/printCharArray3/printCharArray3.ino @@ -1,18 +1,20 @@ // // FILE: printCharArray3.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 -// PURPOSE: demo +// VERSION: 0.1.1 +// PURPOSE: demo with XML writer +// URL: https://github.com/RobTillaart/PrintCharArray // // HISTORY: -// 0.1.0 2017-12-09 initial version +// 0.1.0 2017-12-09 initial version +// 0.1.1 2020-04-30 minor refactor // #include "PrintCharArray.h" -#include "XMLWriter.h" +#include "XMLWriter.h" // https://github.com/RobTillaart/XMLWriter -PrintCharArray ps; +PrintCharArray ps(250); XMLWriter XML(&ps); void setup() @@ -32,6 +34,7 @@ void setup() XML.writeNode("Rain", "10mm"); XML.writeNode("Sun", "40"); XML.tagClose(); + XML.flush(); // write the XML generated in one call Serial.println(ps.getBuffer()); @@ -44,3 +47,4 @@ void loop() } +// -- END OF FILE -- diff --git a/libraries/PrintCharArray/examples/printCharArray4/printCharArray4.ino b/libraries/PrintCharArray/examples/printCharArray4/printCharArray4.ino index e6cafb13..d52034b4 100644 --- a/libraries/PrintCharArray/examples/printCharArray4/printCharArray4.ino +++ b/libraries/PrintCharArray/examples/printCharArray4/printCharArray4.ino @@ -1,16 +1,18 @@ // // FILE: printCharArray4.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.1.1 // PURPOSE: demo it takes less time to send data out. +// URL: https://github.com/RobTillaart/PrintCharArray // // HISTORY: -// 0.1.0 2017-12-09 initial version +// 0.1.0 2017-12-09 initial version +// 0.1.1 2020-04-30 minor refactor // #include "PrintCharArray.h" -PrintCharArray ps; +PrintCharArray ps(200); uint32_t start, stop; @@ -20,30 +22,36 @@ void setup() Serial.println(__FILE__); Serial.println("Using direct print"); - start = millis(); - for (int i=0; i<10; i++) + start = micros(); + for (int i = 0; i < 10; i++) { - Serial.println(1000+i); + Serial.println(1000 + i); } - stop = millis(); + stop = micros(); Serial.println(stop - start); Serial.println(); Serial.println("Using printCharArray"); + start = micros(); ps.clear(); - for (int i=0; i<10; i++) + for (int i = 0; i < 10; i++) { - ps.println(1000+i) + ps.println(1000 + i); } - start = millis(); Serial.println(ps.getBuffer()); - stop = millis(); + stop = micros(); Serial.println(stop - start); Serial.println(); + Serial.println("print PrintCharArray again"); + start = micros(); Serial.println(ps.getBuffer()); - Serial.println(ps.free()); + stop = micros(); + Serial.println(stop - start); + Serial.println(); + Serial.print("FREE: "); + Serial.println(ps.free()); } void loop() @@ -51,3 +59,4 @@ void loop() } +// -- END OF FILE -- diff --git a/libraries/PrintCharArray/examples/printCharArrayDynamicSize/printCharArrayDynamicSize.ino b/libraries/PrintCharArray/examples/printCharArrayDynamicSize/printCharArrayDynamicSize.ino new file mode 100644 index 00000000..2ffa56ec --- /dev/null +++ b/libraries/PrintCharArray/examples/printCharArrayDynamicSize/printCharArrayDynamicSize.ino @@ -0,0 +1,39 @@ +// +// FILE: printCharArrayDynamicSize.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo +// URL: https://github.com/RobTillaart/PrintCharArray +// +// HISTORY: +// 0.1.0 2020-04-30 initial version +// + +#include "PrintCharArray.h" + +PrintCharArray ps(100); + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + Serial.println(ps.free()); + ps.println("Hello World"); + Serial.println(ps.free()); + ps.println(3.14159265, 4); + Serial.println(ps.free()); + Serial.println(ps.getBuffer()); + + ps.clear(); + ps.println(3.14159265, 4); + ps.println("Hello World"); + Serial.println(ps.getBuffer()); +} + +void loop() +{ + +} + +// -- END OF FILE -- diff --git a/libraries/PrintCharArray/keywords..txt b/libraries/PrintCharArray/keywords..txt new file mode 100644 index 00000000..f686a1d4 --- /dev/null +++ b/libraries/PrintCharArray/keywords..txt @@ -0,0 +1,14 @@ +# Syntax Coloring Map For PrintCharArray + +# Datatypes (KEYWORD1) +PrintCharArray KEYWORD1 + +# Methods and Functions (KEYWORD2) +write KEYWORD2 +clear KEYWORD2 +free KEYWORD2 +size KEYWORD2 +getBuffer KEYWORD2 + +# Constants (LITERAL1) + diff --git a/libraries/PrintCharArray/library.json b/libraries/PrintCharArray/library.json index cdd1e691..3bf0b32e 100644 --- a/libraries/PrintCharArray/library.json +++ b/libraries/PrintCharArray/library.json @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PrintCharArray.git" }, - "version":"0.1.0", + "version":"0.2.1", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/PrintCharArray" - } + "platforms": "*" } diff --git a/libraries/PrintCharArray/library.properties b/libraries/PrintCharArray/library.properties index 48d00461..be4c07b2 100644 --- a/libraries/PrintCharArray/library.properties +++ b/libraries/PrintCharArray/library.properties @@ -1,10 +1,12 @@ name=PrintCharArray -version=0.1.0 +version=0.2.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library to capture prints into a char array. paragraph= category=Data Processing -url=https://github.com/RobTillaart/Arduino/tree/master/libraries +url=https://github.com/RobTillaart/PrintCharArray.git architectures=* +includes=PrintCharArray.h +depends= diff --git a/libraries/PrintCharArray/readme.md b/libraries/PrintCharArray/readme.md index 72b280c0..787d803e 100644 --- a/libraries/PrintCharArray/readme.md +++ b/libraries/PrintCharArray/readme.md @@ -1,12 +1,17 @@ +# PrintCharArray + +Arduino library to print to a char array + +# Description PrintCharArray is a class that buffers a number of print statements in a char array. This char array can be processed later. -Typical usecase: -- buffer slow generated of a packet of data - and send it with minimum time between bytes - -- print to buffer an see how long output is; +- buffer slowly generated data, and send it with minimum time between bytes +- print to buffer to see how many chars the output is; use to prevent "display line overflow" (e.g. floats) + +## Operation +See examples diff --git a/libraries/PrintSize/LICENSE b/libraries/PrintSize/LICENSE new file mode 100644 index 00000000..ed401f22 --- /dev/null +++ b/libraries/PrintSize/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/PrintSize/PrintSize.h b/libraries/PrintSize/PrintSize.h index 7a21d881..5c7bc497 100644 --- a/libraries/PrintSize/PrintSize.h +++ b/libraries/PrintSize/PrintSize.h @@ -1,28 +1,43 @@ +#pragma once // // FILE: PrintSize.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.2.1 // PURPOSE: Class that determines printSize // DATE: 2017-12-09 -// URL: -// HISTORY: 0.1.0 2017-12-09 initial version +// URL: https://github.com/RobTillaart/PrintSize // -// Released to the public domain -// - -#ifndef PrintSize_h -#define PrintSize_h +// HISTORY: +// 0.1.0 2017-12-09 initial version +// 0.2.0 2020-04-30 add total counter to sum multiple print statements +// 0.2.1 2020-05-26 fix #1 - URLS + centering example +// 0.2.2 2020-06-19 fix library.json #include "Print.h" -#define PRINTSIZE_VERSION "0.1.0" +#define PRINTSIZE_VERSION "0.2.2" class PrintSize: public Print { public: - PrintSize() {}; + PrintSize() + { + reset(); + }; - size_t write(uint8_t c) { return 1; } + // note: warning unused parameter - remove c to remove warning) + size_t write(uint8_t c) + { + _total++; + return 1; + } + + void reset() { _total = 0; } + + uint32_t total() { return _total; }; + +private: + uint32_t _total = 0; }; -#endif + // -- END OF FILE -- diff --git a/libraries/PrintSize/examples/PrintSize1/PrintSize1.ino b/libraries/PrintSize/examples/PrintSize1/PrintSize1.ino index e974ac5a..0e19bb38 100644 --- a/libraries/PrintSize/examples/PrintSize1/PrintSize1.ino +++ b/libraries/PrintSize/examples/PrintSize1/PrintSize1.ino @@ -1,8 +1,9 @@ // // FILE: PrintSize1.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.1.1 // PURPOSE: demo printSize +// URL: https://github.com/RobTillaart/PrintSize // // HISTORY: // 0.1.0 2017-12-09 initial version @@ -48,3 +49,4 @@ void printSpaces(uint8_t n) while (n--) Serial.print(' '); } +// -- END OF FILE -- diff --git a/libraries/PrintSize/examples/PrintSize_centering/PrintSize_centering.ino b/libraries/PrintSize/examples/PrintSize_centering/PrintSize_centering.ino new file mode 100644 index 00000000..25130e4b --- /dev/null +++ b/libraries/PrintSize/examples/PrintSize_centering/PrintSize_centering.ino @@ -0,0 +1,83 @@ +// +// FILE: PrintSize_centering.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo printSize centering +// URL: https://github.com/RobTillaart/PrintSize +// +// HISTORY: +// 0.1.0 2020-04-30 initial version +// + + +#include "PrintSize.h" + +char woord[24]; +int idx = 0; + +PrintSize ps; + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(); + Serial.println(__FILE__); + + Serial.println("Determine length of 10 random numbers and right "); + Serial.println("align the numbers in a table with their sum."); + Serial.println(); + ps.reset(); +} + +void loop() +{ + uint32_t sum = 0; + + + Serial.println(); + Serial.println(" Centering"); + for (int i = 0; i < 10; i++) + { + // create different order of magnitude random numbers + uint32_t maxsize = pow(10, 1 + random(9)); + uint32_t rn = random(maxsize); + int length = ps.println(rn); + printSpaces((15 - length) / 2); + sum += rn; + Serial.println(rn); + } + Serial.print("================ +\n"); + int length = ps.println(sum); + printSpaces((15 - length) / 2); + Serial.println(sum); + Serial.println(); + + + Serial.println(); + Serial.println(" Right Align"); + for (int i = 0; i < 10; i++) + { + // create different order of magnitude random numbers + uint32_t maxsize = pow(10, 1 + random(9)); + uint32_t rn = random(maxsize); + int length = ps.println(rn); + printSpaces(15 - length); + sum += rn; + Serial.println(rn); + } + Serial.print("================ +\n"); + length = ps.println(sum); + printSpaces(15 - length); + Serial.println(sum); + Serial.println(); + + delay(1000); +} + +void printSpaces(uint8_t n) +{ + while (n--) Serial.print(' '); +} + +// -- END OF FILE -- \ No newline at end of file diff --git a/libraries/PrintSize/examples/PrintSize_printf/PrintSize_printf.ino b/libraries/PrintSize/examples/PrintSize_printf/PrintSize_printf.ino index f666a6a2..d23699a1 100644 --- a/libraries/PrintSize/examples/PrintSize_printf/PrintSize_printf.ino +++ b/libraries/PrintSize/examples/PrintSize_printf/PrintSize_printf.ino @@ -52,3 +52,5 @@ void printSpaces(uint8_t n) { while (n--) Serial.print(' '); } + +// -- END OF FILE -- diff --git a/libraries/PrintSize/examples/PrintSize_total/PrintSize_total.ino b/libraries/PrintSize/examples/PrintSize_total/PrintSize_total.ino new file mode 100644 index 00000000..bd14b41c --- /dev/null +++ b/libraries/PrintSize/examples/PrintSize_total/PrintSize_total.ino @@ -0,0 +1,89 @@ +// +// FILE: PrintSize_total.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo printSize total counter +// URL: https://github.com/RobTillaart/PrintSize +// +// HISTORY: +// 0.1.0 2020-04-30 initial version +// + +/* + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mattis eget odio ut + tempor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin consectetur, + massa nec eleifend aliquet, tellus nulla dapibus magna, eu pharetra dolor turpis + sit amet mauris. Quisque tempor luctus nisl. Donec nisi quam, gravida id urna quis, + vestibulum placerat ex. Etiam auctor odio nisl, at molestie arcu gravida et. + Integer rutrum enim ligula, eget commodo lorem dapibus nec. Ut bibendum sapien at + tellus posuere, lobortis vestibulum magna blandit. Curabitur aliquam, massa sit + amet aliquet ullamcorper, dui metus sollicitudin purus, luctus tempor nisi enim + commodo justo. Nullam tempus, nunc finibus hendrerit mollis, purus odio mattis + nisl, porttitor malesuada erat urna eu neque. Phasellus ultricies ante tortor, + ac facilisis diam dignissim sit amet. Donec accumsan ac orci a malesuada. +*/ +#include "PrintSize.h" + +char woord[24]; +int idx = 0; + +PrintSize ps; + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(); + Serial.println(__FILE__); + + Serial.println("\nType words < 20 chars in the Serial monitor\n"); + ps.reset(); +} + +void loop() +{ + if (Serial.available() > 0) + { + char c = Serial.read(); + if (c == ' ' || c == '\n') + { + process(woord, 60); + woord[0] = '\0'; + idx = 0; + } + else + { + woord[idx++] = c; + woord[idx] = '\0'; + } + } +} + +// split the stream of words in lines of maxlen +void process(char * w, uint8_t maxlen) +{ + // skip empty words. + if (strlen(w) == 0) return; + + // remember position + uint8_t prev = ps.total(); + + // does the word fit on the line + ps.print(w); + ps.print(' '); + if (ps.total() >= maxlen) + { + // if not, fill line with - + for (; prev < maxlen; prev++) Serial.print('-'); + Serial.println(); + + // start counter for new line. + ps.reset(); + ps.print(w); + ps.print(' '); + } + Serial.print(w); + Serial.print(' '); +} + +// -- END OF FILE -- \ No newline at end of file diff --git a/libraries/PrintSize/keywords..txt b/libraries/PrintSize/keywords..txt new file mode 100644 index 00000000..949ff7d6 --- /dev/null +++ b/libraries/PrintSize/keywords..txt @@ -0,0 +1,12 @@ +# Syntax Coloring Map For PrintSize + +# Datatypes (KEYWORD1) +PrintSize KEYWORD1 + +# Methods and Functions (KEYWORD2) +write KEYWORD2 +reset KEYWORD2 +total KEYWORD2 + +# Constants (LITERAL1) + diff --git a/libraries/PrintSize/library.json b/libraries/PrintSize/library.json index e9a387fa..c020c4ed 100644 --- a/libraries/PrintSize/library.json +++ b/libraries/PrintSize/library.json @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PrintSize.git" }, - "version":"0.1.0", + "version":"0.2.2", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/PrintSize" - } + "platforms": "*" } diff --git a/libraries/PrintSize/library.properties b/libraries/PrintSize/library.properties index ddc7affd..9676d126 100644 --- a/libraries/PrintSize/library.properties +++ b/libraries/PrintSize/library.properties @@ -1,10 +1,11 @@ name=PrintSize -version=0.1.0 +version=0.2.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library to determine size of a printed variable. paragraph= category=Data Processing -url=https://github.com/RobTillaart/Arduino/tree/master/libraries +url=https://github.com/RobTillaart/PrintSize architectures=* - +includes=PrintSize.h +depends= diff --git a/libraries/PrintSize/readme.md b/libraries/PrintSize/readme.md index 956e0f5c..e7535d6e 100644 --- a/libraries/PrintSize/readme.md +++ b/libraries/PrintSize/readme.md @@ -1,18 +1,25 @@ - # PrintSize +Arduino library to determine the length of print statements + +# Description + PrintSize is a minimal library to determine the length of a variable when printed. -This includes printing of floats +This includes printing of floats, integers in decimal or hex notation. -## Examples -Example show the alignment of 10 random numbers, -both print(), println() and if supported printf(). +Works for **print()**, **println()** and if supported **printf()** e.g. ESP32. +Finally since **0.2.0** it has a total counter to add up the characters "printed" since +the last **reset()** call. (see example) + +# Operational + +Example shows the right alignment of 10 random numbers + +Example shows (elementary) line fitting -### notes Can be used to calculate the needed space. - - to properly do a right alignment e.g. for numbers. - - do left alignement and overwrite previous output with spaces. + - to properly do a right alignment e.g. for numbers or variable text + - do left alignement and overwrite previous output with just enough spaces. - centering of numbers - - see if output will fit into a line. - + - see if output will fit into a line / display diff --git a/libraries/PrintString/LICENSE b/libraries/PrintString/LICENSE new file mode 100644 index 00000000..1cac81ba --- /dev/null +++ b/libraries/PrintString/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 20017-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/PrintString/PrintString.h b/libraries/PrintString/PrintString.h index 8e45fd6c..70405949 100644 --- a/libraries/PrintString/PrintString.h +++ b/libraries/PrintString/PrintString.h @@ -1,22 +1,21 @@ +#pragma once // // FILE: PrintString.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.1.2 // PURPOSE: Class that captures prints into a String // DATE: 2017-12-09 -// URL: -// HISTORY: 0.1.0 2017-12-09 initial version +// URL: https://github.com/RobTillaart/PrintString // -// Released to the public domain +// 0.1.0 2017-12-09 initial version +// 0.1.1 2020-04-26 added size +// 0.1.2 2020-06-19 fix library.json // -#ifndef PrintString_h -#define PrintString_h - -#include "Arduino.h" #include "Print.h" +#include "String.h" -#define PRINTSTRING_VERSION "0.1.0" +#define PRINTSTRING_VERSION "0.1.2" class PrintString: public Print { @@ -25,10 +24,15 @@ public: size_t write(uint8_t c) { - buffer += (char)c; + buffer.concat(char(c)); return 1; } + size_t size() + { + return buffer.length(); + } + void clear() { buffer = ""; @@ -39,5 +43,5 @@ public: private: String buffer; }; -#endif + // -- END OF FILE -- diff --git a/libraries/PrintString/README.md b/libraries/PrintString/README.md new file mode 100644 index 00000000..3d36f5ee --- /dev/null +++ b/libraries/PrintString/README.md @@ -0,0 +1,19 @@ +# PrintString + +Arduino library to print to a String + +# Description + + +PrintString is a class that buffers a number of print statements in a String. +This String can be requested to process later. + +- buffer slowly generated data, and send it with minimum time between bytes + e.g. to maximize packets for ethernet +- print to buffer to see how many chars the output is; + use to prevent "display line overflow" + (e.g. floats) + +# Operational + +See examples diff --git a/libraries/PrintString/examples/printString/printString.ino b/libraries/PrintString/examples/printString/printString.ino index f17e596d..3eb5265d 100644 --- a/libraries/PrintString/examples/printString/printString.ino +++ b/libraries/PrintString/examples/printString/printString.ino @@ -1,16 +1,17 @@ // // FILE: printString.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.1.1 // PURPOSE: demo experimental +// URL: https://github.com/RobTillaart/PrintString // // HISTORY: -// 0.1.0 2017-12-09 initial version +// 0.1.0 2017-12-09 initial version +// 0.1.1 2020-04-30 align demo with latest XMLWriter lib // #include "PrintString.h" - -#include "XMLWriter.h" +#include "XMLWriter.h" // https://github.com/RobTillaart/XMLWriter PrintString ps; XMLWriter XML(&ps); @@ -41,6 +42,7 @@ void setup() XML.writeNode("Rain", "10mm"); XML.writeNode("Sun", "40"); XML.tagClose(); + XML.flush(); Serial.println(ps.getString()); @@ -50,4 +52,5 @@ void setup() void loop() { } -// END OF FILE + +// -- END OF FILE -- diff --git a/libraries/PrintString/keywords..txt b/libraries/PrintString/keywords..txt new file mode 100644 index 00000000..2ec1d773 --- /dev/null +++ b/libraries/PrintString/keywords..txt @@ -0,0 +1,13 @@ +# Syntax Coloring Map For PrintString + +# Datatypes (KEYWORD1) +PrintString KEYWORD1 + +# Methods and Functions (KEYWORD2) +write KEYWORD2 +size KEYWORD2 +clear KEYWORD2 +getString KEYWORD2 + +# Constants (LITERAL1) + diff --git a/libraries/PrintString/library.json b/libraries/PrintString/library.json index 31a45e47..785721b0 100644 --- a/libraries/PrintString/library.json +++ b/libraries/PrintString/library.json @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PrintString.git" }, - "version":"0.1.0", + "version":"0.1.2", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/PrintString" - } + "platforms": "*" } diff --git a/libraries/PrintString/library.properties b/libraries/PrintString/library.properties index 37eadb5f..2b82e24c 100644 --- a/libraries/PrintString/library.properties +++ b/libraries/PrintString/library.properties @@ -1,5 +1,5 @@ name=PrintString -version=0.1.0 +version=0.1.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library to capture prints into a String. @@ -7,4 +7,5 @@ paragraph= category=Data Processing url=https://github.com/RobTillaart/Arduino/tree/master/libraries architectures=* - +includes=PrintString.h +depends= diff --git a/libraries/PulsePattern/LICENSE b/libraries/PulsePattern/LICENSE new file mode 100644 index 00000000..4c3eaf9b --- /dev/null +++ b/libraries/PulsePattern/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2012-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/PulsePattern/PulsePattern.cpp b/libraries/PulsePattern/PulsePattern.cpp index c4b94762..afd09c79 100644 --- a/libraries/PulsePattern/PulsePattern.cpp +++ b/libraries/PulsePattern/PulsePattern.cpp @@ -1,8 +1,9 @@ // // FILE: PulsePattern.cpp // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: see PULSEPATTERN_LIB_VERSION in .h -// PURPOSE: PulsePattern library for Arduino +// VERSION: 0.1.2 +// DATE: 2012-11-23 +// PURPOSE: Arduino Library to generate repeating pulse patterns // // HISTORY: // 0.0.1 - 2012-11-23 initial version @@ -12,29 +13,14 @@ // 0.0.5 - 2012-12-27 code cleanup+comment // 0.0.6 - 2015-04-18 completed the state machine // 0.0.7 - 2017-07-16 refactor & review -// -// Released to the public domain -// -// TODO -// - fast function iso array to return the next period? -// more adaptive to e.g. sensor values. (investigate) -// - test PRE 1.0 backwards compatibility -// - move code to .h file so compiler can inline? -// - optimize timer code -// - adjust timing to more accurate values -> setTimer() -// - worker should be private - how??? -// - test invalid array periods -// - start en stop index ipv size? -// - pulsepattern recorder -// +// 0.0.8 - 2018-12-13 refactor -> remove some warnings +// 0.1.0 2020-06-19 #pragma once; remove pre 1.0 support; refactor +// 0.1.1 2020-07-04 add continue function, fix spaces. +// 0.1.2 2020-08-07 speed up toggle pin + get/setFactor() + #include "PulsePattern.h" -#if defined(ARDUINO) && ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif // Predefined generator (singleton) PulsePattern PPGenerator; @@ -55,29 +41,39 @@ PulsePattern::PulsePattern() _pin = 0; } -void PulsePattern::init(uint8_t pin, uint16_t * ar, uint8_t size, -uint8_t level, uint8_t prescaler) +void PulsePattern::init(const uint8_t pin, const uint16_t * ar, const uint8_t size, +const uint8_t level, const uint8_t prescaler) { _pin = pin; pinMode(_pin, OUTPUT); stop(); - _ar = ar; + _ar = (uint16_t *) ar; _size = size; - // TODO: run over the array to test invalid values? - // constrain them 10-4095? - _level = constrain(level, LOW, HIGH); + _level = level ? LOW : HIGH; _prescaler = constrain(prescaler, PRESCALE_1, PRESCALE_1024); _cnt = 0; digitalWrite(_pin, _level); _state = STOPPED; + + // fast low level AVR ports + uint8_t _pinport = digitalPinToPort(_pin); + _pinout = portOutputRegister(_pinport); + _pinbit = digitalPinToBitMask(_pin); } void PulsePattern::start() { - if (_size == 0) return; // no pattern if (_state == RUNNING) return; // no restart + _cnt = 0; // start from begin + cont(); +} + +void PulsePattern::cont() +{ + if (_state == RUNNING) return; // no continue + if (_size == 0) return; // no pattern setTimer(1); // start asap _state = RUNNING; } @@ -95,14 +91,21 @@ void PulsePattern::worker() if (_state != RUNNING) return; // set next period & flip signal _level = !_level; - // direct port faster - digitalWrite(_pin, _level); - // TODO: adjustment needed for code overhead when micros?; - // + 5.2 usec for digitalWrite - // + 3 usec for settimer call - OCR1A = (_ar[_cnt]) * (F_CPU/1000000L); + // digitalWrite(_pin, _level); + // direct port much faster + if (_level == 0) *_pinout &= ~_pinbit; + else *_pinout |= _pinbit; + + if (_factor != 4096) + { + OCR1A = _ar[_cnt] * _factor * (F_CPU/1000000UL) / 4096; + } + else + { + OCR1A = _ar[_cnt] * (F_CPU/1000000UL); + } _cnt++; - if (_cnt >= _size) _cnt = 0; // repeat + if (_cnt >= _size) _cnt = 0; // repeat pattern } // TIMER code based upon - http://www.gammon.com.au/forum/?id=11504 @@ -112,21 +115,20 @@ void PulsePattern::stopTimer() TCCR1B = 0; } -// TODO: can be optimized? void PulsePattern::setTimer(const uint16_t cc) const { - TCCR1A = 0; + TCCR1A = 0; // stop timer first TCCR1B = 0; - TCNT1 = 0; // reset counter - OCR1A = cc * 16; // compare A register value; + TCNT1 = 0; // reset counter + OCR1A = cc * 16; // compare A register value; // * 16 makes max period 4095 // min period 12? // 4: CTC mode, top = OCR1A - TCCR1A = _BV (COM1A1); // clear on compare + TCCR1A = _BV (COM1A1); // clear on compare TCCR1B = _BV (WGM12) | _prescaler; TIFR1 |= _BV (OCF1A); // clear interrupt flag TIMSK1 = _BV (OCIE1A); // interrupt on Compare A Match } -// END OF FILE \ No newline at end of file +// -- END OF FILE -- diff --git a/libraries/PulsePattern/PulsePattern.h b/libraries/PulsePattern/PulsePattern.h index 4a10635d..a1a91110 100644 --- a/libraries/PulsePattern/PulsePattern.h +++ b/libraries/PulsePattern/PulsePattern.h @@ -1,59 +1,71 @@ -#ifndef PulsePattern_h -#define PulsePattern_h +#pragma once // // FILE: PulsePattern.h // AUTHOR: Rob dot Tillaart at gmail dot com -// PURPOSE: PulsePattern library for Arduino +// VERSION: 0.1.2 +// DATE: 2012-11-23 +// PURPOSE: Arduino Library to generate repeating pulse patterns // sends a pulse pattern to a digital pin (continuously) // HISTORY: See PulsePattern.cpp // -// Released to the public domain -// -#include +#if !defined(__AVR__) + #error "Only support for AVR boards" +#endif + +#include "Arduino.h" + +#define PULSEPATTERN_LIB_VERSION "0.1.2" -#define PULSEPATTERN_LIB_VERSION "0.0.7" #define NOTINIT -1 #define STOPPED 0 #define RUNNING 1 -#define NO_CLOCK 0 -#define PRESCALE_1 1 -#define PRESCALE_8 2 -#define PRESCALE_64 3 -#define PRESCALE_256 4 -#define PRESCALE_1024 5 +#define NO_CLOCK 0 // timer off +#define PRESCALE_1 1 +#define PRESCALE_8 2 +#define PRESCALE_64 3 +#define PRESCALE_256 4 +#define PRESCALE_1024 5 +#define EXT_T1_FALLING 6 // external clock +#define EXT_T2_RISING 7 // external clock + class PulsePattern { public: PulsePattern(); - - void init(const uint8_t pin, - const uint16_t * ar, const uint8_t size, - const uint8_t level, const uint8_t prescaler); - void start(); - void stop(); - bool isRunning() const { return _state == RUNNING; }; + void init(const uint8_t pin, + const uint16_t * ar, const uint8_t size, + const uint8_t level, const uint8_t prescaler); - void worker(); + void setFactor(float perc) { _factor = round(4096 * (1 + perc)); }; + float getFactor() { return _factor / 4096.0 - 1; }; + void start(); + void cont(); + void stop(); + bool isRunning() const { return _state == RUNNING; }; + + void worker(); private: - void stopTimer(); - void setTimer(const uint16_t cc) const; - + void stopTimer(); + void setTimer(const uint16_t cc) const; + + uint32_t _factor = 4096; uint16_t * _ar; - uint8_t _size; - uint8_t _pin; - uint8_t _prescaler; - volatile uint8_t _level; - volatile int8_t _state; - volatile uint8_t _cnt; + uint8_t _size; + uint8_t _pin; + uint8_t _pinbit; + volatile uint8_t * _pinout; + uint8_t _prescaler; + volatile uint8_t _level; + volatile int8_t _state; + volatile uint8_t _cnt; }; extern PulsePattern PPGenerator; -#endif -// END OF FILE \ No newline at end of file +// -- END OF FILE -- diff --git a/libraries/PulsePattern/README.md b/libraries/PulsePattern/README.md new file mode 100644 index 00000000..e5fae86d --- /dev/null +++ b/libraries/PulsePattern/README.md @@ -0,0 +1,58 @@ +# PulsePattern + +Arduino Library to generate repeating pulse patterns **AVR ONLY** + +## Description + +This is an **experimental** library to generate pulse patterns by means of an Arduino UNO. +As the library uses **AVR hardware timers** it is definitely **NOT** working for ESP +or other non-AVR processors. + +The library uses timer1 for the timing of the pulses. +Therefor the class is implemented with a static instance called PPO. +Still by calling init() one can change all parameters of the process. +One should note that calling init() forces the timer to stop. + +The timer code is based upon the website of Nick Gammon which +holds quite a lot of good solid material (Thanks Nick!). +https://gammon.com.au/forum/bbshowpost.php?bbtopic_id=123 + +Use with care. + +## Interface + +- **PulsePattern()** constructor +- **init(pin, \*ar, size, level, prescaler)** initializer of the Timer1 +* pin that outputs the pattern +* array of durations +* size (or part) of the array to be used +* starting level HIGH/LOW +* prescaler, one of the 5 defines from .h file (table below) +- **setFactor(perc)** percentage = factor to correct timing (relative). +- **getFactor()** get the internal used factor. Due to rounding it can be slightly different. +- **stop()** stop the pattern generator +- **start()** start the pattern generator +- **cont()** continue the pattern generator from the last stopped place (approx). +- **isRunning()** status indicator +- **worker()** must be public otherwise the ISR cannot call it. +There is some bad understood __vector_11() error when worker() is private. + +### Prescaler constants + +| Value | Prescaler | Timer1 | notes | +|:----:|:----|:----|:----:| +| 0 | NO_CLOCK | timer off | | +| 1 | PRESCALE_1 | clk / 1 | | +| 2 | PRESCALE_8 | clk / 8 | | +| 3 | PRESCALE_64 | clk / 64 | | +| 4 | PRESCALE_256 | clk / 250 | | +| 5 | PRESCALE_1024 | clk / 1024 | about 1 ms / pulse | +| 6 | EXT_T1_FALLING | T1 = pin 5 | not tested | +| 7 | EXT_T2_RISING | | not tested | + + +### + +# Operation + +See example diff --git a/libraries/PulsePattern/examples/SOS_demo2/SOS_demo2.ino b/libraries/PulsePattern/examples/SOS_demo2/SOS_demo2.ino index 87649762..0d3eaf88 100644 --- a/libraries/PulsePattern/examples/SOS_demo2/SOS_demo2.ino +++ b/libraries/PulsePattern/examples/SOS_demo2/SOS_demo2.ino @@ -1,39 +1,36 @@ // -// FILE: SOS_demo2.pde +// FILE: SOS_demo2.ino // AUTHOR: Rob Tillaart // DATE: 2012-11-23 // // PUPROSE: demo of the PulsePattern Library // uses timer1 -// + #include "PulsePattern.h" // a pattern consists of durations of LOW and HIGH periods -// so the first line of the SOSpattern is +// so the first line of the SOSpattern is // 500 units LOW, 500 units HIGH etc // for a dutycycle of 50% LOW and HIGH should have equal periods // NOTE max period = 4095. -// min period = about 12 -uint16_t SOSpattern[] = { - 500,500,500,500,500,1500, // SOS in morse - 1500,500,1500,500,1500,1500, - 500,500,500,500,500,1500 }; - -uint16_t XYZpattern[] = { - 100,100,100,100,100,100, // SOS in morse - 500,500,500,500,500,500, - 1000,1000,1000,1000,1000,1000 }; +// min period = about 12 +uint16_t SOSpattern[] = +{ + 500,500,500,500,500,1500, // SOS in morse + 1500,500,1500,500,1500,1500, + 500,500,500,500,500,1500 +}; uint8_t patternSize = 18; uint8_t startLevel = LOW; void setup() { - Serial.begin(9600); - Serial.println("Start PulsePattern"); + Serial.begin(115200); + Serial.println(__FILE__); - // as the prescaler = 1024 the periods of the pattern are a + // as the prescaler = 1024 the periods of the pattern are a // few percent less than a millisecond PPGenerator.init(13, SOSpattern, patternSize, startLevel, PRESCALE_1024); PPGenerator.start(); diff --git a/libraries/PulsePattern/examples/pattern_recorder/pattern_recorder.ino b/libraries/PulsePattern/examples/pattern_recorder/pattern_recorder.ino new file mode 100644 index 00000000..2c342033 --- /dev/null +++ b/libraries/PulsePattern/examples/pattern_recorder/pattern_recorder.ino @@ -0,0 +1,60 @@ +// +// FILE: pattern_recorder.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: records and writes a pattern to serial +// DATE: 2020-07-25 + +#include "Arduino.h" + +uint8_t pin = 4; +uint16_t minDuration = 50; +uint16_t units = 10; +uint32_t counter = 0; +uint32_t sum = 0; + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); +} + +void loop() +{ + uint32_t duration = recordPulse(pin, units, minDuration); + sum += duration; + counter++; + Serial.print(duration); + Serial.print("\t"); + Serial.println(sum/counter); +} + +uint32_t recordPulse(uint8_t pin, uint16_t unit, uint16_t minperiod) +{ + static uint8_t state; + static uint32_t start; + static bool first = true; + if (first) + { + first = false; + pinMode(pin, INPUT_PULLUP); + state = digitalRead(pin); + start = millis(); + } + uint8_t newState = state; + while ((millis() - start) < minperiod - unit); + + uint32_t now = millis(); + while (newState == state) + { + while (millis() - now < unit); + now = millis(); + newState = digitalRead(pin); + } + state = newState; + uint32_t duration = (now - start + unit - 1) / unit; + start = now; + return duration; +} + +// -- END OF FILE -- diff --git a/libraries/PulsePattern/examples/random_pattern/random_pattern.ino b/libraries/PulsePattern/examples/random_pattern/random_pattern.ino new file mode 100644 index 00000000..ebdf23f1 --- /dev/null +++ b/libraries/PulsePattern/examples/random_pattern/random_pattern.ino @@ -0,0 +1,49 @@ +// +// FILE: random_pattern.ino +// AUTHOR: Rob Tillaart +// DATE: 2020-07-04 +// +// PUPROSE: demo of the PulsePattern Library +// uses timer1 +// + +#include "PulsePattern.h" + +// a pattern constants of durations of LOW and HIGH periods +// so the first line of the SOSpattern + +// 500 units LOW, 500 units HIGH etc +// for a dutycycle of 50% LOW and HIGH should have equal periods +// NOTE max period = 4095. +// min period = about 12 +uint16_t random_pattern[] = { 500, 500 }; +uint8_t patternSize = 2; +uint8_t startLevel = LOW; + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + // as the prescaler = 1024 the periods of the pattern are a + // few percent less than a millisecond + PPGenerator.init(13, random_pattern, patternSize, startLevel, PRESCALE_1024); + PPGenerator.start(); +} + +void loop() +{ + random_pattern[0] = 100 + millis() % 1000; + random_pattern[1] = 100 + micros() % 1000; + Serial.print(millis()); + Serial.print('\t'); + Serial.print(micros()); + Serial.print('\t'); + Serial.print(random_pattern[0]); + Serial.print('\t'); + Serial.print(random_pattern[1]); + Serial.println(); + delay(5000); +} + +// -- END OF FILE -- diff --git a/libraries/PulsePattern/examples/siren_pattern/siren_pattern.ino b/libraries/PulsePattern/examples/siren_pattern/siren_pattern.ino new file mode 100644 index 00000000..d324c1e4 --- /dev/null +++ b/libraries/PulsePattern/examples/siren_pattern/siren_pattern.ino @@ -0,0 +1,38 @@ +// +// FILE: siren_pattern.ino +// AUTHOR: Rob Tillaart +// DATE: 2012-11-23 +// +// PUPROSE: demo of the PulsePattern Library +// uses timer1 +// + +#include "PulsePattern.h" + +// a pattern consists of durations of LOW and HIGH periods +// NOTE max period = 4095. +// min period = about 12 +uint16_t pattern[] = +{ + 1500, 1500, 1400, 1400, 1300, 1300, 1200, 1200, 1100, 1100, + 1000, 1000, 900, 900, 800, 800, 700, 700, 600, 600, + 500, 500, 400, 400, 300, 300, 200, 200, 100, 100 +}; + +uint8_t patternSize = 30; +uint8_t startLevel = LOW; + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + PPGenerator.init(13, pattern, patternSize, startLevel, PRESCALE_1024); + PPGenerator.start(); +} + +void loop() +{ + Serial.println(millis()); + delay(1000); +} diff --git a/libraries/PulsePattern/keywords.txt b/libraries/PulsePattern/keywords.txt new file mode 100644 index 00000000..a5553e55 --- /dev/null +++ b/libraries/PulsePattern/keywords.txt @@ -0,0 +1,26 @@ +# Syntax Coloring Map for PulsePattern + +# Datatypes (KEYWORD1) +PulsePattern KEYWORD1 + + +# Methods and Functions (KEYWORD2) +init KEYWORD2 +setFactor KEYWORD2 +getFactor KEYWORD2 +start KEYWORD2 +cont KEYWORD2 +stop KEYWORD2 +isRunning KEYWORD2 + + +# Constants (LITERAL1) +PULSEPATTERN_LIB_VERSION LITERAL1 +NO_CLOCK LITERAL1 +PRESCALE_1 LITERAL1 +PRESCALE_8 LITERAL1 +PRESCALE_64 LITERAL1 +PRESCALE_256 LITERAL1 +PRESCALE_1024 LITERAL1 +EXT_T1_FALLING LITERAL1 +EXT_T2_RISING LITERAL1 \ No newline at end of file diff --git a/libraries/PulsePattern/library.json b/libraries/PulsePattern/library.json index 02fb2837..6c3ec1ea 100644 --- a/libraries/PulsePattern/library.json +++ b/libraries/PulsePattern/library.json @@ -1,7 +1,7 @@ { "name": "PulsePattern", - "keywords": "Pulse,pattern,repeating", - "description": "Library to generate repeating pulse patterns. (uses timer1)", + "keywords": "Pulse, pattern, repeat", + "description": "Library to generate repeating pulse patterns. (uses timer1) AVR only", "authors": [ { @@ -13,12 +13,9 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PulsePattern.git" }, - "version":"0.0.7", + "version":"0.1.2", "frameworks": "arduino", - "platforms": "*", - "export": { - "include": "libraries/PulsePattern" - } + "platforms": "avr" } diff --git a/libraries/PulsePattern/library.properties b/libraries/PulsePattern/library.properties index 656b2e98..1609926e 100644 --- a/libraries/PulsePattern/library.properties +++ b/libraries/PulsePattern/library.properties @@ -1,9 +1,11 @@ name=PulsePattern -version=0.0.7 +version=0.1.2 author=Rob Tillaart maintainer=Rob Tillaart -sentence=Library to generate repeating pulse patterns. -paragraph=uses timer1 +sentence=Library to generate repeating pulse patterns. (AVR only) +paragraph=uses timer1 category=Signal Input/Output -url=https://github.com/RobTillaart/Arduino/tree/master/libraries/ -architectures=* \ No newline at end of file +url=https://github.com/RobTillaart/PulsePattern +architectures=avr +includes=PulsePattern.h +depends=