mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
update libraries M..P
This commit is contained in:
parent
de6544a719
commit
9abe1508b1
21
libraries/NibbleArray/LICENSE
Normal file
21
libraries/NibbleArray/LICENSE
Normal file
@ -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.
|
29
libraries/NibbleArray/README.md
Normal file
29
libraries/NibbleArray/README.md
Normal file
@ -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
|
||||
|
||||
|
@ -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 --
|
@ -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 --
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
name=NibbleArray
|
||||
version=0.1.0
|
||||
version=0.2.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
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=*
|
||||
architectures=*
|
||||
includes=nibbleArray.h
|
||||
depends=
|
||||
|
@ -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
|
||||
//
|
||||
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 --
|
||||
|
@ -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 <WProgram.h>
|
||||
#else
|
||||
#include <Arduino.h>
|
||||
|
||||
#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
|
||||
//
|
||||
|
||||
// -- END OF FILE --
|
||||
|
21
libraries/PCA9635/LICENSE
Normal file
21
libraries/PCA9635/LICENSE
Normal file
@ -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.
|
@ -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 <Wire.h>
|
||||
|
||||
|
||||
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
|
||||
//
|
||||
// -- END OF FILE --
|
||||
|
@ -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 --
|
||||
|
76
libraries/PCA9635/README.md
Normal file
76
libraries/PCA9635/README.md
Normal file
@ -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
|
@ -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 --
|
||||
|
@ -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 <Wire.h>
|
||||
|
||||
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 --
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
name=PCA9635
|
||||
version=0.1.2
|
||||
version=0.2.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
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=*
|
||||
url=https://github.com/RobTillaart/PCA9635
|
||||
architectures=*
|
||||
includes=PCA9635.h
|
||||
depends=
|
||||
|
21
libraries/PCA9685/LICENSE
Normal file
21
libraries/PCA9685/LICENSE
Normal file
@ -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.
|
@ -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 <Wire.h>
|
||||
#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
|
||||
//
|
||||
// -- END OF FILE --
|
||||
|
@ -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
|
||||
//
|
||||
// -- END OF FILE --
|
||||
|
89
libraries/PCA9685/README.md
Normal file
89
libraries/PCA9685/README.md
Normal file
@ -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
|
@ -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 --
|
@ -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 --
|
@ -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 --
|
@ -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 --
|
@ -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 --
|
@ -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 --
|
||||
|
@ -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 <Wire.h>
|
||||
|
||||
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 --
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
name=PCA9685
|
||||
version=0.1.1
|
||||
name=PCA9685_RT
|
||||
version=0.3.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
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=*
|
||||
url=https://github.com/RobTillaart/PCA9685_RT
|
||||
architectures=*
|
||||
includes=PCA9685.h
|
||||
depends=Wire
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=PCF8574
|
||||
version=0.1.9
|
||||
version=0.2.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for PCF8574 - I2C IO expander
|
||||
|
21
libraries/Par27979/LICENSE
Normal file
21
libraries/Par27979/LICENSE
Normal file
@ -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.
|
@ -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 --
|
||||
|
78
libraries/Par27979/examples/PAR27979_demo/PAR27979_demo.ino
Normal file
78
libraries/Par27979/examples/PAR27979_demo/PAR27979_demo.ino
Normal file
@ -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.h>
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
@ -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 --
|
28
libraries/Par27979/keywords.txt
Normal file
28
libraries/Par27979/keywords.txt
Normal file
@ -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)
|
||||
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
name=Par27979
|
||||
version=0.1.0
|
||||
name=PAR27979
|
||||
version=0.2.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Defines for Parallax 27979 serial display.
|
||||
paragraph=Supports
|
||||
category=Sensors
|
||||
url=https://github.com/RobTillaart/Arduino/tree/master/libraries/
|
||||
architectures=*
|
||||
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=
|
||||
|
@ -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
|
||||
|
1
libraries/ParPrinter/replaced by parallelPrinter.txt
Normal file
1
libraries/ParPrinter/replaced by parallelPrinter.txt
Normal file
@ -0,0 +1 @@
|
||||
https://github.com/RobTillaart/ParallelPrinter
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=PinInGroup
|
||||
version=0.1.1
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=A class that groups input pins so they can be read in one logical step.
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=PinOutGroup
|
||||
version=0.1.1
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=A class that groups output pins so they can be updated easier and slightly faster on average.
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=Prandom
|
||||
version=0.1.1
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for random number generation with Python random interface.
|
||||
|
21
libraries/PrintCharArray/LICENSE
Normal file
21
libraries/PrintCharArray/LICENSE
Normal file
@ -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.
|
@ -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 --
|
||||
|
@ -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 --
|
||||
|
@ -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 --
|
||||
|
@ -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 --
|
||||
|
@ -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 --
|
||||
|
@ -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 --
|
14
libraries/PrintCharArray/keywords..txt
Normal file
14
libraries/PrintCharArray/keywords..txt
Normal file
@ -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)
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
name=PrintCharArray
|
||||
version=0.1.0
|
||||
version=0.2.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
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=
|
||||
|
||||
|
@ -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
|
||||
|
21
libraries/PrintSize/LICENSE
Normal file
21
libraries/PrintSize/LICENSE
Normal file
@ -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.
|
@ -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 --
|
||||
|
@ -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 --
|
||||
|
@ -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 --
|
@ -52,3 +52,5 @@ void printSpaces(uint8_t n)
|
||||
{
|
||||
while (n--) Serial.print(' ');
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -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 --
|
12
libraries/PrintSize/keywords..txt
Normal file
12
libraries/PrintSize/keywords..txt
Normal file
@ -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)
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
name=PrintSize
|
||||
version=0.1.0
|
||||
version=0.2.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
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=
|
||||
|
@ -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
|
||||
|
21
libraries/PrintString/LICENSE
Normal file
21
libraries/PrintString/LICENSE
Normal file
@ -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.
|
@ -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 --
|
||||
|
19
libraries/PrintString/README.md
Normal file
19
libraries/PrintString/README.md
Normal file
@ -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
|
@ -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 --
|
||||
|
13
libraries/PrintString/keywords..txt
Normal file
13
libraries/PrintString/keywords..txt
Normal file
@ -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)
|
||||
|
@ -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": "*"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=PrintString
|
||||
version=0.1.0
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
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=
|
||||
|
21
libraries/PulsePattern/LICENSE
Normal file
21
libraries/PulsePattern/LICENSE
Normal file
@ -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.
|
@ -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
|
||||
// -- END OF FILE --
|
||||
|
@ -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 <inttypes.h>
|
||||
#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
|
||||
// -- END OF FILE --
|
||||
|
58
libraries/PulsePattern/README.md
Normal file
58
libraries/PulsePattern/README.md
Normal file
@ -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
|
@ -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();
|
||||
|
@ -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 --
|
@ -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 --
|
@ -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);
|
||||
}
|
26
libraries/PulsePattern/keywords.txt
Normal file
26
libraries/PulsePattern/keywords.txt
Normal file
@ -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
|
@ -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"
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
name=PulsePattern
|
||||
version=0.0.7
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
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=*
|
||||
url=https://github.com/RobTillaart/PulsePattern
|
||||
architectures=avr
|
||||
includes=PulsePattern.h
|
||||
depends=
|
||||
|
Loading…
Reference in New Issue
Block a user