diff --git a/src/libs/PCF8574/PCF8574.cpp b/src/libs/PCF8574/PCF8574.cpp new file mode 100644 index 0000000..22e3d31 --- /dev/null +++ b/src/libs/PCF8574/PCF8574.cpp @@ -0,0 +1,106 @@ +#include "PCF8574.h" + +PCF8574::PCF8574(uint8_t address, TwoWire &twc) : _twc(twc), _address(address), _pinConfig(0b11111111), _pddr(0b00000000) //Inputs by default +{ + +} + +boolean PCF8574::begin() +{ + _twc.begin(); + _twc.beginTransmission(_address); + _twc.write(_pinConfig); + return _twc.endTransmission() == 0; +} + +void PCF8574::pinMode(Pin pin, boolean mode) +{ + uint8_t mask = mode ? pin : pin; //0 INPUT - 1 OUTPUT + + if(mode)//OUTPUT + { + _pinConfig = _pinConfig | mask; + _pddr = _pddr | pin; + } + else + { + _pinConfig = _pinConfig | mask; + _pddr = _pddr & ~pin; + } + + _pinConfig = _pinConfig | mask; + _twc.beginTransmission(_address); + _twc.write(_pinConfig); + _twc.endTransmission(); +} + +void PCF8574::digitalWrite(Pin pin, boolean mode) +{ + //We first check that the pin is an output + if((_pddr & pin) == 0) + return; + + uint8_t mask = mode ? pin : ~pin; //0 LOW, 1 HIGH + if(mode) + _pinConfig = _pinConfig | mask; + else + _pinConfig = _pinConfig & mask; + + _twc.beginTransmission(_address); + _twc.write(_pinConfig); + _twc.endTransmission(); +} + +void PCF8574::togglePin(Pin pin) +{ + //We first check that the pin is an output + if((_pddr & pin) == 0) + return; + + _pinConfig = (_pinConfig & pin) == 0 ? _pinConfig | pin : _pinConfig & ~pin; + + _twc.beginTransmission(_address); + _twc.write(_pinConfig); + _twc.endTransmission(); +} + +boolean PCF8574::digitalRead(Pin pin) +{ + uint8_t reg = 0b00000000; + _twc.requestFrom((uint8_t)_address,(uint8_t)1,(uint8_t)true); + while(_twc.available())reg = _twc.read(); + return (reg & pin) == 0 ? 0 : 1; +} + +void PCF8574::digitalReadAll(boolean array[8]) +{ + uint8_t reg = 0b00000000; + _twc.requestFrom((uint8_t)_address,(uint8_t)1,(uint8_t)true); + while(_twc.available())reg = _twc.read(); + + array[0] = (reg & P0) == 0 ? 0 : 1; + array[1] = (reg & P1) == 0 ? 0 : 1; + array[2] = (reg & P2) == 0 ? 0 : 1; + array[3] = (reg & P3) == 0 ? 0 : 1; + array[4] = (reg & P4) == 0 ? 0 : 1; + array[5] = (reg & P5) == 0 ? 0 : 1; + array[6] = (reg & P6) == 0 ? 0 : 1; + array[7] = (reg & P7) == 0 ? 0 : 1; +} + +boolean PCF8574::getPinMode(Pin pin) +{ + return _pddr & pin == 0 ? INPUT : OUTPUT; +} + +void PCF8574::getPinModeAll(boolean array[8]) +{ + array[0] = (_pddr & P0) == 0 ? INPUT : OUTPUT; + array[1] = (_pddr & P1) == 0 ? INPUT : OUTPUT; + array[2] = (_pddr & P2) == 0 ? INPUT : OUTPUT; + array[3] = (_pddr & P3) == 0 ? INPUT : OUTPUT; + array[4] = (_pddr & P4) == 0 ? INPUT : OUTPUT; + array[5] = (_pddr & P5) == 0 ? INPUT : OUTPUT; + array[6] = (_pddr & P6) == 0 ? INPUT : OUTPUT; + array[7] = (_pddr & P7) == 0 ? INPUT : OUTPUT; +} diff --git a/src/libs/PCF8574/PCF8574.h b/src/libs/PCF8574/PCF8574.h new file mode 100644 index 0000000..d5e6086 --- /dev/null +++ b/src/libs/PCF8574/PCF8574.h @@ -0,0 +1,34 @@ +#ifndef PCF8574_H +#define PCF8574_H +#include +#include + +/*** +* A very simple class to drive a PCF8574 chip +* +* Anatole SCHRAMM-HENRY -- Th3maz1ng +***/ + +class PCF8574 +{ + public: + enum Pin{P0 = 1, P1 = 2, P2 = 4, P3 = 8, P4 = 16, P5 = 32, P6 = 64, P7 = 128}; + + PCF8574(uint8_t address, TwoWire &twc = Wire); + boolean begin(); + void pinMode(Pin pin, boolean mode = INPUT); + void digitalWrite(Pin pin, boolean mode); + boolean digitalRead(Pin pin); + void digitalReadAll(boolean array[8]); + boolean getPinMode(Pin pin); + void getPinModeAll(boolean array[8]); + void togglePin(Pin pin); + private: + TwoWire &_twc; + uint8_t _address; + uint8_t _pinConfig; + uint8_t _pddr; + protected: +}; + +#endif //PCF8574_H diff --git a/src/libs/PCF8574/examples/PCF8574.ino b/src/libs/PCF8574/examples/PCF8574.ino new file mode 100644 index 0000000..61a0ab9 --- /dev/null +++ b/src/libs/PCF8574/examples/PCF8574.ino @@ -0,0 +1,22 @@ +#include "PCF8574.h" + +//Example program with blink on P0 and digitalRead on P1 - P7 + +PCF8574 pcf(0x27); + +void setup() { + Serial.begin(9600); + // put your setup code here, to run once: + pcf.begin(); + pcf.pinMode(PCF8574::P0,OUTPUT); +} + +void loop() { + // put your main code here, to run repeatedly: + Serial.print(pcf.digitalRead(PCF8574::P0));Serial.print(pcf.digitalRead(PCF8574::P1));Serial.print(pcf.digitalRead(PCF8574::P2));Serial.print(pcf.digitalRead(PCF8574::P3));Serial.print(pcf.digitalRead(PCF8574::P4));Serial.print(pcf.digitalRead(PCF8574::P5));Serial.print(pcf.digitalRead(PCF8574::P6));Serial.println(pcf.digitalRead(PCF8574::P7)); + //pcf.digitalRead(PCF8574::P0); + pcf.digitalWrite(PCF8574::P0, HIGH); + delay(200); + pcf.digitalWrite(PCF8574::P0, LOW); + delay(200); +} diff --git a/src/libs/PCF8574/keywords.txt b/src/libs/PCF8574/keywords.txt new file mode 100644 index 0000000..6bf9833 --- /dev/null +++ b/src/libs/PCF8574/keywords.txt @@ -0,0 +1,31 @@ +####################################### +# Syntax Coloring Map For PCF8574 +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +PCF8574 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +digitalReadAll KEYWORD2 +getPinMode KEYWORD2 +getPinModeAll KEYWORD2 +togglePin KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +P0 LITERAL1 +P1 LITERAL1 +P2 LITERAL1 +P3 LITERAL1 +P4 LITERAL1 +P5 LITERAL1 +P6 LITERAL1 +P7 LITERAL1