wanting information about a simple I2c sketch

I have a thread open on the programming questions section about using shift registers to increase the number of i/o's on an Uno. I have heard of, but know very little about I2c. Would someone know of a small sketch somewhere that utilises the PCF 8574 to send info to light leds and receive info from switches that I could learn from, get running and alter for my purpose? I have spent most of this evening trawling through the internet without much success and I have just sent for a PCF 8574 from the internet. I run the electronics for a garden railway built by a Society of Mechanical engineers and we are getting overwhelmed by wiring. If I could put slaves in each of the signals also wired to each of the track sensors I could do the job with very few wires. I would then be able to connect them to an arduino in the signal box and control everything with just 2 wires (plus power). I know they can only run 8 slaves, or 16 in the case of the 8574a but that would be a good start. The best thing I can find on this site is in the playground http://playground.arduino.cc/Code/I2CPortExpander8574. but I suspect that has a lot of information not relevant to the PCF 8574. If I can't find anything better I could load that into my Uno, keep removing anything I thought was not relevant and try to work out what the relevant lines do as a way forward but I am sure there must be a sketch somewhere that is more relevant to just using a PCF 8574, or similar, for lighting LED's and monitoring switches. Each signal has a maximum of 4 LED's so a larger slave would be unnecessary

I have a post about I2C and a different port expander here:

http://www.gammon.com.au/i2c

The concepts would be similar. One problem though is that you need fairly short wiring runs for I2C.

For a garden railway I would be looking at async serial with RS485 protocol (this is a balanced electrical protocol, fairly immune to noise).

http://www.gammon.com.au/forum/?id=11428

You could just run two wires (plus 2 more for power, if required) and have a small slave (eg. an ATtiny85) at each signal. They could each have a different address (you could put that into EEPROM), and have them all listen. Then you just send a message down the wires saying (in effect) "signal 3, go to green".

If you have a lot of signals near each other, then you could indeed use I2C (at the slave end) and use a port-expander. However a 74HC595 shift register could do the same thing and be cheaper.

http://www.gammon.com.au/forum/?id=11518

I know so little about this and I have spent the last fairly unfruitful few days trying to get my head around shift registers, for instance the example I used from the arduino learning site in my thread in programming doesn’t use SPI, I am wondering if the writer failed to understand the SPI library as well.
The info on it here in library/ SPI goes on a lot about SPI but not about the instructions I would have to use to get the SPI library to talk to a shift register. For instance it doesn’t even mention SPI transfer. Nick, I notice your site just links to the arduino site mentioned above or the wiki site that just mentions SPI. How do you find out what instructions you put in your programs to use any library?
I have spent quite a while on your web site over the last few days and find the information on there most informative for which I thank you. I have tried to convert your 74HC165 input page to run the CD 4021 that I have but some of the pins are different

// 
Demo sketch to read from a 74HC165 input shift register
// Author: Nick Gammon
// Date:   23 March 2013

// Pin connections for Uno and similar:

// Chip pin 1 (/PL)  goes to LATCH (D9)
// Chip pin 2 (CP)   goes to SCK   (D13)
// Chip pin 9 (Q7)   goes to MISO  (D12)


#include <SPI.h>

const byte LATCH = 9;

void setup ()
{
  SPI.begin ();
  Serial.begin (9600);
  Serial.println ("Begin switch test.");
  pinMode (LATCH, OUTPUT);
  digitalWrite (LATCH, HIGH);
}  // end of setup

byte optionSwitch;
byte oldOptionSwitch; // previous state

void loop ()
{
  digitalWrite (LATCH, LOW);    // pulse the parallel load latch
  digitalWrite (LATCH, HIGH);
  optionSwitch = SPI.transfer (0);
  
  byte mask = 1;
  for (int i = 1; i <= 8; i++)
    {
    if ((optionSwitch & mask) != (oldOptionSwitch & mask))
      {
      Serial.print ("Switch ");
      Serial.print (i);
      Serial.print (" now ");
      Serial.println ((optionSwitch & mask) ? "closed" : "open");
      }  // end of bit has changed
    mask <<= 1;  
    }  // end of for each bit
  
  oldOptionSwitch = optionSwitch;
  delay (10);   // debounce
}  // end of loop

I didn’t manage to get the chip to work.
All I could get was the switches were closed all the time. So I was getting something as I just get ‘begin switch test’ if nothing is connected.I assume the 4021 is configured differently.

I assume the line Serial.println ((optionSwitch & mask) ? “closed” : “open”); is using the syntax ‘if the variable is a 0 do the first option or if a 1 do the second’ though there is no mention of this in the reference for Serial.println.
I think I will stick to trying to get my head around shift registers and have ordered a 595 but I would like to be able to get the 4021 to work just for the shear hell of it and get it to write into an array that I can access.
I have just noticed your website sketch for the 165 is not using the clock pin? I am connecting the 4021 to
D12 to q7 (the data output)
D13 to clock
D12 to pl (which I assume is the switch for read parallel/write serial. I assume this is correct?
I can see this is rather long and I am asking a lot but I am trying to get my head around it and not just asking you to do it for me.

matelot: Nick, I notice your site just links to the arduino site mentioned above or the wiki site that just mentions SPI. How do you find out what instructions you put in your programs to use any library?

What do you mean it "just links to the Arduino site"?

My page has about 6500 words on it, and in one line only I give a reference to the Arduino site.

The SPI library (which is very simple to use, basically you do SPI.transfer (x) ) can interface with any chip that supports SPI. I can hardly give details for all the thousands of possible chips that it might interface with.

The info on it here in library/ SPI goes on a lot about SPI but not about the instructions I would have to use to get the SPI library to talk to a shift register.

Can you give links to pages please? Mentioning the "library here" is not really helping. If there is a library you are interested a link to the exact one will help a lot.

I have just noticed your website sketch for the 165 is not using the clock pin?

Yes it is, right here:

SCK is "Serial CLock".

It would be helpful if you clarified your requirements. For a while there I thought you were wanting to operate some signals (a lot of them) but re-reading your first post it isn't really clear what you want (quantity-wise):

to send info to light leds and receive info from switches

How many lights? How many switches? What info?

Firtly and most importantly I would like to apologize to Nick Gammon for my comment

Nick, I notice your site just links to the arduino site mentioned above or the wiki site that just mentions SPI. How do you find out what instructions you put in your programs to use any library?

The post took me about 2 hours to write, swapping back and forth between sites for information. I had your SPI site open at the top of the thread on 1 explorer tab and just read the first part

More information about SPI at: http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus More information about the Arduino SPI interface at: http://arduino.cc/en/Reference/SPI

it then lists

OTHER PROTOCOLS

I failed to scroll the page for which I am very sorry. There is a large amount of information about SPI's below that.

I can hardly give details for all the thousands of possible chips that it might interface with.

I wasn't asking you to explain them all. I just wanted to know if you knew anywhere that I could go to that would give me a list of the commands relevant to the libraries that the arduino uses. The link you asked for http://arduino.cc/en/Reference/SPI mentions SPI.setDataMode() function. and SPI.setClockDivider() function. but doesn't mention SPI.transfer (x) . I am wanting to find out how to use the SPI library but don't know where to go to get help with what the commands are and how they work. I will possibly move on to learning about other aspects and want to learn how to use other library functions, that is why I said " in any library".

I have just noticed your website sketch for the 165 is not using the clock pin?

from http://www.gammon.com.au/forum/?id=11979

Chip enable I have connected the clock enable (/CE) pin to ground as the clock may as well always be enabled.

What I was getting at was that I want to write the 8 switches on the shift register into an array, I understand to do this I have to clock the shift register on each time I read a bit of information so this would not work for me. Or at least that is what I understand to be happening.

My ultimate goal is to control the signals for a garden railway. http://www.sheffieldsmee.co.uk/ I was there this afternoon and looking at the control board there are, at present, 44 lights including 4 aspect (four lights in 1 signal), three, and two aspect. At present, due to the fact the system has altered over the years, the signals are mostly controlled from the signal box but it is due a clean up. I am interested in bringing the system together and eventually being able to control all the present signals and add new ones without being buried in cables. I could put a shift register in one signal head and run wires to another signal head from it, this would mean the shift register would need 7 outputs at the most (or I could put a shift register in all the heads, the cost would be within our budget). I also need to get info from all the track sensors, there is one near every signal. A train passes a proximity sensor in the track pulling the sensor wire to '0' potential. That is why I was looking at both input and output shift registers. This is all purely voluntary work for the fun of it. On my bread board in my study I would start small, one shift register , and play with it till I understood it then add bits to it. The PCF 8574 that I started this thread with would allow me to do both tx and rx with I chip but I agree that I2C is not the right direction to go, the whole track is about a 1/2 of a mile ling in an inverted figure 8 format. I have ordered a 595 and will investigate that when it turns up, do you suggest I go for 156 and drop the cd 4021? (remember I may end up with a dozen or more chips ultimately).

matelot: I wasn't asking you to explain them all. I just wanted to know if you knew anywhere that I could go to that would give me a list of the commands relevant to the libraries that the arduino uses. The link you asked for http://arduino.cc/en/Reference/SPI mentions SPI.setDataMode() function. and SPI.setClockDivider() function. but doesn't mention SPI.transfer (x) .

I don't want to nit-pick but it does:

I have just noticed your website sketch for the 165 is not using the clock pin?

from http://www.gammon.com.au/forum/?id=11979

Chip enable I have connected the clock enable (/CE) pin to ground as the clock may as well always be enabled.

That was /CE (chip enable) which is different from clock. The clock pin is used for clocking bits in/out. If you want the chip always enabled, you ground /CE.

(Looks like a mis-typing where I wrote "clock enable" but meant "chip enable". I'll fix that.


I am interested in bringing the system together and eventually being able to control all the present signals and add new ones without being buried in cables. I could put a shift register in one signal head and run wires to another signal head from it, this would mean the shift register would need 7 outputs at the most (or I could put a shift register in all the heads, the cost would be within our budget). I also need to get info from all the track sensors, there is one near every signal. A train passes a proximity sensor in the track pulling the sensor wire to '0' potential. That is why I was looking at both input and output shift registers. This is all purely voluntary work for the fun of it.

It sounds an interesting project. There are all sorts of things you could do, from putting a chip at every signal/input point, to have less chips but a bit more wiring.

Also you could conceivably have "smart chips". A whole Atmega328P processor only costs around $5, and on that you have 20 input/output pins. You could dedicate 10 to outputs, 5 to inputs, and keep 5 for talking to the "master controller", eg. by serial or SPI. For longer wire runs, where there is probably noise from the trains, I think I would use serial via RS485.

The SPI interface is even more poorly suited to your needs than the I2C. You can not use long runs with this. What you want is the DMX interface http://playground.arduino.cc/Learning/DMX

I run the electronics for a garden railway built by a Society of Mechanical engineers and we are getting overwhelmed by wiring. If I could put slaves in each of the signals also wired to each of the track sensors I could do the job with very few wires. I would then be able to connect them to an arduino in the signal box and control everything with just 2 wires (plus power).

Surely you have considered using DCC (Digital Command Control) which has been used by model railroaders for years to power and control everything with just two wires (the tracks). What are your objections to DCC?

Don

I think a garden railway is diffrent from a model railway. With the garden type you have engins that can pull several people. That is not the case with a model as far as I understand it. Correct me if I am wrong.