{"id":55,"date":"2007-05-19T15:51:45","date_gmt":"2007-05-19T15:51:45","guid":{"rendered":"http:\/\/www.pyrofersprojects.com\/blog\/?p=55"},"modified":"2011-10-30T12:04:36","modified_gmt":"2011-10-30T12:04:36","slug":"xy-laser-pointer-controller","status":"publish","type":"post","link":"https:\/\/www.pyrofersprojects.com\/blog\/xy-laser-pointer-controller\/","title":{"rendered":"X\/Y Laser pointer controller"},"content":{"rendered":"<p><img decoding=\"async\" alt=\"PIC Output\" id=\"image58\" src=\"http:\/\/www.pyrofersprojects.com\/blog\/wp-content\/uploads\/2007\/05\/fullscope.thumbnail.jpg\" \/><br \/>\nA long time ago I decided to build a controller that would direct a laser pointer, The idea was to have 2 speakers connected to mirrors so they deflect in the x\/y range. This allows the laser to be aimed around at will.<\/p>\n<p>A simple Pic 16f84 was the controller with an analog devices Dual DAC. The dac has a lock on the output so both x and y get updated at the same time. The pic simply loads an 8bit data value for x, then y, then updates the DAC output.<\/p>\n<p><!--more--><\/p>\n<p>I originaly had some nice Mirror galvanometers from an old laserdisk player to aim the beam, these were a lot better than speakers, however they are not easily accessable for most people. The output of the DAC was centered at 2.5v with a 2.5v swing each way from the 5v supply. This gives a nice AC output from -2.5v to 2.5v relative to the output \u2018gnd\u2019 Great for connecting into cheap audio amps for driving the mirror speakers.<\/p>\n<p>The hard part is firmware on the pic. My original plan was to make writing, but this is quite a complex task. I managed to get a box, a circle, triangle etc but am still working on drawing complex shapes. A third Z axis was provided in the form of a digital out from the pic to turn the laser on\/off. This allows seperation of drawn objects.<\/p>\n<p>I have a couple of games planned, first is pong, the 3 shapes needed here are simple and should be easy to draw. Then asteroids. A lot more complex.<\/p>\n<p>The final game should be a small handheld box that projects a laser \u2018vector\u2019 game onto any surface. Obviously the power of the laser changes how visible the game is under different conditions.<\/p>\n<p><img decoding=\"async\" alt=\"Component Side\" id=\"image56\" src=\"http:\/\/www.pyrofersprojects.com\/blog\/wp-content\/uploads\/2007\/05\/top.thumbnail.jpg\" \/> <img decoding=\"async\" alt=\"Copper Side\" id=\"image57\" src=\"http:\/\/www.pyrofersprojects.com\/blog\/wp-content\/uploads\/2007\/05\/bottom.thumbnail.jpg\" \/> <img decoding=\"async\" alt=\"PIC Output\" id=\"image58\" src=\"http:\/\/www.pyrofersprojects.com\/blog\/wp-content\/uploads\/2007\/05\/fullscope.thumbnail.jpg\" \/> <img decoding=\"async\" alt=\"Square\" id=\"image59\" src=\"http:\/\/www.pyrofersprojects.com\/blog\/wp-content\/uploads\/2007\/05\/scope.thumbnail.jpg\" \/><br \/>\nThis was the first PCB I ever made, it was printed by laser printer onto tranparency, UV exposed onto pre-etch resist coated board and acid etched.<\/p>\n<p>Here is the initial CC5X code, its pretty basic though,<\/p>\n<p>#pragma chip PIC16C84<br \/>\n#pragma config WDTE=off, FOSC=XT, PWRTE=on<\/p>\n<p>\/\/ #pragma config &= 0x3FF9<\/p>\n<p>#include \u201cdelay.c\u201d<\/p>\n<p>\/*  IO-CONFIGURATION: *\/<br \/>\n#define  Konfig_portA  0x08  \/* xxxx 1000, 1=INPUT *\/<br \/>\n#define  Init_portA    0x00  \/* 0000 0000  bits 1,2 are dac control, 4 is laser and 8 is input*\/<\/p>\n<p>#define  Konfig_portB  0x00  \/* 0000 0000, 0=Output *\/<br \/>\n#define  Init_portB    0x00  \/* 0000 0000  All 8 bits output to send data to Dacs*\/<br \/>\n#define  UPDATE        0x00  \/* LDAC and DACAB are inverted *\/<br \/>\n#define  FREEZE        0x01  \/* So 0 in update makes the DAC update *\/<br \/>\n#define  DACX          0x00  \/* and 1 makes it freeze its current data *\/<br \/>\n#define  DACY          0x01  \/* Just some friendly names for the dacs *\/<\/p>\n<p>#pragma  bit  LDAC    @ PORTA.0<br \/>\n#pragma  bit  DACAB   @ PORTA.1<br \/>\n#pragma  bit  LASER   @ PORTA.2<br \/>\n#pragma  bit  INPIN   @ PORTA.3<\/p>\n<p>#pragma  bit  PIN1    @ PORTB.0<br \/>\n#pragma  bit  PIN2    @ PORTB.1<br \/>\n#pragma  bit  PIN3    @ PORTB.2<br \/>\n#pragma  bit  PIN4    @ PORTB.3<br \/>\n#pragma  bit  PIN5    @ PORTB.4<br \/>\n#pragma  bit  PIN6    @ PORTB.5<br \/>\n#pragma  bit  PIN7    @ PORTB.6<br \/>\n#pragma  bit  PIN8    @ PORTB.7<\/p>\n<p>void main ( void)<br \/>\n{<br \/>\nunsigned x,y,t;<br \/>\n\/* initialize *\/<br \/>\nPORTA = Init_portA;<br \/>\nTRISA = Konfig_portA;<br \/>\nPORTB = Init_portB;<br \/>\nTRISB = Konfig_portB;<\/p>\n<p>x=0;<br \/>\ny=0;<\/p>\n<p>DACAB = DACX;<br \/>\nLDAC  = FREEZE;<\/p>\n<p>while (1)<br \/>\n{<br \/>\nDACAB = DACX; \/* The dac seems to work a lot faster than the PIC so no delay is needed *\/<br \/>\nPORTB = x;    \/* but that is based on ititial slow work observations *\/<br \/>\nDACAB = DACY; \/* Although Both dacs appear to change independantly ok with this *\/<br \/>\nPORTB = y;    \/* even though there is no delay *\/<br \/>\nLDAC  = UPDATE; \/* The rest of the program provides a delay while dacs settle! *\/<br \/>\nLDAC  = FREEZE; \/* The dacs update now, while the prog does its work *\/<\/p>\n<p>if (x==255) y\u2013; \/* If at right, go down *\/<br \/>\nif (y==255) x++; \/* if at bottom go left *\/<br \/>\nif (x==0) y++;   \/* If at left, go up *\/<br \/>\nif (y==0) x\u2013;   \/* if at top, go right *\/<br \/>\n\/* delay(2); *\/<br \/>\n}<br \/>\n}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A long time ago I decided to build a controller that would direct a laser pointer, The idea was to have 2 speakers connected to mirrors so they deflect in the x\/y range. This allows the laser to be aimed around at will. A simple Pic 16f84 was the controller with an analog devices Dual [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-55","post","type-post","status-publish","format-standard","hentry","category-general"],"_links":{"self":[{"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/posts\/55","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/comments?post=55"}],"version-history":[{"count":1,"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/posts\/55\/revisions"}],"predecessor-version":[{"id":361,"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/posts\/55\/revisions\/361"}],"wp:attachment":[{"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/media?parent=55"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/categories?post=55"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pyrofersprojects.com\/blog\/wp-json\/wp\/v2\/tags?post=55"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}