From 492098681d7962586174f36c06d95f810d482abd Mon Sep 17 00:00:00 2001 From: Daniele Palumbo Date: Wed, 5 May 2021 18:20:23 +0200 Subject: [PATCH 1/5] Added documentation to README, added sample sketch --- README.md | 23 +++++++++++++++++ examples/sample.ino | 63 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 examples/sample.ino diff --git a/README.md b/README.md index 60d707c..335812b 100644 --- a/README.md +++ b/README.md @@ -1 +1,24 @@ # Centipede Shield Library + +## Reference + +The main documentation is reported in [macetech wiki](https://docs.macetech.com/doku.php/centipede_shield) + +Nevertheless this could be outdated (eg .getIntF is missing in the wiki currently). + +## Methods + +* .digitalWrite([0...127], [LOW...HIGH]) - Acts like normal digitalWrite +* .digitalRead([0...127]) - Acts like normal digitalRead +* .pinMode([0...127], [INPUT...OUTPUT]) - Acts like normal pinMode +* .pinPullup([0...127], [LOW...HIGH]) - Activates internal 100K pullups on inputs when HIGH. +* .portWrite([0...7], [0...65535]) - Writes 16-bit value to one port (chip). Useful for writing 16 outputs at the same time. +* .portRead([0...7]) - Reads 16-bit value from one port (chip) +* .portMode([0...7], [0...65535]) - Write I/O mask to one port (chip). In binary, a 0 means output and a 1 means input. Easier to use than a long list of pinMode() commands. +* .portPullup([0...7], [0...65535]) - Sets pullups on one port (chip). In binary, a 0 means no pullup and a 1 means pullup is active. +* .portInterrupts([0...7],[0...65535],[0...65535],[0...65535]) - Configure interrupts +* [device number],[use interrupt on pin],[default value],[interrupt when != default] +* .portCaptureRead(0...7) - Reads 16-bit value registers as they were when interrupt occurred +* .getIntF(0..7) - These return an interrupt flag state that allows you to determine which port (device) produced an interrupt (and it could be more than one device). +* .init() - Sets all registers to initial values + diff --git a/examples/sample.ino b/examples/sample.ino new file mode 100644 index 0000000..c758f86 --- /dev/null +++ b/examples/sample.ino @@ -0,0 +1,63 @@ +// Example code for Centipede Library +// Works with Centipede Shield or MCP23017 on Arduino I2C port + +#include +#include + + +/* Available commands + .digitalWrite([0...127], [LOW...HIGH]) - Acts like normal digitalWrite + .digitalRead([0...127]) - Acts like normal digitalRead + .pinMode([0...127], [INPUT...OUTPUT]) - Acts like normal pinMode + .portWrite([0...7], [0...65535]) - Writes 16-bit value to one port (chip) + .portRead([0...7]) - Reads 16-bit value from one port (chip) + .portMode([0...7], [0...65535]) - Write I/O mask to one port (chip) + .pinPullup([0...127], [LOW...HIGH]) - Sets pullup on input pin + .portPullup([0...7], [0...65535]) - Sets pullups on one port (chip) + .portInterrupts([0...7],[0...65535],[0...65535],[0...65535]) - Configure interrupts + [device number],[use interrupt on pin],[default value],[interrupt when != default] + .portCaptureRead(0...7) - Reads 16-bit value registers as they were when interrupt occurred + .init() - Sets all registers to initial values + + Examples + CS.init(); + CS.pinMode(0,OUTPUT); + CS.digitalWrite(0, HIGH); + int recpin = CS.digitalRead(0); + CS.portMode(0, 0b0111111001111110); // 0 = output, 1 = input + CS.portWrite(0, 0b1000000110000001); // 0 = LOW, 1 = HIGH + int recport = CS.portRead(0); + CS.pinPullup(1,HIGH); + CS.portPullup(0, 0b0111111001111110); // 0 = no pullup, 1 = pullup + CS.portInterrupts(0,0b0000000000000001,0b0000000000000000,0b0000000000000001); +*/ + +Centipede CS; // create Centipede object + + +void setup() +{ + Wire.begin(); // start I2C + + CS.initialize(); // set all registers to default + + CS.portMode(0, 0b0000000000000000); // set all pins on chip 0 to output (0 to 15) + //CS.portMode(1, 0b0000000000000000); // set all pins on chip 1 to output (16 to 31) + + //TWBR = 12; // uncomment for 400KHz I2C (on 16MHz Arduinos) + +} + + +void loop() +{ + for (int i = 0; i < 16; i++) { + CS.digitalWrite(i, HIGH); + delay(10); + } + + for (int i = 0; i < 16; i++) { + CS.digitalWrite(i, LOW); + delay(10); + } +} From 6270258137f9babb945dbfe8a1282f0aba657bc0 Mon Sep 17 00:00:00 2001 From: Daniele Palumbo Date: Fri, 7 May 2021 15:00:03 +0200 Subject: [PATCH 2/5] Added cache option (broken) The CSDataArray will change over the time, must be fixed in advance --- Centipede.cpp | 6 ++++-- Centipede.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Centipede.cpp b/Centipede.cpp index b1862de..61f5fe5 100644 --- a/Centipede.cpp +++ b/Centipede.cpp @@ -131,12 +131,14 @@ void Centipede::digitalWrite(int pin, int level) { } -int Centipede::digitalRead(int pin) { +int Centipede::digitalRead(int pin, int cache) { int port = pin >> 4; int subregister = (pin & 8) >> 3; - ReadRegisters(port, 0x12 + subregister, 1); + if ( !cache ) { + ReadRegisters(port, 0x12 + subregister, 1); + } int returnval = (CSDataArray[0] >> (pin - ((port << 1) + subregister)*8)) & 1; diff --git a/Centipede.h b/Centipede.h index f44da08..b09ee91 100644 --- a/Centipede.h +++ b/Centipede.h @@ -19,7 +19,7 @@ class Centipede void pinMode(int pin, int mode); void pinPullup(int pin, int mode); void digitalWrite(int pin, int level); - int digitalRead(int pin); + int digitalRead(int pin, int cache = false); void portMode(int port, int value); void portPullup(int port, int value); void portWrite(int port, int value); From 607cc57244edfb7a3a4769831d1584bd63388305 Mon Sep 17 00:00:00 2001 From: Daniele Palumbo Date: Fri, 7 May 2021 16:23:13 +0200 Subject: [PATCH 3/5] fully working cache functionalities Added # with '#' will be ignored, and an empty message aborts the commit. --- Centipede.cpp | 18 ++++++++++++++++++ Centipede.h | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/Centipede.cpp b/Centipede.cpp index 61f5fe5..c285686 100644 --- a/Centipede.cpp +++ b/Centipede.cpp @@ -10,6 +10,9 @@ #include uint8_t CSDataArray[2] = {0}; +#ifdef CACHE +uint8_t CSDataCacheArray[16] = {0}; +#endif #define CSAddress 0b0100000 @@ -41,6 +44,13 @@ void Centipede::initialize() } +#ifdef CACHE +void Centipede::StoreCache(int port) { + CSDataCacheArray[port] = CSDataArray[0]; + CSDataCacheArray[port+1] = CSDataArray[1]; +} +#endif + void Centipede::WriteRegisters(int port, int startregister, int quantity) { Wire.beginTransmission(CSAddress + port); @@ -131,16 +141,24 @@ void Centipede::digitalWrite(int pin, int level) { } +// While the cache parameter is always taken in input, it will be effective only once CACHE is defined in Centipede.h file int Centipede::digitalRead(int pin, int cache) { int port = pin >> 4; int subregister = (pin & 8) >> 3; +#ifdef CACHE if ( !cache ) { ReadRegisters(port, 0x12 + subregister, 1); + StoreCache(port); } + int returnval = (CSDataCacheArray[port] >> (pin - ((port << 1) + subregister)*8)) & 1; +#else + ReadRegisters(port, 0x12 + subregister, 1); + int returnval = (CSDataArray[0] >> (pin - ((port << 1) + subregister)*8)) & 1; +#endif return returnval; diff --git a/Centipede.h b/Centipede.h index b09ee91..293412a 100644 --- a/Centipede.h +++ b/Centipede.h @@ -4,6 +4,8 @@ #ifndef Centipede_h #define Centipede_h +//#define CACHE + #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else @@ -11,6 +13,9 @@ #endif extern uint8_t CSDataArray[2]; +#ifdef CACHE +extern uint8_t CSDataCacheArray[16]; +#endif class Centipede { @@ -33,6 +38,9 @@ class Centipede void WriteRegisters(int port, int startregister, int quantity); void ReadRegisters(int port, int startregister, int quantity); void WriteRegisterPin(int port, int regpin, int subregister, int level); +#ifdef CACHE + void StoreCache(int port); +#endif }; #endif From 0c4e3cd76abe60f58d20f2fc787638cd00947cf9 Mon Sep 17 00:00:00 2001 From: Daniele Palumbo Date: Sat, 8 May 2021 09:26:29 +0200 Subject: [PATCH 4/5] Finalized the CS_CACHE define --- Centipede.cpp | 8 ++++---- Centipede.h | 6 +++--- README.md | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Centipede.cpp b/Centipede.cpp index c285686..7129711 100644 --- a/Centipede.cpp +++ b/Centipede.cpp @@ -10,7 +10,7 @@ #include uint8_t CSDataArray[2] = {0}; -#ifdef CACHE +#ifdef CS_CACHE uint8_t CSDataCacheArray[16] = {0}; #endif @@ -44,7 +44,7 @@ void Centipede::initialize() } -#ifdef CACHE +#ifdef CS_CACHE void Centipede::StoreCache(int port) { CSDataCacheArray[port] = CSDataArray[0]; CSDataCacheArray[port+1] = CSDataArray[1]; @@ -141,13 +141,13 @@ void Centipede::digitalWrite(int pin, int level) { } -// While the cache parameter is always taken in input, it will be effective only once CACHE is defined in Centipede.h file +// While the cache parameter is always taken in input, it will be effective only once CS_CACHE is defined in Centipede.h file int Centipede::digitalRead(int pin, int cache) { int port = pin >> 4; int subregister = (pin & 8) >> 3; -#ifdef CACHE +#ifdef CS_CACHE if ( !cache ) { ReadRegisters(port, 0x12 + subregister, 1); StoreCache(port); diff --git a/Centipede.h b/Centipede.h index 293412a..f8307ac 100644 --- a/Centipede.h +++ b/Centipede.h @@ -4,7 +4,7 @@ #ifndef Centipede_h #define Centipede_h -//#define CACHE +#define CS_CACHE #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" @@ -13,7 +13,7 @@ #endif extern uint8_t CSDataArray[2]; -#ifdef CACHE +#ifdef CS_CACHE extern uint8_t CSDataCacheArray[16]; #endif @@ -38,7 +38,7 @@ class Centipede void WriteRegisters(int port, int startregister, int quantity); void ReadRegisters(int port, int startregister, int quantity); void WriteRegisterPin(int port, int regpin, int subregister, int level); -#ifdef CACHE +#ifdef CS_CACHE void StoreCache(int port); #endif }; diff --git a/README.md b/README.md index 335812b..cb78305 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,7 @@ Nevertheless this could be outdated (eg .getIntF is missing in the wiki currentl * .getIntF(0..7) - These return an interrupt flag state that allows you to determine which port (device) produced an interrupt (and it could be more than one device). * .init() - Sets all registers to initial values +## Compile Options + +if `CS_CACHE` is defined, the library will use sightly more memory, but will allow `.digitalRead([0-127, [TRUE|FALSE])` where the latter parametet will define if to return the value cached or if has to be taken fresh from the port. +If you read all the 127 input from i2c, this should br faster, at the price of 512 byte of memory. From 3cf1189ed1c87fd2bd43bdc90920ea1302cb277f Mon Sep 17 00:00:00 2001 From: Daniele Palumbo Date: Sat, 8 May 2021 11:16:40 +0200 Subject: [PATCH 5/5] Added store of cache upon portRead --- Centipede.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Centipede.cpp b/Centipede.cpp index 7129711..eb506de 100644 --- a/Centipede.cpp +++ b/Centipede.cpp @@ -237,6 +237,10 @@ int Centipede::portRead(int port) { ReadRegisters(port, 0x12, 2); +#ifdef CS_CACHE + StoreCache(port); +#endif + int receivedval = CSDataArray[0]; receivedval |= CSDataArray[1] << 8;