How to program the PCF8574

This is where you talk about the NXJ hardware related topics such as the brick, sensors, LEGO pieces, etc.

Moderators: 99jonathan, roger, imaqine

How to program the PCF8574

Postby JAVA_kiwi » Mon Jul 28, 2008 7:51 pm

Hi
I am new to using lejos and have version 0.6. I want to be able to control a PCF8574 i2c i/o chip using the read and write commands. Despite reading this post viewtopic.php?t=762&highlight=pcf8574 .I am still don't understand how to use the getData and sendData commands in a practical program. My chip has the hex address 0x40 (that is 64 decimal) and it would be great if someone could give me some help here by showing me an example of a lejos program that will use this info to read the value of the PCF8574's i/o pins and display the value on the NXT's LCD screen or else write a byte to the chip.
Thanks, your help is appreciated
Allan
JAVA_kiwi
New User
 
Posts: 4
Joined: Mon Jul 28, 2008 7:08 am

Postby enzomango » Wed Jul 30, 2008 1:02 am

Hi Allan,

I haven't tested this code with the new release yet, but it worked fine with the previous release. There's two classes and I think I had LED's tied to all the PCF8574 ports.

Here's the test code:
Code: Select all
import lejos.nxt.*;
import javax.microedition.lcdui.*;

public class testPCF8574 {
   public static void main(String[] args) throws Exception {
      PCF8574 s = new PCF8574((I2CPort)SensorPort.S1, (byte)0x20);
      Graphics g = new Graphics();
      
      //test blink LED's
      for (int y=0;y<=20;y++) {
         s.sendData((byte)0xFD);
         g.clear();
         g.drawString("Status:" + Integer.toString(s.getData()), 1, 1);
         g.drawString("Port1:" + Integer.toString(s.getSensorPortStatus(1)), 1, 2);
         g.drawString("Port2:" + Integer.toString(s.getSensorPortStatus(2)), 1, 3);
         g.refresh();
   
         Thread.sleep(1000);
         s.sendData((byte)0xFF);   
         g.clear();
         g.drawString("Status:" + Integer.toString(s.getData()), 1, 1);
         g.drawString("Port1:" + Integer.toString(s.getSensorPortStatus(1)), 1, 2);
         g.drawString("Port2:" + Integer.toString(s.getSensorPortStatus(2)), 1, 3);
         g.refresh();
         Thread.sleep(1000);         
      }
   }
}


and here's the PCF8574 wrapper class:


Code: Select all
import lejos.nxt.*;

/**
 * This class is used to communicate with a PCF8574 two-wire I2C-bus
 * to 8-bit parallel bus I/O expander.
 *
 */
public class PCF8574 extends I2CSensor {
   
   /**
    * Returns the sensor port. 
    */
   private I2CPort I2Cport;
   
   /**
    * Returns the sensor address. 
    * Values range from 0x20 - 0x27 (or 0x38 - 0x3F when using a PCF8574A).
    */
   private byte address;
   
   /**
    * Returns the current data value. 
    */
   private byte[] data = {0x00};
   
   /**
    * Initializes the PCF8574 sensor.
    * @param sensorPort NXT sensor port.
    * @param address sensor address.  Values range from 0x20 - 0x27
    * (or 0x38 - 0x3F when using a PCF8574A).
    */
   public PCF8574(I2CPort sensorPort, byte sensorAddress) {
      super(sensorPort);
      I2Cport = sensorPort;
      address = sensorAddress;
   }

   /**
    * Method for sending data to sensor.
    * @param value Data to send.
    * @return
    */
   public void sendData(byte value) {
      data[0] = value;
      I2Cport.i2cStart(address, 0x00, 0, data, 1, 1);
      while (I2Cport.i2cBusy() != 0) {
         Thread.yield();
      }
   }
   
   /**
    * Method for retrieving the data from the sensor.
    * @return value of 8-bit parallel bus port.
    */
   public int getData() {   
      int ret = I2Cport.i2cStart(address, 0x00, 0, data, 1, 0);
      
      if (ret != 0) return -1;
      
      while (I2Cport.i2cBusy() != 0) {
         Thread.yield();
      }
      return (0xFF & data[0]);
   }
   
   /**
    * Method for retrieving the status of one sensor port.
    * @param port the sensor port. Values range from 1-8.  This is the PCF8574, not the NXT port.
    * @return value of sensor port.  1 means port is high, 0 means port is low (pulled to ground).
    */
   
   public int getSensorPortStatus(int sensorPort) {
      int result = -1;
      int mask = -1;
      int data = getData(); //get status of all ports from sensor
      
      //create a mask to logically AND the data with...
      mask = 1 << (sensorPort - 1);
      
      result = (byte)mask & (byte)data;
      if ( result > 0 ) {
         return 1;
      }else {
         return 0;
      }
   }
}
enzomango
Novice
 
Posts: 30
Joined: Tue Feb 26, 2008 5:20 pm

Postby JAVA_kiwi » Wed Jul 30, 2008 7:34 pm

Thanks, enzomango
the code works perfectly with my chip.
Allan
JAVA_kiwi
New User
 
Posts: 4
Joined: Mon Jul 28, 2008 7:08 am

Postby nick_193 » Tue Jan 05, 2010 1:25 pm

Can u guys maybe send me the electrical circuit that you built? I cant get the code to work on my chip.

It does read the changing of byte from 0xFD to 0xFF but it my LED's do not light up..

I dont understand if there is datatransfer between my brick and the PCF8574P or not and if so why isnt my LED lighting up.

This is what ive built on my breadbord;

Image
nick_193
New User
 
Posts: 6
Joined: Wed Oct 14, 2009 10:31 am

Postby epascual » Sun Jan 17, 2010 10:42 am

Hi Nick,

You schematics looks fine for me and it should work as is, as long as values used for pull-up resistors on the I2C lines have a correct value (something like 4k7 works well in general). But they should be ok, since you have already succeeded in reading the inputs state.

Having personally struggled with the same kind of problems (not only in the NXT world, but in robotics and electronic projects I could work on), I ended up making me a favor by buying this kind of tool. Believe me, it largely deserves the bucks for it and in addition will allow you to explore the arcane of various protocols and buses behaviors. Using it to monitor your I2C lines will easily tell you if the NXT is sending the correct frames to the PCF when you try to change the LEDs status. This tool is not a simple oscilloscope but it will decipher various protocols (serial, I2C, SPI,...) and display in clear the values corresponding to the signals.

I'm in no way affiliated to the company which makes this analyzer, and there are other similar products on the market. I'm just a very satisfied user, since it has saved me hours of debugging, and also allowed me to understand better details of how things work, even in my professional activities.

Best regards and hope you'll find the solution of your problem quickly.
epascual
Active User
 
Posts: 100
Joined: Sun Jan 17, 2010 12:15 am
Location: Sophia-Antipolis (France)

Postby s.frings » Thu Jan 20, 2011 9:19 am

The Hardware Developer Kit manual says that the Pull-Up resitors should have 82k Ohm.

Im sure that 4,7k Ohm Pull-Up will not work, because of the R60, R61, R75 and R76 inside the NXT.
s.frings
Active User
 
Posts: 131
Joined: Tue Jul 20, 2010 2:01 pm


Return to NXJ Hardware

Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests

more stuff