Text scrolling backwards

I have built a prototype scrolling LED text board using Hari's design from 2010 http://forum.arduino.cc/index.php/topic,8672.0.html

I did change the column drivers to 74HC595 as per an instructable http://www.instructables.com/id/48x8-SCROLLING-MATRIX-LED-DISPLAY-USING-ARDUINO-CO/?ALLSTEPS I added capacitors between Vcc and ground of each shift register

Everything appears to be working except it scrolls entirely backwards. I don't even understand how this is possible as i thought the 74HC595 fed in order but somehow they are feeding backwards. My first question is software or hardware? The fact that it actually working just backwards makes me think it is something in software but others have used this sketch and i can find no reports of problems.
I know this is probably really basic and may have been covered somewhere already but i do not have the abilities to solve or find the answer to my problem.
Any one know of a book "Arduino for the over 65" It could also be re-titled "Arduino for Kindergarteners"

scrolling_48x8.ino (4.35 KB)

"Arduino for Teens", will help you a lot.

74HC595 is a lousy chip for driving LEDs directly, very current limited.
You likely just need to change the data you are shifting into the 595's to change the order they have their outputs turned on.

CrossRoads:
"Arduino for Teens", will help you a lot.
http://www.amazon.com/gp/product/1285420896/

74HC595 is a lousy chip for driving LEDs directly, very current limited.
You likely just need to change the data you are shifting into the 595's to change the order they have their outputs turned on.

A hint or two on how to do that would be much appreciated
Thanks
I have the book and it is over my head-Thus my comment Old Retired carpenter and hammers are my forte -I am still trying to learn how to use a basic cell phone :slight_smile:

I'd have to see the code you're running now to advice on how to change it.
I've posted here about using SPI.transfer to send data from an array into shift registers.
Say for example you had two arrays, one that 48 bytes long that held the current "frame" of what was being displayed, and another that was 48 bits x 48 rows deep. Each row would correspond to one column being on:
10000000 00000000 00000000 00000000 00000000 00000000 // bytes 0-5
01000000 00000000 00000000 00000000 00000000 00000000 // bytes 6-11
00100000 00000000 00000000 00000000 00000000 00000000 // bytes 12-17
etc
00000000 00000000 00000000 00000000 00000000 00000010 // bytes 276-281
00000000 00000000 00000000 00000000 00000000 00000001 // bytes 282-287

So for the multiplexing, you read from the frame array and put that on the column anodes, then shift out 6 bytes of 1 and mostly zeroes to turn on the cathode driver for the matching column.
(or invert the 0s & 1s above if driving cathodes directly. What's high & low will depend on your hardware setup, but this gives the idea of how it could work)

void loop(){
currentMicros = micros();  // capture the "time"
elapsedMicros = currentMicros - previousMicros; // how long since last time capture?
if (elapsedMicros >= columnDuration){ // time for the next column to be shown?
previousMicros = previousMicros + columnDuration; // set up next time to change
for (x=0; x<48; x=x+1){  // which column being displayed
// put anode data out
digitalWrite (anodeSS, LOW);
SPI.transfer (anodeArray[x]);
digitalWrite (anodeSS, HIGH);
// put 6 bytes of cathode data out
digitalWrite (cathodeSS, LOW);
SPI.transfer (anodeArray[x*48]+0);
SPI.transfer (anodeArray[x*48]+1);
SPI.transfer (anodeArray[x*48]+2);
SPI.transfer (anodeArray[x*48]+3);
SPI.transfer (anodeArray[x*48]+4);
SPI.transfer (anodeArray[x*48]+5);
digitalWrite (cathodeSS, HIGH);
} // end time check 
// do other stuff, like update anodeArray with any frame changes
} // end loop

The cathode array could go in progmem to save SRAM space; or you could just use 6 bytes and update the data after sending it out. Depends on how much time you wanted to put into walking a 1 across the 6 bytes.
Ex:
cathode0 = 0b10000000; // initialize it
then as part of x<48 if loop:
if (cathode0 >0 0){
cathode0 = cathode0 >>1 // now its 0b01000000
if (cathode0 == 0){
cathode1 == 0b1000000;
}
if (cathode1 >=0){
cathode1 = cathode1 >>1;
}
etc
I started working that out, order of checking & shifting is important, just got too messy for me, so I just put the cathode data into an array and said the heck with it.
6 SPI.transfers and its done, way less code than creating the data on the fly, and if the order is reversed, just change the array.

Next time, use code tags (# button) and copy/paste it in. Works better all around.

I can't follow all that. Am not a software engineer, I just glaze over reading other people's code.

Now I am really confused, I few rather lacking in understanding what you are saying. Are you saying what i put in to message is not code. It is what i loaded into my Arduino I just used the IDE " copy for forum" and pasted it

Sorry for taking your time up on this

To attach code to a post click on the hash icon # ( above the smily's at the top of the message pane) where you want the code to appear in your post and paste the code in between the sets of square brackets enclosing the words code and /code
  HERE See attached image

Thanks Pedro

int x;
int y;
int latchPin1 = 5; //Arduino pin connected to blue 12 RCLK of 74HC595
int clockPin1 = 6; //Arduino pin connected to green 11 SRCLK of 74HC595
int dataPin1 = 7;  //Arduino pin connected to violet 14 SER of 74HC595

//-- Rows (Positive Anodes) --
int latchPin2 = 9; //Arduino pin connected to yellow Latch 12 RCLK of 74HC595
int clockPin2 = 10; //Arduino pin connected to white Clock 11 SRCLK of 74HC595
int dataPin2 = 8;  //Arduino pin connected to grey Data 14 SER of 74HC595

//=== B I T M A P ===
//Bits in this array represents one LED of the matrix
// 8 is # of rows, 7 is # of LED matrix we have
byte bitmap[8][8]; // Change the 7 to however many matrices you want to use.second 8 is #matrix
int numZones = sizeof(bitmap) / 8;
int maxZoneIndex = numZones-1;
int numCols = numZones * 8;

byte alphabets[][5] = {
  {0,0,0,0,0},
  {31, 36, 68, 36, 31},
  {127, 73, 73, 73, 54},
  {62, 65, 65, 65, 34},
  {127, 65, 65, 34, 28},
  {127, 73, 73, 65, 65},
  {127, 72, 72, 72, 64},
  {62, 65, 65, 69, 38},
  {127, 8, 8, 8, 127},
  {0, 65, 127, 65, 0},
  {2, 1, 1, 1, 126},
  {127, 8, 20, 34, 65},
  {127, 1, 1, 1, 1},
  {127, 32, 16, 32, 127},
  {127, 32, 16, 8, 127},
  {62, 65, 65, 65, 62},
  {127, 72, 72, 72, 48},
  {62, 65, 69, 66, 61},
  {127, 72, 76, 74, 49},
  {50, 73, 73, 73, 38},
  {64, 64, 127, 64, 64},
  {126, 1, 1, 1, 126},
  {124, 2, 1, 2, 124},
  {126, 1, 6, 1, 126},
  {99, 20, 8, 20, 99},
  {96, 16, 15, 16, 96},
  {67, 69, 73, 81, 97},
};

//=== S E T U P ===

void setup() {
  pinMode(latchPin1, OUTPUT);
  pinMode(clockPin1, OUTPUT);
  pinMode(dataPin1, OUTPUT);

  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);
 
  //-- Clear bitmap --
  for (int row = 0; row > 8; row++) {
    for (int zone = 0; zone <= maxZoneIndex; zone++) {
      bitmap[row][zone] = 0;
    }
  }
}

//=== F U N C T I O N S ===
// This routine takes whatever we've setup in the bitmap array and display it on the matrix
void RefreshDisplay()
{
  for (int row = 0; row < 8; row++) {
    int rowbit = 1 << row;
    digitalWrite(latchPin2, LOW);  //Hold latchPin LOW for as long as we're transmitting data
    shiftOut(dataPin2, clockPin2, MSBFIRST, rowbit);   //Transmit data

    //-- Start sending column bytes --
    digitalWrite(latchPin1, LOW);  //Hold latchPin LOW for as long as we're transmitting data

    //-- Shift out to each matrix (zone is 8 columns represented by one matrix)
    for (int zone = maxZoneIndex; zone >= 0; zone--) {
      shiftOut(dataPin1, clockPin1, MSBFIRST, bitmap[row][zone]);
    }

    //-- Done sending Column bytes, flip both latches at once to eliminate flicker
    digitalWrite(latchPin1, HIGH)
    ;digitalWrite(latchPin2, HIGH)

    //-- Wait a little bit to let humans see what we've pushed out onto the matrix --
    ;delayMicroseconds(500);
  }
}

// Converts row and colum to actual bitmap bit and turn it off/on
void Plot(int col, int row, bool isOn)
{
  int zone = col / 8;
  int colBitIndex = x % 8;
  byte colBit = 1 << colBitIndex;
  if (isOn)
    bitmap[row][zone] =  bitmap[y][zone] | colBit;
  else
    bitmap[row][zone] =  bitmap[y][zone] & (~colBit);
}
// Plot each character of the message one column at a time, updated the display, shift bitmap left.
void AlphabetSoup()
{
  char msg[] = "HELP ME I DONOT KNOW WHAT I AM DOING ";

  for (int charIndex=0; charIndex < (sizeof(msg)-1); charIndex++)
  {
    int alphabetIndex = msg[charIndex] - '@';
    if (alphabetIndex < 0) alphabetIndex=0;
   
    //-- Draw one character of the message --
    for (int col = 0; col < 6; col++)
    {
      for (int row = 0; row < 8; row++)
      {
        bool isOn = 0;
        if (col<5) isOn = bitRead( alphabets[alphabetIndex][col], 7-row ) == 1;
        Plot( numCols-1, row, isOn)
    ;  }
     
      //-- The more times you repeat this loop, the slower we would scroll --
      for (int refreshCount=0; refreshCount < 7; refreshCount++) //change  this value to vary speed
        RefreshDisplay();
      //-- Shift the bitmap one column to left --
      for (int row=0; row<8; row++)
      {
        for (int zone=0; zone < numZones; zone++)
        {
          bitmap[row][zone] = bitmap[row][zone] >> 1;
                    // Roll over lowest bit from the next zone as highest bit of this zone.
          if (zone < maxZoneIndex) bitWrite(bitmap[row][zone], 7,
bitRead(bitmap[row][zone+1],0));
        }
      }
    }
  }
}

//=== L O O P ===
void loop() {
  AlphabetSoup();
}

I tend to get in the forum later at , and feel brain dead trying to read other's code. Hard enough following my own thinking at times 8)