Forum Index > Projects > LED Pegboard and Matrix Projects
 ghosting
 |  Printable Version
By: MarkWexler (offline) on Saturday, March 26 2011 @ 11:17 AM PDT (Read 1597 times)  
MarkWexler

Hello. There have been periodic discussions of ghosting (unwanted LEDs lighting up), but no really definitive recipe for getting rid of it. I have a serial version of Peggy 2, and I have serious ghosting issues with the following code:

PHP Formatted Code

#include <Peggy2Serial.h>

union mix_t {
    unsigned long atemp;
    unsigned char c[4];
} mix;
 
void SPI_TX(char cData)
{
    SPDR = cData;
    while (!(SPSR & _BV(SPIF))) ;
}

Peggy2 displayArea;

void setup()
{
    displayArea.HardwareInit();
}

void DrawOneDot(byte x, byte y, byte value)
{
    byte pc, pd;
   
    byte j = y + 1;
 
    if (j < 16) {
        pd = j;
        pc = ((pd & 3) << 4) | (PORTC & 15);
        pd = pd & 252;
    }
    else {
        pd = (j - 15) << 4;  
        pc  = PORTC & 15;
    }

    if (value)
        mix.atemp = (uint32_t) 1 << x;
    else
        mix.atemp = 0;
       
    PORTC = PORTC & 15;
    PORTD = 0;

    SPI_TX(mix.c[3]);
    SPI_TX(mix.c[2]);
    SPI_TX(mix.c[1]);
    SPI_TX(mix.c[0]);

    PORTB |= 2U;
    PORTB &= 253U;

    PORTD = pd;
    PORTC = pc;
}

void loop()
{
    DrawOneDot(0, 0, 1);
    //delay(1);            // put delay to reduce (but not decrease shadow)
    DrawOneDot(24, 24, 1);
    //delay(1);
}
 



What I want is to light up just the northwest and southeast pixels; with the above code, I also get rather bright ghosting on the NE and SW pixels. Un-commenting the delay() calls, I can lower, but not reduce the ghosting (even for higher delays).

What should I do? It seems that I should be putting the delays somewhere else, but I'm not sure where. Or is it a hardware issue?

(I should point out that for my application--studying vision during high-speed eye movements--the ghosting is a serious problem.)

Thanks a lot for any advice on this.

Mark


Forum Apprentice
Apprentice

Status: offline

Registered: 04/15/10
Posts: 3

Profile Email    
   
By: Windell (offline) on Saturday, March 26 2011 @ 06:30 PM PDT  
Windell

Yes, the ghosting that you have in that example is very strong, and it is possible to do much, much better. I do understand that this is important, and you are not the only person using Peggy2 (and its variants) for visual testing.

In general, it is usually not possible to completely eliminate ghosting in a multiplexed array-- there are tradeoffs in terms of power and refresh rate that must always be considered. You can, however, reduce it to the point that I hope will no longer be a problem for your application.

Try the following code, and let me know what you think:

PHP Formatted Code
#include <Peggy2Serial.h>

union mix_t {
    unsigned long atemp;
    unsigned char c[4];
} mix;
 
void SPI_TX(char cData)
{
    SPDR = cData;
    while (!(SPSR & _BV(SPIF))) ;
}

Peggy2 displayArea;

void setup()
{
    displayArea.HardwareInit();
}

void DrawOneDot(byte x, byte y, byte value)
{
    byte pc, pd;
     byte j = y + 1;
 
 // First, send command to blank all columns.
    SPI_TX(0);
    SPI_TX(0);
    SPI_TX(0);
    SPI_TX(0);

    PORTB |= 2U;
    PORTB &= 253U;
   
 
    if (j < 16) {
        pd = j;
        pc = ((pd & 3) << 4) | (PORTC & 15);
        pd = pd & 252;
    }
    else {
        pd = (j - 15) << 4;  
        pc  = PORTC & 15;
    }

    if (value)
        mix.atemp = (uint32_t) 1 << x;
    else
        mix.atemp = 0;
     
// You can add a delay here to reduce ghosting AT THE COST OF OVERALL BRIGHTNESS
//    delayMicroseconds(1000);  
    PORTC = PORTC & 15;
    PORTD = 0;

    SPI_TX(mix.c[3]);
    SPI_TX(mix.c[2]);
    SPI_TX(mix.c[1]);
    SPI_TX(mix.c[0]);

    PORTD = pd;
    PORTC = pc;
    PORTB |= 2U;
    PORTB &= 253U;


//asm("nop");   // short delay

}

void loop()
{

 // The following variable sets the amount of time that each spot is lit.  
 // There is a tradeoff: more time per spot is brighter and has less ghosting,
 // but it reduce the refresh rate.
 //
 // Sample values with two spots:
 // Value: 20 microseconds: Perfect flicker-free redraw, but with some ghosting
 // Value: 1000 microseconds: flicker-free unless you look quickly side-to-side, reduced ghosting
 // Value: 5000 microseconds: flickery when you look side-to-side, low ghosting
 
 unsigned int TimePerSpot = 5000;  // Microseconds, up to 65535.
   
 
    DrawOneDot(0, 0, 1);
    delayMicroseconds(TimePerSpot);
    DrawOneDot(24, 24, 1);
    delayMicroseconds(TimePerSpot);
}
 



There is a variable to set at the end, TimePerSpot, which you can adjust to get higher brightness and lower ghosting, but at the cost of lower refresh rate. There is also a place in the middle where you can add a delay to reduce the ghosting at the cost of overall brightness. You may also want to consider putting the Peggy behind a sheet of darkened acrylic to improve the overall contrast.


Windell H. Oskay
drwho(at)evilmadscientist.com
http://www.evilmadscientist.com/

Forum Evil Scientist
Evil Scientist

Status: offline

Registered: 06/15/06
Posts: 1932
Sunnyvale, CA

Profile Email Website  
   
By: MarkWexler (offline) on Wednesday, April 06 2011 @ 07:25 AM PDT  
MarkWexler

Dear Windell,

Thank you very much for your code, and sorry to take so long in my reply. The program works as you say in the comments: at 20 microsec delay there's ghosting, less at 1000 microsec, and none at all at 5000 microsec.

Unfortunately, this way of eliminating ghosting comes at a heavy price: after updating a row, you have to wait 5 milliseconds until you update another one, if you do not want the ghost of the first row to appear in the second. It's kind of throwing the baby out with the bathwater! Although I suppose that for most applications, this isn't really an issue.

Mark


Forum Apprentice
Apprentice

Status: offline

Registered: 04/15/10
Posts: 3

Profile Email    
   
By: Windell (offline) on Wednesday, April 06 2011 @ 11:40 AM PDT  
Windell

Unfortunately, this way of eliminating ghosting comes at a heavy price: after updating a row, you have to wait 5 milliseconds until you update another one, if you do not want the ghost of the first row to appear in the second.



That's just an extreme example, and not necessarily one that I'm recommending. You can also increase the apparent contrast at the expense of maximum brightness, by adding a neutral density filter over the top-- that may be a more acceptable way to eliminate ghosting for your application.

>Although I suppose that for most applications, this isn't really an issue.

True indeed. You wouldn't see the ghosting (even in the 20 microsec example) in a video application, for example.


Windell H. Oskay
drwho(at)evilmadscientist.com
http://www.evilmadscientist.com/

Forum Evil Scientist
Evil Scientist

Status: offline

Registered: 06/15/06
Posts: 1932
Sunnyvale, CA

Profile Email Website  
   



 All times are PDT. The time is now 04:48 PM.
Normal Topic Normal Topic
Locked Topic Locked Topic
Sticky Topic Sticky Topic
New Post New Post
Sticky Topic W/ New Post Sticky Topic W/ New Post
Locked Topic W/ New Post Locked Topic W/ New Post
View Anonymous Posts 
Able to Post 
Filtered HTML Allowed 
Censored Content 

Evil Mad Scientist Forum Archives — Read only!

Please visit our new forums for new discussions.


DIY Hardware for Electronic Art


The Original Egg-Bot Kit


Octolively
Interactive LED kits


Meggy Jr RGB
LED matrix game
development kit.


Business-card sized
AVR target boards


Peggy 2
LED Pegboard kits

My Account






Lost your password?