SN74HC595 for 64 led POV globe (school project)

Is there someone who has expiriance with this.
We can make the hardware, software is a big problem.
We want to use an arduino uno for this

We are looking for an assistant who can write the code,
Or who can write a code to shift 8 SN74HC595's in a row so we can copy past the binary or decimal data we can get from an simple exel sheet.

Of course there will be a Facebook of the progress with results and many thanks to our programmer.

thanks,
Hans (Belgium)

If you want fast output, connect the shift registers to the SPI interface: MOSI->Data, SCK->Click, SS->Latch. Then you can use the SPI library to send 8-bit chunks at 8 MHz. Since your 'slave' device has no output you can leave the MISO line unconnected.

i can see your point there,

so is the serial out in bin hex or dec?

let’s say we make it from bottem to top, led1 at Q0 of the first 959, then led2 at Q1 of the first and so on that led 9 of the globe wil be at Q0 from the secund 959 …led 64 wil be at Q7 of 959 nr 8.

How would the code look like for the first line (i will need a delay there) and then te secund line… ansd so on until i have line 128 (or even more lines )

I made an exel so that i can draw anyting i want on a 128Hx64V raster (ad 1 if led needs to be lit)
Than i can calculate the decimal number of al the vertical lines that have to be schifted out.
So for example; dec 18446744073709600000 will light up all led’s
folowed by 0 in the secund line wil make them all dark

Problem for me is writing the code
Making the globe can be done (mechanics and electronics at school)
i alredey started on making the print for the led’s (commen +) 8 at the time with 74 959 en ULN2803A at the end also resistor space for each led on the print. (happy to share the print when tested )

globe would spin at near 3000 rpm or 1500 with dalander
or at every speed with frequentie modulator

so is the serial out in bin hex or dec?

The SPI interface sends 8 bits per transfer so I would store the images as bytes (groups of 8 bits). I would store them as hex but you can use decimal or binary if you like. It all gets converted to binary in the compiler.

For 128 columns of 64 bits:

#include <avr/pgmspace.h>
// Keep the image in PROGMEM (FLASH) to conserve SRAM
const byte image[8][128] PROGMEM = {
 {1, 2, 3, 4, 5, 6,7 ,8},  // First column
 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, // Second column
 {255,255,255,255,255,255,255,255}, // Third column
 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, // Fourth column
.
.
.
};
void loop() {
    for (byte column = 0; column < 128; column++) {
        digitalWrite(SS, LOW);
        for (byte row = 0; row < 8; row++) {
            SPI.transfer(pgm_read_byte(&image[row][column]));
        digitalWrite(SS, HIGH); // Latch the new values
        delayMicroseconds(100);  // Adjust to get desired refresh rate.
        }
    }
}

hanzie:
Is there someone who has expiriance with this.
We can make the hardware, software is a big problem.
We want to use an arduino uno for this

:smiley:
this is super !
We will start working next week on this,
My students will make Facebook page where the progress can be folowed.
Link wil be here soon!

Thanks for these answers,
I wil make some speed and memory space calculation first, so this is out of the way before starting

greetings,
Hans

i am waiting for the componends so i am testing the code first. (John his code)
134: error: too many initializers for 'const byte [8][256]'
I try to solve the errors as they come,
i can not find thies one on the forum,

How do you get the code so far here in this so i can schow the progress?
greetings, Hans

hanzie:
134: error: too many initializers for 'const byte [8][256]'

Do you have 256 rows of 8 bytes each? The rows should look like one of these:

 {1, 2, 3, 4, 5, 6,7 ,8},  // First column
 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, // Second column
 {255,255,255,255,255,255,255,255}, // Third column
 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, // Fourth column

hanzie:
i am waiting for the componends so i am testing the code first. (John his code)
134: error: too many initializers for 'const byte [8][256]'
I try to solve the errors as they come,
i can not find thies one on the forum,

How do you get the code so far here in this so i can schow the progress?
greetings, Hans

You have your indices the wrong way round. You indicated in you earlier posts that you wanted a 256 row array with 8 bytes per row, but what you have defined in an 8 row array with 256 bytes per row. That could be why you are getting an error message.

With 64 LEDs, why not use one MAX7219, and write data into its 8 registers?

If you want fast transfers, use direct port manipulation and no loops:
With an Uno and Chip Select on D10, the SPI SS pin:

#include<SPI.h>  // import library

define an array for the 64 LEDs
byte dataArra[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,}; // some initial data to make a line perhaps

in void setup:
pinMode(10, OUTPUT);  // D10 as output pin

in void loop:

// display update flag set? based on time, or a dataArray change
if (displayUpdate == 1){
displayUpdate = 0; // clear the flag
// send out 8 bytes via SPI to MAX7219, or to 8 shift registers: SCK for clock, MOSI for data, SS for latching the data into output registers
PORTB = PORTB & B11111011; // clear PB2 (SS pin)
SPI.transfer(dataArray[0]);
SPI.transfer(dataArray[1]);
SPI.transfer(dataArray[2]);
SPI.transfer(dataArray[3]);
SPI.transfer(dataArray[4]);
SPI.transfer(dataArray[5]);
SPI.transfer(dataArray[6]);
SPI.transfer(dataArray[7]);
PORTB = PORTB | 0b00000100;  // set PB2 (SS pin)
}[/code}

Which Arduino do you have? That array takes 2 kB of RAM.

If the data in the array is fixed (as you have indicated with the 'const' keyword), then you can use the PROGMEM directive to put it in Flash memory. Don't waste precious RAM resources on something you aren't going to change.

Thanks for al the help, i will upload the scematics so you can see what i am about to do.
Then we can test the code on it. For now i just wanted to load the code in the arduino uno en got errors
I am waiting on the components at school .

I orderd the 74sh959's with ULN2803 at the end so no MAX! i hope this wil work?
I am drawing a print for 8 led's at the time

would be 160 rows (1 turn of the globe) 8 bytes per row(so 8 x 74sh959 in cascade), then start with beginning again.
Data example :
255,255,255,255,255,255,255,255 (line 1)
0,0,0,0,0,0,0,0 (line 2)
255,255,255,255,255,255,255,255 (3)
0,0,0,0,0,0,0,0 (4)
.
and so on until line 160, this schoud give me a striped ball

I want to display the world map.

Tekst message would be later in the project with other arduino uno on opposite side of the globe and further out.
world map would be faster then the rpm of the globe, tekst would be slower then the rpm (1500rpm)
In this way i would create the elusion that 2 globes are spinning in opposite direction.

To this hardware designer, this seems a pretty simple task:
(in response to a PM on this)

#include<SPI.h> 
unsigned long currentTime; 
unsigned long elapsedTime; 
unsigned long previousTime; 
unsigned long duration = 100000UL; // 100mS 
byte latchPin = 10; // PORTB, bit 2 
byte row=0; // 0 to 159 
int arrayPointer=0; // will be 0,8,16,24 
byte dataArray[] = { 
0,0,0,0,0,0,0,0, 
0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 
0,0,0,0,0,0,0,0, 
// etc for the 160 rows 
0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 
}; 
void setup(){ 
pinMode (latchPin, OUTPUT); 
digitalWrite (latchPin, HIGH); 
SPI.begin(); 
} 
void loop(){ 
currentTime = micros(); // all time variables are unsigned long 
elapsedTime = currentTime - previousTime; // calculate how long since last update 
if (elapsedTime >=duration){ // time for next update? 
  previousTime = previousTime + duration; // set up time of next update 
  row=row+1; // keep track of row being displayed 
  if (row == 160) {row = 0;} // reset if reach the end 
  arrayPointer = row * 8; // point to start of next group of data 
  // send the data out 
  PORTB = PORTB & B11111011; // clear PORTB, bit 2 for latch signal, adjust to your actual setup 
  SPI.transfer(dataArray[arrayPointer]); 
  SPI.transfer(dataArray[arrayPointer+1]); 
  SPI.transfer(dataArray[arrayPointer+2]); 
  SPI.transfer(dataArray[arrayPointer+3]); 
  SPI.transfer(dataArray[arrayPointer+4]); 
  SPI.transfer(dataArray[arrayPointer+5]); 
  SPI.transfer(dataArray[arrayPointer+6]); 
  SPI.transfer(dataArray[arrayPointer+7]);   
  PORTB = PORTB | B00000100; // set latch signal 
  } // end time check 
// do other stuff if not time for an update 
} // end loop

CrossRoads:
With 64 LEDs, why not use one MAX7219, and write data into its 8 registers?

He wants this for a POV display!

Your point? There is plenty of time to write the 8 registers and let the MAX7219 display it.
And if not, use the non-multiplexed shift registers.

Heh, heh.

The MAX7219 is a multiplexing display driver, refreshing at a nominal 800 Hz.