Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion Centipede.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <Wire.h>

uint8_t CSDataArray[2] = {0};
#ifdef CS_CACHE
uint8_t CSDataCacheArray[16] = {0};
#endif

#define CSAddress 0b0100000

Expand Down Expand Up @@ -41,6 +44,13 @@ void Centipede::initialize()
}


#ifdef CS_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);
Expand Down Expand Up @@ -131,14 +141,24 @@ void Centipede::digitalWrite(int pin, int level) {

}

int Centipede::digitalRead(int pin) {
// 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 CS_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;

Expand Down Expand Up @@ -217,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;

Expand Down
10 changes: 9 additions & 1 deletion Centipede.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
#ifndef Centipede_h
#define Centipede_h

#define CS_CACHE

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

extern uint8_t CSDataArray[2];
#ifdef CS_CACHE
extern uint8_t CSDataCacheArray[16];
#endif

class Centipede
{
Expand All @@ -19,7 +24,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);
Expand All @@ -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 CS_CACHE
void StoreCache(int port);
#endif
};

#endif
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
# 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

## 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.
63 changes: 63 additions & 0 deletions examples/sample.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Example code for Centipede Library
// Works with Centipede Shield or MCP23017 on Arduino I2C port

#include <Wire.h>
#include <Centipede.h>


/* 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);
}
}