Before connecting the Digispark to the USB port, check for any shorts (direct positive voltage to ground connection) as this could damage both the Digispark board and the USB/PC.
Initial testing of a I2C interfaced device (and if the I2C interface library is working on the ATtiny85/Digispark) is to use the I2C scanner sketch (Code Snippet 1 below).
Once it is determined that I2C communication is working with the ATtiny85 and the PCF8574, 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.
I2C Device Address Scanner
The I2C device (the PCF8574 in this case) needs to be connected via the SDA and SCK pins (with pullup resistors, and obviously connect Gnd and Vcc) to the ATtiny85/Digispark. The SoftSerial library is used so output can be directed via USB-TTL converter 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 PCF8574 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
#include
#define TX_RX_PIN 3
SoftSerial mySerial(TX_RX_PIN, TX_RX_PIN);
int runOnce=1;
void setup() {
mySerial.begin(115200);
delay(3000); //give a delay so can connect the port in the receiving software
mySerial.txMode(); //before sending a message, switch to txMode
mySerial.println("I2C Address Scanner. Scanning ...");
TinyWireM.begin(); // initialize I2C lib
}
void loop() {
while (runOnce) {
runOnce=0;
scanI2Cdevices();
}
}
void scanI2Cdevices(){
byte count = 0;
for (byte i = 8; i < 120; i++){
TinyWireM.beginTransmission (i);
if (TinyWireM.endTransmission () == 0){
mySerial.print ("Found i2c Device Address: ");
mySerial.print (i, DEC);
mySerial.print (" (0x");
mySerial.print (i, HEX);
mySerial.println (")");
count++;
delay (10);
}
}
mySerial.println ("Finished.");
mySerial.print ("Found ");
mySerial.print (count, DEC);
mySerial.println (" device(s).");
}
"Bare Bones" PCF8574 Library
Once it is determined that I2C is working between the ATtiny85 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 simplest library is by 'debsahu' on github (1). 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 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
#define PCF8574_ADDRESS (0x38) // SDA - P0 CLK - P2
A85_PCF8574 myPCF8574;
void setup(){
myPCF8574.begin(PCF8574_ADDRESS);
}
void loop()
{
/*
myPCF8574.setBit(0,1);
delay(500);
myPCF8574.setBit(1,1);
delay(500);
myPCF8574.setBit(2,1);
delay(500);
myPCF8574.setBit(3,1);
delay(500);
PCD8574A_resetAll();
delay(500);
*/
myPCF8574.setByte(B00000001);
delay(500);
myPCF8574.setByte(B00000011);
delay(500);
myPCF8574.setByte(B00000111);
delay(500);
myPCF8574.setByte(B00001111);
delay(500);
PCD8574A_resetAll();
delay(500);
}
void PCD8574A_resetAll(){
myPCF8574.setByte(B00000000);
}
"Bells and Whistle's" PCF8574 Library
The PCF8574 library by 'RobTillaart' on github (2) provides the same basic functionality as that used in code snippet 1 above, however, provides a more 'arduino' style 'syntax'. Also, this library provides a few other wrappers and routines that potentially make utilisation of the PCF8574 for controlling buttons easier (and in particular, for rotating through the PCF8574 pins, e.g. for LED displays etc).
One thing to remember if utilising this library is that it targetting Arduino boards and hence uses the Wire.h library. This needs to be changed in the library files to TinyWireM.h so that the ATtiny85 will work. 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).
Code Snippet 3: Flashing LED's connect to PCF8574
#include "PCF8574.h"
PCF8574 PCF_01(0x38); // SDA - P0 CLK - P2
void setup()
{
PCF_01.begin();
}
void loop() {
PCF_01.write(0, LOW);
delay(500);
PCF_01.write(1, LOW);
delay(500);
PCF_01.write(2, LOW);
delay(500);
PCF_01.write(3, LOW);
delay(500);
PCF_01.write(3, HIGH);
delay(500);
PCF_01.write(2, HIGH);
delay(500);
PCF_01.write(1, HIGH);
delay(500);
PCF_01.write(0, HIGH);
delay(500);
}
Only Logged-In Members can add comments