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 May 2002 7-15


May 7, 2002

I couldn't solve the alignment problem: the diodes are too tight, and if they would not be tight, every pull on the signal wires would de-align them. Solutions: Wrapping a cord (0.025 elastic wire) twice around the front part of the diode. Disadvantage: too difficult to align. Pull of wires would misalign the assembly.


Finally, I designed a solution that uses just two parallel, isolated, soft wires that are soldered to the laser's pins, and glued each with two holes to the 3D printed holder, with a U shaped ending (Figure 104).


Therefore, one inner side of the holder had to be made thinner, so that the wires (the U part) do not get in the way of the laser path. The connections (GND and signal) would be soldered on the other side of the U, which deflects all forces away from the wires that hold the diodes.




Figure 104: 3D design of alignment solution: double U holder for laser diodes, making them very easy to align by just bending the two isolated wires (green and red) slightly







During the day, I could not print another diode holder because there was a 16-hour job on the 3D printer that started at 5pm. So I decided to experiment with an earlier version of the holder, cutting away the back of the holder.



May 8, 2002

I finally 3D printed several versions of the diode holder (Figure 105).


Figure 105: Holder with open back


I assembled one, by drilling 32 holes manually (four for each laser: a pair for ground, and a pair for current), and inserting isolated wire from jumper wire kit, which was a pain. Epoxy glued the wires in. Connected all the GND pins with one stiff piece of wire. Aligned the laser diodes (was possible, but still took some time): the alignment is on an acceptable level now.


Figure 106: Test of laser diode holder (left), completed holder (right)


Figure 107: Laser diode holders consisting of a double U shaped isolated wire




In the following, a few pictures of the completed TinyProjector prototype 9.



Figure 108: Final prototype 9 of TinyProjector


Then I wrote all software for receiving serial code, and writing single characters (A-Z, !)  (Figure 109)


#include <16F877.h>


// File name: tiny2p2.c


// Configure PIC to use: HS clock, no Watchdog Timer,

// no code protection, enable Power Up Timer




// Tell compiler clock is 4MHz.  This is required for delay_ms()

// and for all serial I/O.  These functions use software delay

// loops, so the compiler needs to know the processor speed.


#use Delay(Clock=4000000)


// Declare that we'll manually establish the data direction of

// each I/O pin on ports A, B, and C.


#use fast_io(A)

#use fast_io(B)

#use fast_io(C)

#use fast_io(D)


#use RS232(Baud=9600,xmit=PIN_A0,Rcv=PIN_A3,INVERT)


// Set variable that maps to memory

#byte PORTA = 5

#byte PORTB = 6

#byte PORTC = 7

#byte PORTD = 8



byte _SPACE[5] = {





  0b11111111 };


byte _EXCL[5] = {





  0b11111111 };


byte _A[5] = {





  0b00000001 };


byte _B[5] = {





  0b10001001 };


byte _C[5] = {





  0b10111101 };


// ETC, ETC, all characters of the alphabet


char char1;


int i;

int z;

int x;



void project3(byte the_character[5], int the_line) {


    PORTB = the_character[the_line];

    delay_us(80);  //worked: 80

    PORTB = 0xFF;

    delay_us(60);  //worked: 60




void project2(char c, int line_number) {



      case 'A': project3(_A,line_number);


      case 'B': project3(_B,line_number);


      case 'C': project3(_C,line_number);



// ETC, ETC, again, switches to all characters of the alphabet


      default:  project3(_SPACE,line_number);




void project1(char the_char) {


   int v;

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

       project2(the_char, v);






main() {


  // Since we've declared #use fast_io(A)(B)(C) (above), we MUST

  // include a call to set_tris_a/b/c() at startup.


  set_tris_a(0b00001000);  // A3 is input (serial)

  set_tris_b(0b00000000);  // all Bs are outputs

  set_tris_c(0b00000001);  // C0 is input (photodiode)

  set_tris_d(0b00000000);  // all Ds are outputs



  while(1) {


    char1 = getc();

    putc(char1);           // echo char1


    PORTB = 0x00;


    PORTB = 0xFF;




    while (z<40) {


      if (input(PIN_C0)) {     // most of the time, diode is not covered:

         PORTB = 0xFF;         // turn lasers off

      }else{                   // at the point where the diode is covered:


         for (x=0; x<8; x++) {




      } // end of diode is covered


    } // end of small while


  } //end of big while loop


} // end of main

Figure 109: Excerpts of the PIC code that displays all characters, and receives input from the serial port (tinyp2.c)


Later, I added some preset text lines that are triggered by sending single digits from 2-9 over the serial port to the PIC.


Then I connected the TinyProjector prototype 9 to Natalia's Palm 5, and it worked well with Pterminal and Graffiti (Figure 110).


Figure 110: TinyProjector prototype 9 connected to a Palm Pilot via serial cable


However, there was still a problem: the sensor seems to fluctuate, generating horizontal jitter in the projection. Either it is mechanical imperfections of the servo arm (tried to make it better, but was not successful), or to much stray light (built a cardboard casing around the IR and diode, but did not seem to make a difference.)


Stayed up all night to make it work! Here are the problems that came up:


  • Multiple triggering of the sensor makes projection jittery (on the horizontal axis): I have to check the signal with an oscilloscope, and make it less sensitive. Perhaps with a filtering mechanism?
  • I still have to figure out how to read characters from the serial port without waiting for getc. Perhaps with kbhit? http://www.ccsinfo.com/faq/?25
  • The calibration is still sub optimal: where the mirror starts (the amount of delay after the sensor reports a shadow), and how wide it is (how many pixels of a given size there are)
  • Make the projection less high by arranging the laser beams vertically closer to each other. Like that, the distance to the wall can be increased, and—as a consequence—the horizontal resolution: this allows for displaying more characters.
  • Build a protective casing around current prototype 9
  • Design and build a dedicated circuit board that contains all electronic components, possibly using surface mount PIC and transistors.



May 14, 2002

I connected the photodiode to the oscilloscope: it indeed showed a double triggering. The peaks are about 10ms apart. Furthermore, Gerardo says that the levels are very low: 1V is the max (which is strange, because I think I measured it earlier, and it gave 4.5V)

Figure 111: Part of the signal of the photo diode during operation of TinyProjector


May 15, 2002

With Gerardo's help, I measured the output of the photodiode (again). On a voltmeter, it is between 1V and 4.3V. Then, we measured on an oscilloscope, and it looked similar. (The measurements yesterday were not correct; there must have been some problems with the settings.) The signal is generally high at 4.3V, and drops to approx. 1V when the servo arm passes. Actually, it has two lows, separated with a high spike. First we thought that this is causing the jittering: sometimes the PIC detects the first low, sometimes the second. However, that is not the case, because when the PIC detects the first low, it waits 15ms, and then starts with the blinking sequence that in itself lasts 9.6ms. Therefore, the PIC detects a low, and then ignores the photodiode signal for 25ms, and only then looks for a low again. At that point, the signal is high again for sure.



In order to solve the jittering problem, we inserted a Schmitt trigger (with buffer) to straighten out the signal (see screenshots, Figure 112). Although the signal looks very clean now (no slopes anymore), both the signal in the oscillator and the projection still jitter. These two might actually not be because of the same reason.


Figure 112: Signal of photodiode directly (top, blue line), and with the Schmitt trigger (bottom, yellow line)


The oscillator says that the signal frequency that comes from the photodiode is between 120 and 145Hz. However, it doesn't really matter that this frequency is not constant, if the motor (rotation speed) is the reason for the jittering of the oscillator signal. Such a variation would just translate in a variable refresh rate, which is not relevant.


If the motor is the reason for the jitter in the oscilloscope signal, then it is the connection between motor and mirror that is reason for the jitter in the projection. Whenever the photodiode triggers the laser sequence, the mirror has to be at the same place. That does not seem to be the case: it's probably the connection (hole) between the servo arm and the pushrod that wears out more and more. One solution would be to glue in a ball bearing instead of a plain hole, another one could be to use thicker material or harder material, like aluminum as a servo arm.



Natalia gave me an iDen phone with a little Java application that sends characters to the serial port (Figure 113).



Figure 113: TinyProjector prototype 9 connected to a iDen cellphone via serial cable

previous section | May 2002 7-15 | 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