PCF8574 and some LEDs - Project Showcase - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

PCF8574 and some LEDs


  • Please log in to reply
12 replies to this topic

#1 Trey Aughenbaugh

Trey Aughenbaugh

    Advanced Member

  • Members
  • PipPipPip
  • 36 posts

Posted 20 March 2011 - 04:53 AM

Hello,
Here is a simple LED test I created to learn I2C and the PCF8574 Port Expander.
At first I just sent some simple commands to turn the LEDS on and off.

Then I ran into Hinnie's Knightrider Project and added some of his code to mine.
I'm only using 1 Port expander and 6 LEDS. It was just a test and 6 LEDS is all that was plugged into my breadboard I was using.

The code supplied will do a 6 LED version of Knightrider and holding the onboard push button will do a different pattern test I was playing with.

One thing to note, my PCF8574 had a different ID than Hinnie's. If you are problems, that could something to look at.
Also, make sure you follow this little note I found:

that chip can drive LED's directly, but you have to connect them this way:
+5V------+LED-------330Rresistor------P8574pin
(edit: make sure the resistor is at least 330R)
This is called 'sinking' current, rather than 'sourcing' it.
According to the specifications on the datasheet, the 8574 can source ( i.e. give out during high pin state) only 100uA or .1ma, but it can sink (i.e. accept during low pin state) 20 milliamps.


using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoKN
{
    public class Program
    {
        public static void Main()
        {
            new Thread(() => flashOnboardLed(3000)).Start();

            I2CDevice MyI2CBus = new I2CDevice(null);
            I2CDevice.Configuration pcf8574_0 = new I2CDevice.Configuration(0x38, 400);
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1];

            InputPort button = new InputPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled);
            bool buttonState = false;

            int val = 0x0001;  //Number of bits to have always on.
            bool dir = false;
            byte[] cmd = new byte[1];
            int Max = 0x0020; //6 LEDS =32 Dec or 20 hex
            while (true)
            {
                buttonState = button.Read();
                if (!buttonState)
                {
                    Pattern(MyI2CBus, pcf8574_0);
                    Thread.Sleep(500);
                }

                MyI2CBus.Config = pcf8574_0;
                cmd[0] = (byte)(val ^ 0xFF);
                xActions[0] = I2CDevice.CreateWriteTransaction(cmd);
                MyI2CBus.Execute(xActions, 1000);

                if ((val & Max) > 0)
                    dir = true;
                if ((val & 0x0001) > 0)
                    dir = false;
                if (!dir)
                    val = val << 1;
                else
                    val = val >> 1;
                Thread.Sleep(50);
            }
        }

        public static void Pattern(I2CDevice MyI2CBus, I2CDevice.Configuration pcf8574_0) 
        {
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1];
            byte[] cmd = new byte[1];
            int[] vals = {0xC,0x12,0x21,0x33,0x3F};

            for (int i = 0; i < vals.Length; i++)
            {
                MyI2CBus.Config = pcf8574_0;
                cmd[0] = (byte)(vals[i] ^ 0xFF);
                xActions[0] = I2CDevice.CreateWriteTransaction(cmd);
                MyI2CBus.Execute(xActions, 1000);
                Thread.Sleep(100);
            }
            MyI2CBus.Config = pcf8574_0;
            cmd[0] = (byte)(0 ^ 0xFF);
            xActions[0] = I2CDevice.CreateWriteTransaction(cmd);
            MyI2CBus.Execute(xActions, 1000);
        }

        public static void flashOnboardLed(object flashTime)
        {
            OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
            while (true)
            {
                led.Write(!led.Read());
                Thread.Sleep((int)flashTime);
            }
        }  

    }
}

Attached Files



#2 65tux

65tux

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts

Posted 22 June 2012 - 05:33 PM

One of these days I really need to try to understand I2C addressing - the chip you reference has a "prefix" of 0111 and your 3 address bits are all 0, so, 0111000. How the heck is that address 38?

#3 nakchak

nakchak

    Advanced Member

  • Members
  • PipPipPip
  • 404 posts
  • LocationBristol, UK

Posted 22 June 2012 - 06:22 PM

Hi 65tux The 0x38 is hexadecimal in decimal its 56 and 56 in binary is 111000 Hope that helps your understanding Nak.

#4 65tux

65tux

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts

Posted 22 June 2012 - 07:41 PM

I get it - once you realize it's right to left, not left to right it makes sense. Now it does at least! I'm slow, but I'm learning! Forum has been a huge help.

#5 nakchak

nakchak

    Advanced Member

  • Members
  • PipPipPip
  • 404 posts
  • LocationBristol, UK

Posted 22 June 2012 - 10:33 PM

Apologies to the OP I don't mean to hijack your thread.

You might want to look into binary and hexadecimal maths, both are pretty easy, just alternative ways of representing integers. Here is a quick overview (and i purposely don't muddy the waters with negative numbers, i am purely talking about unsigned integers here)

Binary
Starting with the basics, binary is a positional numbering system, and simply says that 1 means add the value of the position and 0 means dont add the value of the position. Binary is also known as base 2, what this means is that each position is equal to 2n where n is the number of places from the right most digit. i.e. the right most digit's value is equal to 20 = 1, the first digit from the right is equal to 21 = 2 etc.

128 64 32 16 8 4 2 1
--------------------
 0  0  0  0  0 0 0 0 = 0 in Decimal
 0  0  0  0  0 0 0 1 = 1 in Decimal
 0  0  0  0  0 0 0 0 = 2 in Decimal
 0  0  0  0  0 0 1 1 = 3 in Decimal (1 + 2)
 0  0  1  1  1 0 0 0 = 56 in Decimal (32 + 16 + 8)

Hexadecimal
Hex is a notation which is more compact than decimal and also lends it self to a shorthand of binary representations of numbers. Unlike decimal where you have the numerals 0-9 in hex you have 0-F. So unlike in decimal where ten is represented by two numerals (1 and 0) in hex it has a single numeral A to represent it. once you have counted up to F you "roll over" to the next column just like in decimal, so 0x10 (10 hex) is 16 in decimal.

How does this help?
Well the largest number you can represent with a single byte is 255 or 11111111 in binary, but in hex its just FF which is much easier to write/type than 11111111 and uses less characters (so less memory) than 255 in decimal does, when you are dealing with 8 bits the compactness isnt of much use, but consider 32 bit numbers where the largest number is
4294967295 in decimal, 11111111111111111111111111111111 in binary and FFFFFFFF in hex.

In .net the 0x prefix you see infront of a number means that its hex.

Nak.

#6 supra

supra

    Advanced Member

  • Members
  • PipPipPip
  • 210 posts
  • LocationOntario, Canada

Posted 22 September 2012 - 02:54 AM

@nakchak


quote name='nakchak' timestamp='1340404410' post='31116']
128 64 32 16 8 4 2 1
--------------------
    0  0   0  0  0 0 0 0 = 2 in Decimal


[/quote]

Where is binary for decimal 2?Posted ImagePosted ImagePosted ImagePosted Image

Should be:
0 0 0 0 0 0 1 0 = 2 in Decimal

#7 gfcwfzkm

gfcwfzkm

    Advanced Member

  • Members
  • PipPipPip
  • 52 posts
  • LocationBrig-Glis, Switzerland

Posted 01 October 2012 - 08:57 AM

It dont work on my netduino. :( I translated the code to VB and changed the IC-Address to &H70 Dim pcf8574_0 As New I2CDevice.Configuration(&H70, 400) i use a PCF8574AP VB dont show any errors :S mfg gfc

#8 neslekkim

neslekkim

    Advanced Member

  • Members
  • PipPipPip
  • 350 posts
  • LocationOslo, Norway

Posted 01 October 2012 - 10:15 AM

How are you people choosing addresses for this device?, one place it seems that you solder the adresspins to high/low, but still all of you are using quite different addresses, so how do you know if you are using the correct one? (I'm really noob at this i2c stuff, that's why I'm asking)

--
Asbjørn


#9 gfcwfzkm

gfcwfzkm

    Advanced Member

  • Members
  • PipPipPip
  • 52 posts
  • LocationBrig-Glis, Switzerland

Posted 01 October 2012 - 11:51 AM

I checked my Address in the Datasheets. With A0, A1 and A2 can you change the address mfg gfc

#10 neslekkim

neslekkim

    Advanced Member

  • Members
  • PipPipPip
  • 350 posts
  • LocationOslo, Norway

Posted 01 October 2012 - 12:06 PM

ah, 7.1 in the datasheet, so if a0-a2 is low, your adress is 70hex, IF you have the pcf8574A, but if you have the pcf8574, then it would be 40hex in the same condition. So, how do one come up with 38hex, and 20-21hex as above, and the referenced article?, when 70hex and 40hex is the absolute lowest adress you can have on those two devices? If, I understood this correctly that is... Or, on the 8574, is the adressing only 7 bits? From figure 10 here http://www.nxp.com/d...eet/PCF8574.pdf it looks like its only 7 bit for 8574, and 8 bits on 8574A, but figure 11&12, it seems like the 8574 do have 8bit adress, so 40hex is for write, and 41hex is for read.

--
Asbjørn


#11 gfcwfzkm

gfcwfzkm

    Advanced Member

  • Members
  • PipPipPip
  • 52 posts
  • LocationBrig-Glis, Switzerland

Posted 01 October 2012 - 12:28 PM

uff, idk. im a noob in i2c too. I tried the code and wired all like in the sample, but it dont work :(

#12 neslekkim

neslekkim

    Advanced Member

  • Members
  • PipPipPip
  • 350 posts
  • LocationOslo, Norway

Posted 01 October 2012 - 12:47 PM

Ok, after reading about the i2cdevice, it seems like it takes 7bit adresses, it's masking away the r/w bit, so I guess it's shifted down one bit. That means you should try 38hex instead if you put a0-a2 low and you have the A chip. If you have the non-A chip,it would mean 20hex as adress, and then I understand the above example, and the linked example..

--
Asbjørn


#13 SteveS

SteveS

    Member

  • Members
  • PipPip
  • 21 posts

Posted 08 October 2012 - 02:14 PM

Ok, after reading about the i2cdevice, it seems like it takes 7bit adresses, it's masking away the r/w bit, so I guess it's shifted down one bit. That means you should try 38hex instead if you put a0-a2 low and you have the A chip.
If you have the non-A chip,it would mean 20hex as adress, and then I understand the above example, and the linked example..


That's right. The Wire library used in Arduino does exactly that too. On a couple of boards I built where I had I2C slaves that supported A0..An pins, I put either jumpers or a DIL switch to allow me to set the address, but where you will only have a single device, hardwiring is usually easier. Some devices, like the RTC (DS1307?) don't support it anyway, although I'm not sure why you'd want more than RTC

SteveS




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.