trying to control 37leds with 5x 74HC595

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

//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;

}

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

like this you mean ?

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);
}

the arduino software has a limit of maximum 4bytes

No it does not.
If you look at shift out at :-

you will see it says:-

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.

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 :slight_smile:
kind regards, kjelle

Grumpy_Mike:

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.

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:-

 //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

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:-

 //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]);
}
}

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.

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.

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();

kjellebormans:
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:

I calculated this number with the Arduino:

 80! = 71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000

Try using SPI.

Plus there is a long long type. That is 64 bits.

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 :slight_smile:

kjellebormans:
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..

You know how I know you didn't run or look at my sketch? :~

Chagrin:

kjellebormans:
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..

You know how I know you didn't run or look at my sketch? :~

I did runned your sketch and looked at it in the serial but i didn't know how to send it out to my shift register..
Now i am writting my own sketch with some parts from your sketch and trying to make it work for my hardware..

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

Why so you can ignore that as well?

Grumpy_Mike:

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

Why so you can ignore that as well?

Sorry grumpy_mike but i need to use the Shift register and i need to keep it as cheap as possible ..
so if i use spi i need to make my project more expensiver and i am on the limit rigth know..
i got 5 shift registers, enough leds and the arduino and that are the things i only can use for this project.
because the software steering is hard because i can't split up the unsigned long long into 5 or more pieces because the shift register works with an 8bit system so you need to send 5times 8bits you can't send them in one piece.. The highbits and lowits from the arduino software just splits a unsigned long or word but the split in 2 thats easy because you just have 16 bits .. but the unsigned long long got 64 bits if you use highbit and lowbit on that i don't know what you will get but it isn't the upers 32bits and the other 32 bits that i would need to split up again untill its 8bits / piece .. i am know wondering if it would work on a other methode .. i 'm trying to just read in one bit and then shift them on a randomspeed from 0->36-0->36-->....
i hope you understand me :slight_smile:
greetzz kjelle

kjellebormans:
so if i use spi i need to make my project more expensiver and i am on the limit rigth know..

Why? I used SPI to drive some 595s. It's built into the processor. It's hardly an expense.

I don't understand the rest of what you said. You don't need to put things into an unsigned long. Why would you even do that?