banner

Sunday, December 4, 2011

Python maps mouse movements to an led matrix display controlled by a PIC


Introduction:

This is a small "toy paint" on an LED dot matrix display which is controlled by a mouse connected to a PC... We have seen the MS PAINT in windows. This is a small 'TOY PAINT' for my small 8x10 LED dot matrix display :-) Here, using a PC mouse, I could draw and erase picture on a small 80 pixel display made by LEDs. At first I thought of making a mouse controlled robotic arm but due to lack of few mechanical parts, I just postponed that and now made this toy paint as a part of familiarizing  two python modules named pygame and pyserial. The heart of the display is a PIC16F877A micro controller. Now, from the PC side, every thing is done on python. Now, if I am using an RF module in between the PIC and USB to UART converter, I can do the same process remotely... The same idea could be applied in robotics for smooth control of activities remotely using a computer mouse...



Working:

PC side:(linux)
I have used python for capturing the mouse coordinates. A module named pygame is used for the purpose. We could get the mouse coordinates on a pygame window of a predefined size (here I used 320 x 400) using appropriate function calls...Now what I need to do next is, I need to send the scaled version of captured coordinates and the 3 mouse button status to PIC16F877A using serial port. Here I am using a usb to serial adapter for the purpose. For sending the mouse coordinate and the 3 button state, I used another python module named pyserial. Now, when ever any mouse event occur (mouse event means mouse clicks or mouse movement), the data is send to the PIC16F877A via the serial port (/dev/ttyUSB0). 

Display:
The 10x8 LED dot matrix display is controlled by a PIC16F877A micro controller. The received data (6 bytes) is collected in a buffer until a 0x0d is received which confirms the end of data... Now, the first two bytes consist of the coordinate data (for 10x8 pixel) and the remaining 3 bytes consist of the mouse button status.. Now another 10byte buffer is used to store the display data which is modified according to the coordinates received and the state of the mouse buttons... When the mouse is freely moved in such a  way that the mouse cursor lies inside the pygame window, then the corresponding coordinate on the LED display is illuminated. (the working of multiplexed led dot matrix display is already explained with examples in one of my earlier post). We can see the the mouse cursor movement in the LED display. Now while pressing the left mouse button the pixel which is illuminated at that instant is illuminated for ever until we erase of clear the display. By this way a picture is drawn on the display. Now, the centre mouse button is used to clear the display all at time and the right mouse button is used to clear the individual pixel in which the mouse pointer is pointed... 

python code for capturing mouse events and sending in to PIC:
import serial,time,sys,os
os.system("clear")
ser = serial.Serial("/dev/ttyUSB0",115200)
ser.timeout = 0.3
try:
    ser.open()
except Exception,e:
    print "error open serial port: " + str(e)
    exit()
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((320,400))
pygame.display.update()    
pygame.display.set_caption("10x8 LED DOTMATRIX DISPLAY")
button = (0,0,0)
if ser.isOpen():
    try:
        ser.flushInput()
        ser.flushOutput()
        x = 0
        y = 0
        while 1:
            for i in pygame.event.get():
                if i.type == QUIT:
                    ser.close()
                    exit()
                elif i.type == MOUSEMOTION:
                    x,y = pygame.mouse.get_pos()
                    pygame.display.update()
                elif i.type == MOUSEBUTTONDOWN:
                    button = pygame.mouse.get_pressed()
                elif i.type == MOUSEBUTTONUP:
                    button = pygame.mouse.get_pressed()
                ser.write(str(x/40))
                ser.write(str(y/40))
                ser.write(str(button[0]))
                ser.write(str(button[1]))
                ser.write(str(button[2]))
                ser.write("\x0d")
    except Exception, e1:
        print "COMMUNITATION ERROR :-(: " + str(e1)
else:
    print "SORRY, ERROR IN OPENING SERIAL PORT "


PIC16F877A code:
/*---------------------------------------------*/
/* mouse controlled led dotmatrix display      */
/* compiler: Hi tech C compiler with MPLAB IDE */
/* date: 4/12/2011                             */
/* by vinodstanur@gmail.com                    */
/*---------------------------------------------*/
#include<pic.h>
#define _XTAL_FREQ 20e6
__CONFIG(0x3F3A);
char i,s;
bit ok;
char buf[10];
char disp[10];
char xcord, ycord;
void clear_disp()
{
 for(i = 0; i < 10; i++)
  disp[i] = 0;
}  
void usrt_init()
{
 TRISC6=0;
 TXSTA=0b00100100; 
 RCSTA=0b10010000; 
 BRGH=1;   
 SPBRG=10;      //baud rate 115200
}
void clock(){ RB6=1;RB6=0;}
void reset(){ RB7=1;RB7=0;}
void display(void)
{
 int j=0;
 reset();
 PORTD = 255;
 for(i = 0; i < 10; i++) {
  if(i == ycord)
   for(j = 0; j < 9; j++)
    PORTD = ~((disp[i]|xcord) & (1 << j));
  else
   for(j = 0; j < 9; j++)
    PORTD = ~((disp[i]) & (1 << j));
  __delay_us(50);
  PORTD = 255; 
  clock();
 } 
}

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

void interrupt UART()  //interrupt service routine
{ 
  
 buf[s] = RCREG;
 if(buf[s] == 0xd) {
  s = 0;
  ok = 1;
  return;
 } 
 s++; 
}

void txd(char write_data)
{
 TXREG = write_data;
 while(!TRMT);
} 
void main()
{
 TRISD=0;
 TRISB6=0;
 TRISB7=0;
 usrt_init();
 interrupt_enable();
 while(1){
  if(ok){
   if(buf[2] == '1')
     disp[buf[1] - '0'] |= (0b10000000 >> (buf[0] - '0'));
   else if(buf[4] == '1') 
    disp[(ycord = (buf[1] - '0'))] &= ~(xcord = (0b10000000 >> (buf[0] - '0'))); 
   else if(buf[3] == '1')
    clear_disp();
   else {
    ycord = (buf[1] - '0');
    xcord = (0b10000000 >> (buf[0] - '0'));
   } 
   ok = 0;   
  }
  display(); 
 }
}  

circuit diagram


5 comments:

gireesh kumar said...

excellent work

Devanand T said...

very good work, we have previously met at edaboard

Devanand T said...
This comment has been removed by the author.
dharmendra said...

excellent

Liza Jenifer said...

Well! You have useful collection regarding electronics. I can learn more about Electronic from this blog, i really need it. You have done superb job. I'm searching a website where i can purchase LED Lights for my home while searching i found this blog.

Post a Comment

SHARE IT on FB