Go Down

Topic: trying to control 37leds with 5x 74HC595 (Read 2314 times) previous topic - next topic

Mar 12, 2012, 09:25 am Last Edit: Mar 12, 2012, 09:35 pm by kjellebormans Reason: 1
i have to make a project for school, The electronic roulette.
So the french roulette table counts 37numbers (0-36) so for each number i use a led that i am controlling from my arduino thats controls my shift register but one shift register is not enough, so i am using 5 shift registers in one line. the 595 got a serial output so i connect the first 595 to the arduino the data signal line continues to the next by the serial output. But now my question i only get my 2 first registers work because the arduino software has a limit of maximum 4bytes so i seperated it in 3words ( i could do it in 2words and 1int but just to make the total view easier i used 3).
i think the problem is with seperate the 3 words into 6 registers and then sending them out with the shiftout function. does someone have an idea that might help me all replies are very welcome
(my full software that i have up to now you can see below)
with kind regards,

kjelle

Code: [Select]
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;

int del = 10; //delay

int Randomwaarde;
int thisLed;


void setup() {
  Serial.begin(9600);
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);

  randomSeed(analogRead(3));
  Randomwaarde = random(190, 210);
  Serial.println(Randomwaarde);

}

void loop() {


  for (thisLed = 0; thisLed <= 36; thisLed++) {

    if (del <= Randomwaarde) //controleerd de del(de vertraging) met de opgegeven randomwaarde
    {
      registerWrite(thisLed,HIGH);
      delay(del);
    }
    else
    { 
      int EndLed = thisLed ;
      registerWrite(EndLed, HIGH);
      delay(10000);
      randomSeed(analogRead(3));
      Randomwaarde = random(190, 210);
      Serial.println(EndLed);
      Serial.println(Randomwaarde);

      del = 10;

    }
  }
}


void registerWrite(int whichPin, int whichState)

{

  word word1 = 0;
  word word2 = 0;
  word word3 = 0;
 
  byte registerSix;
  byte registerFive;
  byte registerFour;
  byte registerTree;
  byte registerTwo;
  byte registerOne;

  digitalWrite(latchPin, LOW);

  if(whichPin <16)
  {

    bitWrite(word1, whichPin, whichState);

    registerOne = highByte(word1);
    registerTwo = lowByte(word1);

  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
  }

  if(whichPin >=16 && whichPin <=31)
  {

    bitWrite(word2, whichPin, whichState);

    registerTree = highByte(word2);
    registerFour = lowByte(word2);


  shiftOut(dataPin, clockPin, MSBFIRST, registerFour);
  shiftOut(dataPin, clockPin, MSBFIRST, registerTree);
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
  }

  if(whichPin >=32 && whichPin <=36)
  {

    bitWrite(word3, whichPin, whichState);

    registerFive = lowByte(word3);
    registerSix = highByte(word3);
 
 
  shiftOut(dataPin, clockPin, MSBFIRST, registerSix);
  shiftOut(dataPin, clockPin, MSBFIRST, registerFive);
  shiftOut(dataPin, clockPin, MSBFIRST, registerFour);
  shiftOut(dataPin, clockPin, MSBFIRST, registerTree);
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
}

  digitalWrite(latchPin, HIGH);
 
  Serial.println(whichPin);

  del = del +1;

}   


ajofscott

All 6 bytes must be sent each update with the first bye being 0x00.

#2
Mar 12, 2012, 11:15 am Last Edit: Mar 12, 2012, 11:17 am by kjellebormans Reason: 1
like this you mean ?
Code: [Select]

if(whichPin <16)
 {

   bitWrite(word1, whichPin, whichState);

   registerOne = highByte(word1);
   registerTwo = lowByte(word1);

 shiftOut(dataPin, clockPin, MSBFIRST, registerSix);
 shiftOut(dataPin, clockPin, MSBFIRST, registerFive);
 shiftOut(dataPin, clockPin, MSBFIRST, registerFour);
 shiftOut(dataPin, clockPin, MSBFIRST, registerTree);
 shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
 shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
 }

 if(whichPin >=16 && whichPin <=31)
 {

   bitWrite(word2, whichPin, whichState);

   registerTree = highByte(word2);
   registerFour = lowByte(word2);


 shiftOut(dataPin, clockPin, MSBFIRST, registerSix);
 shiftOut(dataPin, clockPin, MSBFIRST, registerFive);
 shiftOut(dataPin, clockPin, MSBFIRST, registerFour);
 shiftOut(dataPin, clockPin, MSBFIRST, registerTree);
 shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
 shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
 }

 if(whichPin >=32 && whichPin <=36)
 {

   bitWrite(word3, whichPin, whichState);

   registerFive = lowByte(word3);
   registerSix = highByte(word3);


 shiftOut(dataPin, clockPin, MSBFIRST, registerSix);
 shiftOut(dataPin, clockPin, MSBFIRST, registerFive);
 shiftOut(dataPin, clockPin, MSBFIRST, registerFour);
 shiftOut(dataPin, clockPin, MSBFIRST, registerTree);
 shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
 shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
}

Grumpy_Mike

Quote
the arduino software has a limit of maximum 4bytes

No it does not.
If you look at shift out at :-
http://arduino.cc/en/Reference/shiftOut
you will see it says:-
Quote
Shifts out a byte of data one bit at a time.

So combining them is wrong, just send all the bytes out to the shift register. There is no need for any of the whichPin nonsense.

Do you have tryied this bfore because i can control them till 16bits but then the memory is not enough unsigned long can handle 2byte but 37 has +/- 4bytes..?

You could multiplex them, 16 LEDs + 3 phases, only 2 registers + 3 lines for sink drive, or 3 registers.
I also have PIC related web domain.

Grumpy_Mike

Quote
Do you have tryied this bfore because i can control them till 16bits

Yes I have tried this before. You are only shifting out a byte at a time, but then if you don't want to learn then don't ask the question.

sorry maybe i came wrong over but maybe if you have an example you can post it ?
because my teacher also don't know a real solution for it ?
so if you could it will help alot :)
kind regards, kjelle


Quote
Do you have tryied this bfore because i can control them till 16bits

Yes I have tried this before. You are only shifting out a byte at a time, but then if you don't want to learn then don't ask the question.

Grumpy_Mike

Well it depends on exactly what you want to do. With 5 shift registers you are best having an array of 5 bytes. However if for some reason you want it in one variable you could use a long long - that is 64 bits long.
Do you want to use the shift out function? You can just as easily roll your own.
This is an example using byte arrays, I have not tested this but it compiles:-
Code: [Select]
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;

byte leds [] ={0,1,2,3,4}; // 5 bytes to shift out //
void setup(){
    updateLEDs();
}
void loop(){
}

void updateLEDs(){  // clocks out the LED values
for(int i=0; i<5; i++){
shiftOut(dataPin, clockPin, MSBFIRST, leds[i]);
}
}


i need to make a ledroulette, so my leds are starting to spin really fast (like the ball in the game) and it slows down till it have the same value as my random programme so actually i need a really long variable ..
my hardware is not at my envirmont but i will test it as soon as possible.
many thanks for your help


Well it depends on exactly what you want to do. With 5 shift registers you are best having an array of 5 bytes. However if for some reason you want it in one variable you could use a long long - that is 64 bits long.
Do you want to use the shift out function? You can just as easily roll your own.
This is an example using byte arrays, I have not tested this but it compiles:-
Code: [Select]
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;

byte leds [] ={0,1,2,3,4}; // 5 bytes to shift out //
void setup(){
    updateLEDs();
}
void loop(){
}

void updateLEDs(){  // clocks out the LED values
for(int i=0; i<5; i++){
shiftOut(dataPin, clockPin, MSBFIRST, leds[i]);
}
}



Grumpy_Mike

Remember that code will just output a fixed pattern on your LEDs, you need to drive it with your application code to make it do anything.

Chagrin

Sounds like you're looking for an elegant method of handling a 36 bit array. Run this; watch the serial output and see if it's what you're looking for.

Code: [Select]
void setup() {
  Serial.begin(9600);
}

unsigned long long registerLEDs = 0; // unsigned long long is 64 bits wide
unsigned long long tempLEDs = 0;

void loop() {
  if (registerLEDs == 0 || registerLEDs>>35 == 1) {
    registerLEDs = 1; // set the "ball" back to the first position
  } else {
    registerLEDs = registerLEDs * 2; // move the "ball" one position up
  }
 
  delay(300);
 
  tempLEDs = registerLEDs;
  for (int x = 0; x <= 4; x += 1) {
    byte y = tempLEDs % 256; // the last 8 bits
    // you would shiftout "y" here
    Serial.print(y, BIN); // note that the output is not left-padded with zeroes
    Serial.print('|');
    tempLEDs = tempLEDs>>8; // shift all the bits in tempLEDs 8 positions to the right
  }

  Serial.println(); Serial.println();

Nick Gammon


But now my question i only get my 2 first registers work because the arduino software has a limit of maximum 4bytes so i seperated it in 3words ...


What limit would that be?

Take a look here:

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

I calculated this number with the Arduino:

Code: [Select]
80! = 71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000


Try using SPI.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

Plus there is a long long type. That is 64 bits.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

i guess that the shift out function isn't the best way to work with...
I'm thinking te create a for loop with the unsigned long long variable
and then just always multiplying (*2) each bit..
but 237  is al lot of memory can the mega handle it ?

if someone else has a other idea about how it could work to he may always post it idea :)

Go Up