banner

Saturday, March 31, 2012

An attempt to show grayscale images on an LED dot matrix display with software PWM

Introduction:
      This is just a time pass hobby project, I am trying to display some pictures (JPEG/PNG/BMP etc) on my 8x8 led dotmatrix display.  You can see photos of my 8x8 led dotmatrix display showing some grayscale pictures. The main thing which you may notice is that the brightness of each led depends on the picture information respective to the scaled(8x8) pixel of the original picture.
The original pictures are drawn using GIMP image editor in linux and saved as png. The scaled pictue is sent from the PC to PIC via UART.
 Any way, this will be the worst monochrome display showing pictures:-)
 
Photos: 
 Here you could see the led display showing few pictures opened in gimp editor... You could compare the pictures and observe the PWM effect on the led matrix.














Working:
A pic16f877a is the heart of the 8x8 display. It is configured to drive the matrix. Brightness of each led is controlled by software PWM.. A 64 byte buffer(in pic) is used to store the brigntness information of 64 leds. Also another 64byte buffer is used to collect data(picture information) streamed out from PC via UART. Now, from PC side, every thing is done using a python script. Python image library (PIL) is used to convert any picture to 8x8  grayscale image. Now we get 64 bytes of data from a converted picture. Each byte value is divided by 4(since value 64 is the pwm max) and introduced to the PIC via UART using pyserial. When the 64 byte packet is completely received, it is introduced to the display... It show a single frame for about one second. Then next 64byte is sent from the PC and it is displayed and it continues...


Circut diagram:


C Program for PIC16F877A (hi tech c):
#include <htc.h>
#include <stdlib.h>
__CONFIG(0x3F3A);
#define _XTAL_FREQ 20e6   
#define reset RB7=1;RB7=0;   
#define clock RB6=1;RB6=0;

void interrupt_enable();
void uart_init();
void txd(unsigned char);

unsigned char uart_count, flag;
unsigned char image[64];
unsigned char image_b[];
void display()
{
    unsigned index = 0;
    unsigned char k;
    unsigned char h,i,j;
    for(h = 0; h < 64; h++) {
        index = 0;
        reset;
        for(i = 0; i < 8; i++) {
            k=1;
            for(j = 0; j < 8; j++) {
                if(image[index]) {
                     PORTD = ~(k);
                     image[index]--;                     
                }
                PORTD=255;
                index++;
                k<<=1;
            }
            PORTD=255;
            clock;
        }
    }
}

main()
{
TRISB6=0;TRISB7=0;RB7=0;TRISD=0;
PORTD = 255;
uart_init();
interrupt_enable();
unsigned char i,j;
unsigned char val = 0;
unsigned char extra = 0;
while(1)
{
    while(!flag);
    for(j=0;j<64;j++) {
        for(i=0;i<64;i++) {
            image[i] = image_b[i];
        }
        display();
    }
    flag=0;
}
}


void uart_init()
{
 TRISC6=0;
 TXSTA=0b00100100; 
 RCSTA=0b10010000; 
 BRGH=1;   //  high baud rate
 SPBRG=10;      //baud rate 115200
}

void interrupt_enable()
{
 GIE=1;
 PEIE=1;
 RCIE=1;
}

void interrupt UART()  //interrupt service routine
{
    image_b[uart_count] = RCREG;
    uart_count++;
    if(uart_count>=64) {
        uart_count=0;
        flag=1;
    }
    TXREG=RCREG;
}

Python code (PC side):
#!/usr/bin/python
import Image, os, time, sys, serial

ser = serial.Serial()
ser.baudrate=115200 
ser.port="/dev/ttyUSB0" 
ser.open()

while 1:
    files = os.listdir(".")
    for name in files:
        if((name[-3:] == "jpg") or (name[-3:] == "png") or (name[-4:] == "jpeg") or (name[-3:] == "JPG") or (name[-3:] == "PNG") or (name[-4:] == "JPEG")  or (name[-3:] == "PNG")):    
            try:        
                im = Image.open(name)
                nim = im.resize((8,8))
                nim = nim.convert("L")
                pix = nim.load()
                for i in range(8):
                    for j in range(8):
                        ser.write(chr((255-pix[i,j])/4))
                        print pix[i,j],
                    print '\n'
                time.sleep(1);
            except:
                ser.close()
                sys.exit(0)

2 comments:

gireesh kumar said...

nice work

MSM Websites said...

I think you have great knowledge regarding LED. I think you're right that the brightness of each led depends on the picture information respective to the scaled(8x8) pixel of the original picture. This Post is very helpful for me to increase my information. I appreciated your work. Keep sharing useful post like this.
China Wholesale Electronics

Post a Comment

SHARE IT on FB