Multiplex IR LED's?

I also forgot to ask, how would I generate a 38khz wave for the IR Emitters so the detectors can sense the IR signals?

You love springing surprises don't you. You said at the start that the IR carried no data, now you are saying they are modulated!!!
Well modulation is data, what sort of sensor do you have, part number? This changes again how you should do things.

Grumpy_Mike:
The code is nearly right but you only do one column per refresh not all of them.
You are only sourcing one LED's current per shift register pin so that is fine but check on the data sheet that the total package current is OK, it depends on what type of shift register you get, that is given by the letters before the 595 bit, you might have to use LS or HS type. The darlingtons are good for 500mA per pin.

OOOOOOOohhhh omg I understand now :smiley:

Firstly, the datasheet for the 595s Im getting say the max continuous output current is 35mA I think, http://www.jaycar.com.au/products_uploaded/ZC4895.pdf But I dont know if thats per pin or not?

Ok now to the good part :P, I think I have got it, and I wrote up the code, not psuedocode:
This works if the ULN2803 inverts I have read that it does but im still not sure, on your site It says they do or is that for the FET's?

const int latchPin = 4;
const int clockPin = 3;
const int dataPin = 2;

byte displayData [ ] = {
B11111111,
B10000001,
B10111101,
B10100101,
B10100101,
B10111101,
B10000001,
B11111111,
B11011011,
B11111111,
B11111111,
B11111111};
int rowCount = 0;

long int refreshDue;
long int refreshTime = 10; 

void setup() {
  pinMode(dataPin, OUTPUT); //Data
  pinMode(clockPin, OUTPUT); //Clock
  pinMode(latchPin, OUTPUT); //Latch
}
void loop() {
  if(millis() >= refreshDue){
    refreshDue = millis() + refreshTime;
    refreshDisplay();
  }
}

void refreshDisplay(){

  if (rowCount>=12)rowCount=0;
  
  byte rowData;
  byte col1Data;
  byte col2Data;
  
  rowData = displayData[rowCount];
  
  if (rowCount<=7){
    col2Data=B00000000;
    col1Data=byte(rowCount+1);
  }else if (rowCount>=8{
    col2Data=byte((rowCount-8)+1);
    col1Data=B00000000;
  }
  
  digitalWrite(latchPin, LOW);
  shiftout(dataPin, clockPin, MSBFIRST, col2Data);
  shiftout(dataPin, clockPin, MSBFIRST, col1Data);
  shiftout(dataPin, clockPin, MSBFIRST, rowData);
  digitalWrite(latchPin, HIGH);

  rowCount ++;
  
}

(I also used alot of your code, thanks bro :P)

There is one minor flaw in this code...
instead of refreshing left to right, or right to left (which is what I wanted)
it refreshes or the bit walks like this (_ means that its not used shift register pin)
00000001 0000 _ _ _ _
00000010 0000 _ _ _ _
00000100 0000 _ _ _ _
00001000 0000 _ _ _ _
00010000 0000 _ _ _ _
00100000 0000 _ _ _ _
01000000 0000 _ _ _ _
10000000 0000 _ _ _ _
00000000 0001 _ _ _ _
00000000 0010 _ _ _ _
00000000 0100 _ _ _ _
00000000 1000 _ _ _ _

Also I believe you mean HC, I cant find any HS595's anywere :stuck_out_tongue:

P.S: I saw your post whilst I was posting a reply to the other one :P, I dont mean to spring the surprise, I was using just a photodiode and hoping it would work, when I realised the part that I ordered from sparkfun wasnt a photodiode but rather a reciever Lol, fail, so then I just thought since the instructable I was following before was a load of crap and I might as well actually use the reciever it could give me a better result :slight_smile:
This is the part: TSOP38, can be found here: IR Receiver Diode - TSOP38238 - SEN-10266 - SparkFun Electronics
But I might have to order from somewhere else as they only take credit card and use something like this: http://www.jaycar.com.au/productView.asp?ID=ZD1952&form=CAT2&SUBCATID=976#1
which is way too overpriced for me :frowning:
I would prefer to use this: http://www.electus.co.nz/productView.asp?ID=6149&CATID=33&keywords=&SPECIAL=&form=CAT&SUBCATID=140 but I dont know how to use it with the emitter, all examples use reciever breakouts and stuff :frowning:

Thanks Mike :smiley:

With your code, have the walking 1 variable as a global like the rowCount. Change it each time by a:-

walk1 = walk1 << 1;

Reset it to 1 when you reset the rowCount. Then there is no need to calculate the col2Data or col1Data simply output the walk1 value:-

  shiftout(dataPin, clockPin, MSBFIRST, walk1 >> 8);
  shiftout(dataPin, clockPin, MSBFIRST, walk1);
  shiftout(dataPin, clockPin, MSBFIRST, rowData);

You better say what your application is because I suspect that the sensor you have is not suitable. Look at the data sheet and you will see that you can't carry on giving it pulses and expect the output to say at one level. If you want to just detect when a beam is broken you need the TSOP4038 sensor.

Grumpy_Mike:
With your code, have the walking 1 variable as a global like the rowCount. Change it each time by a:-

walk1 = walk1 << 1;

Reset it to 1 when you reset the rowCount. Then there is no need to calculate the col2Data or col1Data simply output the walk1 value:-

  shiftout(dataPin, clockPin, MSBFIRST, walk1 >> 8);

shiftout(dataPin, clockPin, MSBFIRST, walk1);
  shiftout(dataPin, clockPin, MSBFIRST, rowData);

Ahh thats what the >> and << operators do, I see, yes that narrows down the code alot, thanks :slight_smile:

Grumpy_Mike:
You better say what your application is because I suspect that the sensor you have is not suitable. Look at the data sheet and you will see that you can't carry on giving it pulses and expect the output to say at one level. If you want to just detect when a beam is broken you need the TSOP4038 sensor.

I just want to detect a broken beam yea :slight_smile:

Ok so you need to change your sensor.

Grumpy_Mike:
Ok so you need to change your sensor.

Damn, so I get a TSOP4038, I found this one on an Australian site which I might be able to buy it off: http://www.x-on.com.au/details-new.asp?i=549879&t=7&p=

My only problem is, everywhere people mention that the IR Emitters need to be pulsing at 38khz for the IR Detectors to pick it up... So how do I do that?

You setup one of the timers to change the PWM frequency to 38KHz and drive the LEDs from that pin.

Grumpy_Mike:
You setup one of the timers to change the PWM frequency to 38KHz and drive the LEDs from that pin.

But how can one output drive 6 or more Ir emitters? With a transitor or something?

Yes one output through a resistor into the base of a transistor. Emitter to ground, then collector to a resistor, other end to an LED and then on to the +ve supply. You can parallel up the resistor / LED series circuit many times, providing the transistor can take the collector emitter current.

Grumpy_Mike:
Yes one output through a resistor into the base of a transistor. Emitter to ground, then collector to a resistor, other end to an LED and then on to the +ve supply. You can parallel up the resistor / LED series circuit many times, providing the transistor can take the collector emitter current.

Sorry I have not replied for days, I have been preoccupied with schoolwork, mainly tests and stuff, I will reply again soon but right now Im just posting this not to be rude :slight_smile:

Thankyou Mike :slight_smile:

Phew... Its been along time Mikey ;P, sorry I haven't replied.

I managed to get some of it working and others not so much... all my parts have come and I finally have started putting it together. The IR Recievers work well :), I found some neat code for them, the only problem I have is the Multiplexed LED's, I made a few modifications to the code:

(Not including IR parts)

const int latchPin = 4;
const int clockPin = 3;
const int dataPin = 2;

byte displayData [ ] = {
B10101101,
B10000001,
B10101001,
B10100101,
B10100101,
B10010101,
B10000001,
B10010101,
B10010011,
B10101010,
B10100101,
B11111111};
int rowCount = 0;
unsigned int walk1 = 1;

long int refreshDue;
long int refreshTime = 5000; 

void setup() {
  pinMode(dataPin, OUTPUT); //Data
  pinMode(clockPin, OUTPUT); //Clock
  pinMode(latchPin, OUTPUT); //Latch
  Serial.begin(9600);
  
  //Clear Registers
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
  digitalWrite(latchPin, HIGH);
}
void loop() {
  if(millis() >= refreshDue){
    refreshDue = millis() + refreshTime;
    refreshDisplay();
  }
}

void refreshDisplay(){

  if (rowCount>=12){
    rowCount=0;
    walk1 = 1;
  }
  
  byte rowData=0;

  rowData = displayData[rowCount];
  byte walk2=highByte(walk1);
  
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, walk2);
  Serial.println("C2: ");
  Serial.println(walk2,BIN);
  shiftOut(dataPin, clockPin, MSBFIRST, lowByte(walk1));
  Serial.println("C1: ");
  Serial.println(lowByte(walk1),BIN);
  shiftOut(dataPin, clockPin, MSBFIRST, rowData);
  Serial.println("Row: ");
  Serial.println(rowData,BIN);
  digitalWrite(latchPin, HIGH);

  walk1 = walk1 << 1;
  rowCount ++;
  
}

Now what happens is peculiar,using this layout:

The LED's light up in random? I have tried changing the row data array to make them all light up, none light up and only 1 light up etc... whenever at least one 1 bit is in the rowdata, the led's light up randomly. I have not connected all the columns/rows to the Darlington and shift registers yet, but I dont see if this should make much of a difference yet I guess im wrong. only row 1 & 2 are connected and column 1 & 2, yet I cant get the LED's to light up how I define them in the rowdata matrix. I hope you understand what im saying if not tell me I shall clarify.

Im not sure but could it be the shift registers are not cleared properley? if so, how can I do that, I tried in the setup function yet it doesnt look like it did anything

Thanks for your help again in advance, Ill take pics of the project soon :slight_smile:

Two points:-

  1. do not use pins 0 & 1 as these are used for serial operations and will interfere with uploading code.
  2. Add some decoupling capacitors on each chip. De-coupling

Right sorry I forgot to change the pin order, ye its not on 0,1,2 its on 2,3,4

I am going to decouple it ASAP, ill post back when I do :slight_smile: Thanks Mike

Ok So I got hold of a 0.1uf capacitor, and wired it to the ground and 5v pin on the shift registers. Nothing worked still..., I decided to test different parts of the cuircut and i found a few intereresting things:

  1. 2 Shift register pins on the row shift register, when connected light the LED
  2. When row 1 & 2 are plugged in with/without ground, the LED's in wierd places light up
  3. When i change the output of the walk to say of B00000001, for column 1 and B00000000 for col 2, i touch the shift register pins to ground with an led and it lights up on all of them?
  4. The first row data seemed to be working for a bit, now it seems lost when I changed the columns to a non walking value the pins in the row always output 1??? im soo confused Lol

The shift register pattern must be data followed by the walking one. Remember that the first two shift outs define the walking 1 pattern and the last out is the data.
So output 0x0, 0x8, 0xff in that order.
That should light up one complete column the left hand one. If it does not then look at the signal on the pins of the shift register outputs and see that the first one has its outputs all set at one, and the other two have the outputs all at zero except for pin 7 on the middle shift register.
If you don't see this then you have a miss match between your software and your hardware. So either change the software or change the wiring so they match.
There is no need to put 5V on the pin 10 of the darlingtons. You have not got pin 13 connected to ground on the last shift register.

Should I disconnect pin 13 from the ground and the 5v from the darlingtons because that is what I have? And Ill try the pattern after school :slight_smile: I needa go :stuck_out_tongue:

Should I disconnect pin 13 from the ground

No the schematic shows it NOT connected to ground on the last shift register, it should be connected to ground on all shift registers.

and the 5v from the darlingtons

Yes remove it. It probably will not stop things from working, but in the context of your circuit it is wrong and could lead to trouble if you powered the LEDs with more than 5V. They are designed as flyback protection when driving motors and should be connected to the motor supply. For your application you do not need them so just disconnect it.

Grumpy_Mike:

Should I disconnect pin 13 from the ground

No the schematic shows it NOT connected to ground on the last shift register, it should be connected to ground on all shift registers.

and the 5v from the darlingtons

Yes remove it. It probably will not stop things from working, but in the context of your circuit it is wrong and could lead to trouble if you powered the LEDs with more than 5V. They are designed as flyback protection when driving motors and should be connected to the motor supply. For your application you do not need them so just disconnect it.

Ok now this is really wierd, I put your code in, shifting out the bytes like so:

shiftOut(dataPin, clockPin, MSBFIRST, 0x0);
shiftOut(dataPin, clockPin, MSBFIRST, 0x8);
shiftOut(dataPin, clockPin, MSBFIRST, 0xff);

But awkwardly enough, the board starts with 1 column of some led's lit, moves up to 2, 3, 4, 5, 6, 7, 8 then just goes column 1,2,3,4,5,6,7,8 and the whole board then stays lit, with some few maybe badly wired exceptions?, 2 rows etc are not lit and sometimes randomly get lit?

The full code:

const int clockPin = 11;
const int latchPin = 12;
const int dataPin = 13;

long int refreshDue;
long int refreshTime = 100;

void setup() {
  pinMode(dataPin, OUTPUT); //Data
  pinMode(clockPin, OUTPUT); //Clock
  pinMode(latchPin, OUTPUT); //Latch
  
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, LOW);
  digitalWrite(latchPin, LOW);
}
void loop(){
    if(millis() >= refreshDue){
    refreshDue = millis() + refreshTime;
    refreshDisplay();
  }
}

void refreshDisplay(){
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, 0x0);
  shiftOut(dataPin, clockPin, MSBFIRST, 0x0);
  shiftOut(dataPin, clockPin, MSBFIRST, 0x8);
  shiftOut(dataPin, clockPin, MSBFIRST, 0xff);
  digitalWrite(latchPin, HIGH);
}

Thanks Mike :slight_smile:

I think it is not wired up like you think it is. For the time being forget the matrix and just put out one pattern to the shift registers. Then go round with a meter or LED and resistor and see if this pattern corresponds to what you expect. Then change the pattern and repeat. Do this five or six times until you spot the fault or you verify that what you send out is what you get on the shift register outputs.