diff --git a/PCF8574.cpp b/PCF8574.cpp index 1bf1b5a..9a235b0 100644 --- a/PCF8574.cpp +++ b/PCF8574.cpp @@ -149,50 +149,90 @@ void PCF8574::readBuffer(bool force){ } } -/** - * Read value of all INPUT pin - * Debounce read more fast than 10millis, non managed for interrupt mode - * @return - */ -PCF8574::DigitalInput PCF8574::digitalReadAll(void){ - DEBUG_PRINTLN("Read from buffer"); - Wire.requestFrom(_address,(uint8_t)1);// Begin transmission to PCF8574 with the buttons - lastReadMillis = millis(); - if(Wire.available()) // If bytes are available to be recieved - { - DEBUG_PRINTLN("Data ready"); - byte iInput = Wire.read();// Read a byte +#ifndef PCF8574_LOW_MEMORY + /** + * Read value of all INPUT pin + * Debounce read more fast than 10millis, non managed for interrupt mode + * @return + */ + PCF8574::DigitalInput PCF8574::digitalReadAll(void){ + DEBUG_PRINTLN("Read from buffer"); + Wire.requestFrom(_address,(uint8_t)1);// Begin transmission to PCF8574 with the buttons + lastReadMillis = millis(); + if(Wire.available()) // If bytes are available to be recieved + { + DEBUG_PRINTLN("Data ready"); + byte iInput = Wire.read();// Read a byte - if ((iInput & readMode)>0){ - DEBUG_PRINT("Input "); - DEBUG_PRINTLN((byte)iInput, BIN); + if ((iInput & readMode)>0){ + DEBUG_PRINT("Input "); + DEBUG_PRINTLN((byte)iInput, BIN); - byteBuffered = byteBuffered | (byte)iInput; - DEBUG_PRINT("byteBuffered "); - DEBUG_PRINTLN(byteBuffered, BIN); - } - } + byteBuffered = byteBuffered | (byte)iInput; + DEBUG_PRINT("byteBuffered "); + DEBUG_PRINTLN(byteBuffered, BIN); + } + } - DEBUG_PRINT("Buffer value "); - DEBUG_PRINTLN(byteBuffered, BIN); - - if ((bit(0) & readMode)>0) digitalInput.p0 = ((byteBuffered & bit(0))>0)?HIGH:LOW; - if ((bit(1) & readMode)>0) digitalInput.p1 = ((byteBuffered & bit(1))>0)?HIGH:LOW; - if ((bit(2) & readMode)>0) digitalInput.p2 = ((byteBuffered & bit(2))>0)?HIGH:LOW; - if ((bit(3) & readMode)>0) digitalInput.p3 = ((byteBuffered & bit(3))>0)?HIGH:LOW; - if ((bit(4) & readMode)>0) digitalInput.p4 = ((byteBuffered & bit(4))>0)?HIGH:LOW; - if ((bit(5) & readMode)>0) digitalInput.p5 = ((byteBuffered & bit(5))>0)?HIGH:LOW; - if ((bit(6) & readMode)>0) digitalInput.p6 = ((byteBuffered & bit(6))>0)?HIGH:LOW; - if ((bit(7) & readMode)>0) digitalInput.p7 = ((byteBuffered & bit(7))>0)?HIGH:LOW; - - if ((readMode & byteBuffered)>0){ - byteBuffered = ~readMode & byteBuffered; - DEBUG_PRINT("Buffer hight value readed set readed "); + DEBUG_PRINT("Buffer value "); DEBUG_PRINTLN(byteBuffered, BIN); - } - DEBUG_PRINT("Return value "); - return digitalInput; -}; + + if ((bit(0) & readMode)>0) digitalInput.p0 = ((byteBuffered & bit(0))>0)?HIGH:LOW; + if ((bit(1) & readMode)>0) digitalInput.p1 = ((byteBuffered & bit(1))>0)?HIGH:LOW; + if ((bit(2) & readMode)>0) digitalInput.p2 = ((byteBuffered & bit(2))>0)?HIGH:LOW; + if ((bit(3) & readMode)>0) digitalInput.p3 = ((byteBuffered & bit(3))>0)?HIGH:LOW; + if ((bit(4) & readMode)>0) digitalInput.p4 = ((byteBuffered & bit(4))>0)?HIGH:LOW; + if ((bit(5) & readMode)>0) digitalInput.p5 = ((byteBuffered & bit(5))>0)?HIGH:LOW; + if ((bit(6) & readMode)>0) digitalInput.p6 = ((byteBuffered & bit(6))>0)?HIGH:LOW; + if ((bit(7) & readMode)>0) digitalInput.p7 = ((byteBuffered & bit(7))>0)?HIGH:LOW; + + if ((readMode & byteBuffered)>0){ + byteBuffered = ~readMode & byteBuffered; + DEBUG_PRINT("Buffer hight value readed set readed "); + DEBUG_PRINTLN(byteBuffered, BIN); + } + DEBUG_PRINT("Return value "); + return digitalInput; + }; +#else + /** + * Read value of all INPUT pin in byte format for low memory usage + * Debounce read more fast than 10millis, non managed for interrupt mode + * @return + */ + byte PCF8574::digitalReadAll(void){ + DEBUG_PRINTLN("Read from buffer"); + Wire.requestFrom(_address,(uint8_t)1);// Begin transmission to PCF8574 with the buttons + lastReadMillis = millis(); + if(Wire.available()) // If bytes are available to be recieved + { + DEBUG_PRINTLN("Data ready"); + byte iInput = Wire.read();// Read a byte + + if ((iInput & readMode)>0){ + DEBUG_PRINT("Input "); + DEBUG_PRINTLN((byte)iInput, BIN); + + byteBuffered = byteBuffered | (byte)iInput; + DEBUG_PRINT("byteBuffered "); + DEBUG_PRINTLN(byteBuffered, BIN); + } + } + + DEBUG_PRINT("Buffer value "); + DEBUG_PRINTLN(byteBuffered, BIN); + + byte byteRead = byteBuffered; + + if ((readMode & byteBuffered)>0){ + byteBuffered = ~readMode & byteBuffered; + DEBUG_PRINT("Buffer hight value readed set readed "); + DEBUG_PRINTLN(byteBuffered, BIN); + } + DEBUG_PRINT("Return value "); + return byteRead; + }; +#endif /** * Read value of specified pin diff --git a/PCF8574.h b/PCF8574.h index 80b5645..87036e4 100644 --- a/PCF8574.h +++ b/PCF8574.h @@ -18,6 +18,9 @@ // Uncomment to enable printing out nice debug messages. // #define PCF8574_DEBUG +// Uncomment for low memory usage this prevent use of complex DigitalInput structure and free 7byte of memory +// #define PCF8574_LOW_MEMORY + // Define where debug output will be printed. #define DEBUG_PRINTER Serial @@ -55,16 +58,6 @@ class PCF8574 { public: - struct DigitalInput { - uint8_t p0; - uint8_t p1; - uint8_t p2; - uint8_t p3; - uint8_t p4; - uint8_t p5; - uint8_t p6; - uint8_t p7; - } digitalInput; PCF8574(uint8_t address); PCF8574(uint8_t address, uint8_t sda, uint8_t scl); @@ -77,7 +70,23 @@ public: void readBuffer(bool force = true); uint8_t digitalRead(uint8_t pin); - DigitalInput digitalReadAll(void); + #ifndef PCF8574_LOW_MEMORY + struct DigitalInput { + uint8_t p0; + uint8_t p1; + uint8_t p2; + uint8_t p3; + uint8_t p4; + uint8_t p5; + uint8_t p6; + uint8_t p7; + } digitalInput; + + + DigitalInput digitalReadAll(void); + #else + byte digitalReadAll(void); + #endif void digitalWrite(uint8_t pin, uint8_t value); private: diff --git a/examples/readAll_Interrupt_lowMemory/readAll_Interrupt_lowMemory.ino b/examples/readAll_Interrupt_lowMemory/readAll_Interrupt_lowMemory.ino new file mode 100644 index 0000000..bc87f6f --- /dev/null +++ b/examples/readAll_Interrupt_lowMemory/readAll_Interrupt_lowMemory.ino @@ -0,0 +1,46 @@ +#include "Arduino.h" +#include "PCF8574.h" + +// To use in low memory mode and prevent use of 7byte you must decomment the line +// #define PCF8574_LOW_MEMORY +// in the library + +// For arduino uno only pin 1 and 2 are interrupted +#define ARDUINO_UNO_INTERRUPTED_PIN 2 + +// Function interrupt +void keyChangedOnPCF8574(); + +// Set i2c address +PCF8574 pcf8574(0x39, ARDUINO_UNO_INTERRUPTED_PIN, keyChangedOnPCF8574); +unsigned long timeElapsed; +void setup() +{ + Serial.begin(115200); + + pcf8574.pinMode(P0, INPUT); + pcf8574.pinMode(P1, INPUT); + pcf8574.pinMode(P2, INPUT); + pcf8574.begin(); + + Serial.println("START"); + + timeElapsed = millis(); +} + +bool keyChanged = false; +void loop() +{ + if (keyChanged){ + byte di = pcf8574.digitalReadAll(); + Serial.print("READ VALUE FROM PCF: "); + Serial.println(di, BIN); +// delay(5); + keyChanged= false; + } +} + +void keyChangedOnPCF8574(){ + // Interrupt called (No Serial no read no wire in this function, and DEBUG disabled on PCF library) + keyChanged = true; +}