TinyProjector Lab Notebook

top | summary | prototypes | original proposal | diary

previous section 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | next section



Diary of October 2001 8-16

 

October 8, 2001

I tried to set up a serial connection to the Palm Pilot. It didn't work, even after inserting resistors into RS232 pins on PIC.

 

 

 

C code for TinyProjector prototype2

 

Since the serial connection did not work at this time, I made the projector go through a sequence of a few different projections (Figure 27).

 

#include <16F84.h>

#fuses HS,NOWDT,NOPROTECT,PUT

#use Delay(Clock=10000000)

#use fast_io(A)

#use fast_io(B)

#use RS232(Baud=38400,Xmit=PIN_A1,Rcv=PIN_A0,parity=n,bits=8)

#byte PORTA = 5

#byte PORTB = 6

#define SERVO PIN_A2

 

int v;

char char1 = 's';

 

void delay_10us(int i) {

   do {delay_us(10);

      } while(--i);

}

 

// character projection routines

void project_A(int forward) {

      for (v=0; v<5; v++) {     

         if ((v==0)||(v==4))         { PORTB = 0b00000001; }

         if ((v==1)||(v==2)||(v==3)) { PORTB = 0b11101110; }

         delay_us(1100);

         PORTB = 0xFF;

         delay_us(1000);

      }

}

 

void project_C(int forward) {

   if (forward==1) {

      for (v=0; v<5; v++) {     

         if  (v==0)                  { PORTB = 0b10000001; }

         if ((v==1)||(v==2)||(v==3)) { PORTB = 0b01111110; }

         if  (v==4)                  { PORTB = 0b10111101; }

         delay_us(1300);

         PORTB = 0xFF;

         delay_us(1000);

      }

   }else{

      for (v=0; v<5; v++) {     

         if  (v==0)                  { PORTB = 0b10111101; }

         if ((v==1)||(v==2)||(v==3)) { PORTB = 0b01111110; }

         if  (v==4)                  { PORTB = 0b10000001; }

         delay_us(1300);

         PORTB = 0xFF;

         delay_us(1000);

      }

   }

}

 

void project_O(int forward) {

      for (v=0; v<5; v++) {     

         if ((v==0)||(v==4))         { PORTB = 0b10000001; }

         if ((v==1)||(v==2)||(v==3)) { PORTB = 0b01111110; }

         delay_us(1100);

         PORTB = 0xFF;

         delay_us(1000);

      }

}

 

void project_L(int forward) {

   if (forward==1) {

      for (v=0; v<5; v++) {     

         if  (v==0)                          { PORTB = 0b00000000; }

         if ((v==1)||(v==2)||(v==3)||(v==4)) { PORTB = 0b01111111; }

         delay_us(1300);

         PORTB = 0xFF;

         delay_us(1000);

      }

   }else{

      for (v=0; v<5; v++) {     

         if ((v==0)||(v==1)||(v==2)||(v==3)) { PORTB = 0b01111111; }

         if  (v==4)                          { PORTB = 0b00000000; }

         delay_us(1300);

         PORTB = 0xFF;

         delay_us(1000);

      }

   }

}

 

void project_N_hires(int forward) {

   if (forward==1) {

      for (v=0; v<10; v++) {     

         if  ((v==0)||(v==1))                { PORTB = 0b01111110; }

         if  ((v==2)||(v==8))                { PORTB = 0b00000000; }

         if  (v==3)                          { PORTB = 0b01111001; }

         if  (v==4)                          { PORTB = 0b01110011; }

         if  (v==5)                          { PORTB = 0b11100111; }

         if  (v==6)                          { PORTB = 0b11001110; }

         if  (v==7)                          { PORTB = 0b10011110; }

         if  (v==9)                          { PORTB = 0b11111110; }

         delay_us(700);

         PORTB = 0xFF;

         delay_us(1000);

      }

   }else{

      for (v=0; v<10; v++) {     

         if  ((v==9)||(v==8))                { PORTB = 0b01111110; }

         if  ((v==7)||(v==1))                { PORTB = 0b00000000; }

         if  (v==6)                          { PORTB = 0b01111001; }

         if  (v==5)                          { PORTB = 0b01110011; }

         if  (v==4)                          { PORTB = 0b11100111; }

         if  (v==3)                          { PORTB = 0b11001110; }

         if  (v==2)                          { PORTB = 0b10011110; }

         if  (v==0)                          { PORTB = 0b11111110; }

         delay_us(700);

         PORTB = 0xFF;

         delay_us(1000);

      }

   }

}

 

void project_EXCLAMATION(int forward) {

      for (v=0; v<5; v++) {      

         if ((v==0)||(v==1)||(v==3)||(v==4)) { PORTB = 0b11111111; }

         if  (v==2)                          { PORTB = 0b01100000; }

         delay_us(1100);

         PORTB = 0xFF;

         delay_us(1000);

      }

}

 

void project_SPACE(int forward) {

      for (v=0; v<5; v++) {     

         PORTB = 0b11111111;

         delay_us(1100);

         PORTB = 0xFF;

         delay_us(1000);

      }

}

 

main() {

int k, m, u, s;

set_tris_a(0b00000001);

set_tris_b(0b00000000);

 

   while(1) {  

        for (u=0; u<10; u++) { // write "cool" six times

            for (k=0; k<15; k++) {

                OUTPUT_HIGH(SERVO);

                  delay_us(1900);

                OUTPUT_LOW(SERVO);

                  delay_ms(3);

                if (k==0)   { project_C(1); }

                if (k==1)   { project_O(1); }

                if (k==2)   { project_O(1); }

                if (k==3)   { project_L(1); }

                if (k==4)   { project_EXCLAMATION(1); }

                if (k==5)   { project_SPACE(1); }

                if (k==6)   { project_C(1); }

                if (k==7)   { project_O(1); }

                if (k==8)   { project_O(1); }

                if (k==9)   { project_L(1); }

                if (k==10)  { project_EXCLAMATION(1); }

                if (k==11)  { project_SPACE(1); }

                if (k==12)  { project_C(1); }

                if (k==13)  { project_O(1); }

                if (k==14)  { project_O(1); }

 

                  delay_us(1300);

            }

 

          for (m=0; m<15; m++) {

                OUTPUT_HIGH(SERVO);

                   delay_us(1000);

                OUTPUT_LOW(SERVO);

                   delay_ms(2);

                if (m==0)  { project_O(0); }

                if (m==1)  { project_O(0); }

                if (m==2)  { project_C(0); }

                if (m==3)  { project_SPACE(0); }

                if (m==4)  { project_EXCLAMATION(0); }

                if (m==5)  { project_L(0); }

                if (m==6)  { project_O(0); }

                if (m==7) { project_O(0); }

                if (m==8) { project_C(0); }

                if (m==9) { project_SPACE(0); }

                if (m==10) { project_EXCLAMATION(0); }

                if (m==11) { project_L(0); }

                if (m==12) { project_O(0); }

                if (m==13) { project_O(0); }

                if (m==14) { project_C(0); }

 

                delay_us(1300);

           }

        } // end of cool

 

        delay_ms(500);

        for (u=0; u<10; u++) { // write "A" six times

 

           for (k=0; k<15; k++) {

              OUTPUT_HIGH(SERVO);

                    delay_us(1900);

              OUTPUT_LOW(SERVO);

                    delay_ms(3);

              project_A(1);

              delay_us(1300);

           }

 

           for (m=0; m<15; m++) {

              OUTPUT_HIGH(SERVO);

                    delay_us(1000);

              OUTPUT_LOW(SERVO);

                    delay_ms(2);

              project_A(0);

              delay_us(1300);

           }

 

        } // end of AAA

 

        delay_ms(1000);

        for (u=0; u<10; u++) { // write "N" hires

           for (k=0; k<15; k++) {

              OUTPUT_HIGH(SERVO);

                    delay_us(1900);

              OUTPUT_LOW(SERVO);

                    delay_ms(3);

              project_N_hires(1);

              delay_us(1300);

           }

 

           for (m=0; m<15; m++) {

              OUTPUT_HIGH(SERVO);

                    delay_us(1000);

              OUTPUT_LOW(SERVO);

                    delay_ms(2);

              project_N_hires(0);

              delay_us(1300);

           }

 

        } // end of NNN hires

        delay_ms(1000);

 

   } // end of main while loop

} // end of main

Figure 27: C code for TinyProjector prototype 2

 

After a lot of tweaking, the projection of the second prototype seems acceptable to me. The refresh rate is about 3Hz, which means it relies on Persistence of Vision principles. [This will not be the case anymore in the next prototype.]

 

 

Figure 28: Two projections: a row of "A" characters (left), and a row of high resolution "N" (right)

 

After the demo started to work properly, I still had to design a poster (which first required installing software on a laptop, like Thumbs and Photoshop).

 

First I made some hand drawings (Figure 29), and digitized them.

 

Figure 29: Drawings for poster

 

 

Then I took tons of pictures of the prototype (Figure 30).


 

Figure 30: Working TinyProjector prototype 2

After designing the poster (Figure 31), I had to fix the plotters (I actually did both Hammersmith and Lenz), printed it out, cut it manually, and spray-glued it onto cardboard.

 

 

 

Figure 31: Final poster for Fall 2001 sponsor meeting

 

[Note: I did not sleep this night either, only October 9 afternoon from 2pm till 7pm.]

 

 

Figure 32: Me in my office, one of my work areas

 

 

October 9, 2001

Demoed TinyProjector prototype 2 9:30 – 12:30 during I/O Open House at the MIT Media Lab.

 

Figure 33: Me demoing during the I:O sponsor open house

 

October 11, 2001

I demoed TinyProjector prototype 2 from 15:00 – 18:00, during Digital Life open house.

 

I replaced 7 laser diodes after I accidentally connected 4.8V (power supply!) instead of 4.5V: four of them were down to 20% brightness; three more broke later. (The original idea I had was to start the laser projector demo with a Clapper! But in order to use the Clapper, I had to use a power supply instead of the 3 alkaline cells. Unfortunately, the power supply had 4.8V instead of 4.5V…)

 

During these extensive repairs, I had an idea: In order to speed up the repair time, why don’t I just screw the laser diodes into the acrylic? And don't solder the contacts, but just clip the cables on. (I never implemented this idea.)

 

Credits: These people helped me with the second prototype of TinyProjector:

 

o       Deva Seetharam (deva@media.mit.edu): for the idea that we had during the Tangible interfaces class in October 2000

o       Natalia Marmasse (nmarmas@media.mit.edu): C problems, circuit problems

o       Vadim Gerasimov (vadim@media.mit.edu): original circuit design

o       Rob Poor (r@media.mit.edu), Matt Reynolds (matt@media.mit.edu), and hackers on hackers mailing list: electronics details

o       Bakthiar Mikhak (mikhak@media.mit.edu): PIC programmer

o       Borglab: cables

o       Hannes Vilhjalmsson (hannes@media.mit.edu) and GNL (wires, foam)

 

 

Feedback from interactions during open house:

 

o       The Private Eye (like Bradley Rhodes has been wearing) is based on the same principle: a row of red LEDs and a vibrating mirror:
http://www.ndirect.co.uk/~vr-systems/priveye1.htm

 

o       Matt Reynolds (matt@media.mit.edu) suggests using smaller mirrors that are balanced, and probably require a far smaller servo. [I will follow this suggestion during design of the next prototype.]

 

 

October 16, 2001

I met with Sloan Kulper (sloan@media.mit.edu) from John Maeda's group. I showed him my demo, and he told me what he is working on, which is very related (http://acg.media.mit.edu/people/sloan/June.html/index.html).

 

We were talking about the novelty of our work, and started to look into the US Patents database. Indeed, we found a long list of very related work:

 

http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=%2Fnetahtml%2Fsearch-bool.html&r=0&f=S&l=50&TERM1=4470044&FIELD1=&co1=AND&TERM2=&FIELD2=&d=pall

 

Most of these patents are based on persistence of vision projection with LEDs, (like for the Skyliner™ and the Private Eye. For example, patent number 4470044 (Figure 34):

 

Momentary visual image apparatus

A modulated array of lights for the creation of momentarily perceptible visual images when scanned asynchronously by the human eye during characteristic saccadic eye movements between points of eye fixation is described in the disclosure. The array and modulation style are chosen to provide an image that matches the span of the human eye/brain combination for recognition of tachistroscopically presented lines of text, other symbols, and pictorial images, and to achieve an illusory effect wherein the momentary image appears dissociated from the array of lights and appears superimposed on the scene of eye fixation just prior to initiating the saccadic movement. A preferred embodiment using light emitting diodes and large-scale integrated logic circuitry is described for generation of words, phrases up to 32 characters long, and simple pictures.”

(Patent filed May 15, 1981, awarded September 4, 1984.)

 

http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=/netahtml/search-bool.html&r=24&f=G&l=50&co1=AND&d=pall&s1=4470044&OS=4470044&RS=4470044

 

Figure 34: Patent 4470044

 

The illustrations speak for themselves. Most of the other patents are very similar.

 

However, the patent number 6222459 is different because is explicitly mentions laser diodes, and is therefore very close to my work (Figure 35):

 

Method of word screen formation by laser light projection and the structure for the same

The present invention relates to a method of word screen formation by laser light projection and the structure of word formation by laser light projection, and in particular, relates to a plurality of laser production devices arranged in a single column and by rapid reciprocating action of the devices to project multiple columns of light track and form word arrays.”

(Patent filed July 22, 1999, awarded April 24, 2001)

 

http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=/netahtml/search-bool.html&r=5&f=G&l=50&co1=AND&d=pall&s1=4470044&OS=4470044&RS=4470044

 

Figure 35: Patent 6222459

 

Up to that point, there is still the rotating mirror concept missing, but the very last illustration/claim describes exactly this variation of the above projector (Figure 36):

 

Figure 36: Patent 6222459, third last paragraph: “In another preferred embodiment of the present invention (…) the lateral edge of the board body 50 and the inner wall of the two lateral edges of the housing 72 are in engagement with each other, and adjacent to the board body 50, is a plurality of laser production devices 30, 31, 32 are mounted. At the laser port, the reciprocating mechanism 60 driven by the power source 40 is provided. The power source 40 is an electrical source 41 connected in series to a switch 44, and the reciprocating mechanism 60 is a reciprocating swinging type electric motor 63 connected to a speed-adjusting element 43. The center of the output shaft of the speed-adjusting element 43 is provided in vertical with a reflection mirror 64. The electric motor 63 is electrically connected to the power source 40 and the reflection surface of the reflection mirror 64 faces the laser port of the laser production devices 30, 31, 32, such that the laser light emitted from the laser port is directed to the reflective mirror 64 while the mirror 64 is swinging, and the light is reflected through the housing window 71 to the column position, where the projection face corresponding to the lighted word screen, and forms lighted word tracks.”

 

Claim 5 pretty much describes the full rotational two-faced mirror version of my idea.

 

However, as I will describe later in this lab notebook, a system with such a mirror design is very inefficient and can work only with very high power laser diodes since with such a mirror configuration, the duty cycle of the lasers is far from optimal.

 

I wonder if the inventor of this patent, Mr. Chih-Yu Ting from the Taiwanese company OPCOM Inc. (http://www.opcomgroup.com/main.htm), a laser and CCD products producer, has actually built the projector described in claim 5. I doubt it very much.

 

Note that this patent was awarded after I started working on this project.



previous section | October 2001 8-16 | next section

section 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12


Send me some comments! Stefan Marti Last updated February 23, 2003.

Copyright © 1997-2004 by Stefan Marti and MIT Media Lab. All rights reserved