Before connecting the Arduino Nano to the USB port, check for any shorts (direct positive voltage to ground connection) as this could damage both the Nano board and the USB/PC.
Initial testing of a I2C interfaced device (and if the I2C interface library is working on the Arduino Nano) is to use the I2C scanner sketch (Code Snippet 1 below).
Once it is determined that I2C communication is working with the Arduino Nano and the PCF8574A, the next steps are using the various libraries to set the quasi bidirectional I/O pins on the PCF8574 as both input and output. The simple example of turning LED's on/off connected to the PCF8574 pins is used to determine if correct PCF8574 pins are I/O compared to the transmitted sequences (Code Snippet 2 below).
I2C Device Address Scanner
The I2C device (the PCF8574A in this case) needs to be connected via the SDA and SCK pins (with pullup resistors, and obviously connect Gnd and Vcc) to the Arduino Nano. The Serial Monitor on the Arduino IDE is used so output can be directed via USB to a PC Com serial port.
Using a PCF8574A and PCF8574 pins 1 through 3 (ie A0 to A2) tied to ground produces an I2C device address of 0+0111+0+0+0 = 0x38, so the code below should report a single device found with address of 0x38 hexadecimal. Altering which of the PCF8574A pins 1 through 3 are tied to ground or Vcc will change the reported address (the datasheet gives the table showing what the resultant addresses should be).
Code Snippet 1: I2C Device Address Scanner
#include
void setup() {
delay(200);
Serial.begin(115200);
bool PCF_Found = false ;
// SEARCH FOR PCF8574
for(int i = 0;i < 8;i++) {
int address = PCF8574::combinationToAddress(i, false);
if(PCF8574(address).read() != -1) {
Serial.print("Found PCF8574: addr = 0x");
Serial.println(address, HEX);
PCF_Found = true ;
}
}
// SEARCH FOR PCF8574A
for(int i = 0;i < 8;i++) {
int address = PCF8574::combinationToAddress(i, true);
if(PCF8574(address).read() != -1) {
Serial.print("Found PCF8574A: addr = 0x");
Serial.println(address, HEX);
PCF_Found = true ;
}
}
if (!PCF_Found ) {
Serial.println("Search done. No PCF8574 devices found.") };
}
void loop() {}
Checking PCF8574 with LED output
Once it is determined that I2C is working between the Arduino Nano and the PCF8574, the relevant library can be used to read and write to the PCF8574 to either set output pins and or read the state of input pins. The Arduino library for the PCF8574 is on the repository (1) or via the Arduino IDE. This library allows reading/writing to individual PCF8574 port pins and or reading/writing to all the PCF8574 port pins as a single byte. The following code snippet demonstrates setting/resetting PCF8574 pins as output, which control the state of attached LEDs (as per the circuit in the Schematics Section).
The LED's are connected with current limiting resistors to 5V rather than to ground. This "pull-up" arrangement means that when the relevant PCF8574 port is set to 'low' the PCF8574 can then "sink current" and the LED will light brightly (i.e., dependant upon the 5V source and 330 ohm current limiting resistor). The alternative arrangement with the PCF8574 port being set 'high' (and then the corresponding LED would need to connected to ground) means that the PCF8574 port supplies the '5V' but since the output of the PCF8574 ports is only in the mA range, the LED will be very dim.
The Photographs Section shows the circuit on breadboard, whereas, the Videos Section shows the circuit in operation.
Code Snippet 2: PCF8574 as output controlling LED's
#include
PCF8574 ex1(0x38);
byte ledRegister = 0b11111110; //each bit corresponds to a I/O port on the PCF8574
// a '0' means the port is connected to ground
// a '1' means the port is high, i.e., 5V
void setup() {
}
void loop() {
ex1.write(ledRegister);
delay(500);
ledRegister = ledRegister << 1;
ledRegister = ledRegister + 1;
if (ledRegister < 0b11111011) { ledRegister = 0b11111110;};
}
Using 4x4 Matrix keypad with PCF8574
The matrix keypad library by 'joeyoung' on github (2) contains several separate arduino format libraries, each one adding to the library Keypad external expansion port communication via an I2C port on the Arduino Nano. The 'Keypad_I2C' is the particular library for use with the PCF8574 expansion chip.
The library by 'joeyoung' builds upon the 'Keypad library for Arduino' (3) which also needs to be installed with the Arduino IDE.
The benefit of using the PCF8574 with the keypad, rather than just using the normal Arduino method of direct connection to the various ports on the Nano (or other Arduino board), is that only 2 pins on the Nano are required.
The following code snippet demonstrates using the PCF8574 to interface the Arduino Nano with a 4x4 matrix keypad (as per the circuit in the Schematics Section). The schematic shows 10 Kohm pull-up resistors for the columns (which is needed for a 'direct connect' version). However, this is not required for the PCF8574A which has lightly pulled up 'input' state for I/O pins - by default it will read as a high logic level, but connecting the GPIO to ground will cause it to read as a low logic level.
Code Snippet 3: 4x4 Matrix keypad connected to PCF8574
#include
#include
#include
#define I2CADDR 0x38
const byte ROWS = 4; //four rows on keypad
const byte COLS = 4; //four columns on keypad
// define the character represented by each key
char keys[ROWS][COLS] = {
{'1','4','7','0'},
{'2','5','8','F'},
{'3','6','9','E'},
{'A','B','C','D'}
};
byte rowPins[ROWS] = {0, 1, 2, 3}; //PCF8574 pins connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 5, 6, 7}; //PCF8574 pins connect to the column pinouts of the keypad
TwoWire *jwire = &Wire; //test passing pointer to keypad lib
Keypad_I2C kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS, I2CADDR, PCF8574, jwire );
void setup(){
Serial.begin(9600);
while( !Serial ){ /*wait*/ }
jwire->begin();
kpd.begin();
Serial.print( "start with pinState = " );
Serial.println( kpd.pinState_set(), HEX );
}
void loop(){
char key = kpd.getKey();
if (key){
Serial.println(key); //echo key to the serial monitor/connected PC
}
}
Only Logged-In Members can add comments