Go Down

Topic: POV toy (Read 1 time) previous topic - next topic

georgelstuart

Hey experts!
I have a problem that is puzzling me. I created a Persistence of Vision LED toy on Arduino that works but I am trying to take it to the next step and it is giving me a hard time.
I started off with working code copied from the web, it writes data to a vertical string of LEDs that can be coded with letters to spell out words. I cleaned it up a bit and it works great, but is only a column of 5 leds and doesn't offer much resolution. I mapped the code over to a column of 7 LEDs and it just doesn't work under that configuration. maybe someone who is more experienced can give it a quick once over and point me in the right direction...

This is the code that works with a five pixel tall array of LEDs that writes three pixels wide as it moves from left to right and creates the image in midair:

// defining the alphabet
int _[3][5] = {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}};
int A[3][5] = {{0,1,1,1,1}, {1,0,1,0,0}, {0,1,1,1,1}};
int B[3][5] = {{1,1,1,1,1}, {1,0,1,0,1}, {0,1,0,1,0}};
int C[3][5] = {{0,1,1,1,0}, {1,0,0,0,1}, {1,0,0,0,1}};
int D[3][5] = {{1,1,1,1,1}, {1,0,0,0,1}, {0,1,1,1,0}};
etcetera for rest of alphabet

int letterSpace;
int dotTime;

void setup()
{
 // setting the ports of the leds to OUTPUT
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 
 // defining the space between the letters (ms)
 letterSpace = 10;
 // defining the time dots appear (ms)
 dotTime = 5;
 
}

void printLetter(int letter[3][5])
{
 int y;
 int x;
 // x is column and y is row within 2d array for each letter
 // as y increments, it prints the dots of each vertical element
 // as x increments, it moves the print scan to the next vertical element to the right

 for (x=0; x<3; x++) {
 for (y=0; y<5; y++){
   digitalWrite(y+2, letter
  • [y]);
     }
      delay(dotTime);
      for (y=0; y<5; y++)
     {
       digitalWrite(y+2, 0);
     }

     }
     delay(letterSpace);
     }
    void loop()
    {
     // printing some letters
     
     printLetter(H);
     printLetter(E);
     printLetter(L);
     printLetter(L);
     printLetter(O);
     printLetter(_);
    }
    this 5X3 code works great, but it doesn't give enough resolution for good readability, so I am thinking that 7 tall by 5 wide would be about right. It seems easy to map it out larger, but I must be missing something because it doesn't work!
    I Breadboarded a seven pixel tall array of LEDs and wrote the following code to run as a 7 tall by 5 wide POV display for more resolution and it doesn't work. It is exactly the same code, but mapped for 7X5 rather than 5X3. I don't think it is a hardware problem, the 5X3 code runs fine on the same hardware, both mapped to output pins 2-7 and 4-9.
    Please take a look:
    Thanks in advance for any help!

    // defining the alphabet
    int _[5][7] = {{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}};
    int A[5][7] = {{0,0,0,0,1,1,1}, {0,0,0,1,0,0,0}, {1,0,0,1,0,0,0}, {0,0,0,1,0,0,0}, {0,0,0,0,1,1,1}};
    int B[5][7] = {{1,1,1,1,1,1,1}, {1,0,0,1,0,0,1}, {1,0,0,1,0,0,1}, {1,0,0,1,0,0,1}, {0,1,1,0,1,1,0}};
    int C[5][7] = {{0,0,1,1,1,0,0}, {1,1,0,0,0,1,1}, {1,0,0,0,0,0,1}, {1,1,0,0,0,1,1}, {0,1,1,0,0,1,0}};
    int D[5][7] = {{1,1,1,1,1,1,1}, {1,1,0,0,0,0,1}, {1,0,0,0,0,0,1}, {0,1,0,0,0,1,0}, {0,0,1,1,1,0,0}};
    etcetera for rest of alphabet

    int letterSpace;
    int dotTime;

    void setup()
    {
     // setting the ports of the leds to OUTPUT
     pinMode(2, OUTPUT);
     pinMode(3, OUTPUT);
     pinMode(4, OUTPUT);
     pinMode(5, OUTPUT);
     pinMode(6, OUTPUT);
     pinMode(7, OUTPUT);
     pinMode(8, OUTPUT);
     
     // defining the space between the letters (ms)
     letterSpace = 10;
     // defining the time dots appear (ms)
     dotTime = 5;
     
    }

    void printLetter(int letter[5][7])
    {
     int y;
     int x;
     int progression;
     
     // x is column and y is row within 2d array for each letter
     // as y increments, it prints the dots of each vertical element
     // as x increments, it moves the print scan to the next vertical element of 7 LEDs to the right

     for (x=0; x<5; x++){
     for (y=0; y<7; y++){
       digitalWrite(y+2, letter
  • [y]);
     }
      delay(dotTime);
      for (y=0; y<7; y++)
     {
       digitalWrite(y+2, 0);
     }

     }
     delay(letterSpace);
     }
     

    void loop()
    {
     // printing some letters
     
     printLetter(H);
     printLetter(E);
     printLetter(L);
     printLetter(L);
     printLetter(O);
     printLetter(_);
    }


mem

#1
Jul 06, 2008, 10:09 am Last Edit: Jul 06, 2008, 11:08 am by mem Reason: 1
You may have run out of memory. The Arduino only has 1k of RAM and your larger arrays use almost all of that up. Try it with bytes instead of ints

change:
int [5][7] =

to
byte [5][7] =


that will cut the memory usage in half, try it and see it that gets it to work.

You could also use program memory instead of RAM using PROGMEM, see : http://www.arduino.cc/en/Reference/PROGMEM

Not really necessary in your application but you can reduce the memory usage even more if you store your arrays as bits, but its more complicated. There is an example of some code that reads arrays defined as bits in posts 12 and 14 of this thread: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1214715130/0

you would do something like:
byte A[5] = {{0b00001110}, {0b00010000}, {0b10010000}, {0b00010000}, {0b00001110}};  // define bits

 for(row=0; row < 5, row++)
   for(int column=0; column < 7; column++ )  // you may need to go in reverse here depending on how you store your bits
        boolean value = array[row] & (1<< column) ;
 


roypardi

not to hijack this thread, but reading the memory links you posted has made me wonder about the details of memory usage: the sketch is stored in Flash memory but when the Arduino starts up, does it load the sketch into SRAM? (doesn't seem like it could because of the size disparity) or does it repeatedly read program instructions from the Flash memory?

mem

Only data is loaded into SRAM, code is run from flash. Using PROGMEM allows largish amounts data to kept in flash and this is only moved into DRAM byte by byte  as needed

kg4wsv

The ATmega (and many other microcontrollers) are Harvard architecture machines, where the program and data areas are physically separate, with their own address spaces.  The program runs from FLASH, in the case of the ATmega.  Only data is stored in SRAM.  THis is why techniques like PROGMEM are needed - special hardware is used to move data from one program space to another.  (EEPROM is a third memory space in the ATmega.)

Most microprocessors (e.g. Pentium, SPARC, etc) are von Neumann architecture, where program and data share a common physical memory and address space.

-j


georgelstuart

Mem,
thanks for helping out a newbie! I commented out half the arrays and of course it works now. I will have to try the other solutions as exercises in learning.
Thanks again,

follower

For those interested, the OP got some replies on an avrfreaks thread also, which might be helpful to people with similar questions in the future:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=66102

--Phil.

Go Up