Project tutorial
Magic Projector (A Romantic One)

Magic Projector (A Romantic One) © GPL3+

Simple but meaningful project to ask a girl to be your girlfriend using an LED matrix & Arduino. (We aren't responsible for broken hearts.)

  • 1,648 views
  • 2 comments
  • 7 respects

Components and supplies

A000066 iso both
Arduino UNO & Genuino UNO
×1
Tens70
9V battery (generic)
×1
61vhxtmzbyl
AA Batteries
×1
Led matrix 8x8 common cathode
I did use the GMM-23088CSB, but every generic matrix should work, just need to ensure what's the pinout diagram.
×1
12002 04
Breadboard (generic)
×1
08377 02 l
Resistor 330 ohm
×8
Keystone 233 image 75px
9V Battery Clip
×1
Fairchild semiconductor pn2222abu. image
General Purpose Transistor NPN
×1
Switch
×1
Hand lamp
You can use any source of light that produces a directed beam of light. I did use a led hand lamp: NF-A651.
×1
Resistor 2.7K ohm
×1
11026 02
Jumper wires (generic)
Any wire should work
×1
Cardboard box
Recycled carton 🌎
×1
Glue
×1
Matt black paper
×1

Necessary tools and machines

09507 01
Soldering iron (generic)
Hy gluegun
Hot glue gun (generic)
Cutting pliers

Apps and online services

About this project

Most of the time, engineers seem to be non-creative people. But that's not true! We are much more creative than people think. Recently I had to find an original way to ask a girl to be my girlfriend, so after a little brainstorm, I decided to use some components that I've found in my desk to make the date very special for her.

Step One: Matrix Control

Display things on the matrix can be done by two ways: using a led driver MAX7219, which reduce the amount of pins used by the Arduino and reduce the number of resistors in the circuit. Or connecting pin by pin on the matrix to the Arduino, this makes the circuit too big and uncomfortable to work with, and you end with 2 pins left to use on any other thing.

My first try was to use the MAX7219, but due to noisy signals I give up and switch to the hard method. This problem can be solved using short connections as the datasheet said on page 10.

But I didn't have time to make a custom PCB for it.

MAX7219 noisy signal effect

So, for the next try, I wire every pin on the matrix to each one of the pins on the Arduino.

Remember to use current limiting resistors on each cathode, I decided to use 330 Ohm.

Code for the Matrix

The program can be found on my GitHub repo. It's well commented, so I won't get deep on it. But if you do the wiring as I did, everything should work.

To generate every image on the matrix, I found a useful resource on the internet, just need to set the dots to on or off, copy the resulting code and delete the first two comma separated values of the array.

Upload the code and turn it on!

Led matrix working using the pin to pin connection

Step two: Controlling the light

This was a tricky part because the lamp I did use was borrowed from a friend and he asked me not to do anything irreversible to his lamp. So for the connections, instead of do some soldering, I had to find a way to attach the cables to the battery and the lamp using just cardboard and tape.

At the beginning, I want to use a light bulb, so that's the reason why I have a relay on the circuit. But when I do the first try with it, I realized that the light bulb don't work for this task because the light beam it's not focused. So I replace it with the LED lamp, but I have not time to make the circuit again, so the relay stay in place. It should work only using the transistor.

I have two batteries on my circuit because I don't have wires of the long needed to connect the light control circuit and the matrix control circuit, but it should work using only one 9V battery to power all the circuit.

Step Three: Box Enclosure

The magic box has two compartments. The first is where the Arduino and the matrix are attached. The second have the light and his control circuit in it. In order for the projection to work, you have to be careful when get the hardware inside the box, anything should be in front of the light. I've tried to attach the wires very well to avoid any problem.

The box should look like this, but feel free to make your own design.

For the control panel I get some translucent black fabric and cover the matrix with it. When it's turn off, the led behind are barely visible, so it gives a nice effect to the box.

I cover all the cardboard with matte black paper to make it looking good, and finally print text that was made in Canva on acetate paper and put it on one side of the box. Image below:

Results

I programmed some nice sprites on the matrix and after some seconds, it turns on the light inside revealing the message.

Try it before use

Add some flowers, a romantic place, good food, ask her to turn on the device and be prepared for success. In my case, she said yes.

Code

Arduino codeArduino
 /******************/
//  Arturo Enrique Rosete Cruz
//  arturorosete0@gmail.com
//  Control an 8x8 led matrix(GMM-23088CSB) with an Arduino UNO
//  Pin connections:
//  Remember use a resistor on each anode.
//  Columns
//  matrix  | 13 |  3 |  4 | 10 |  6 | 11 | 15 | 16 | 
//  Arduino |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |
//
//  Raws
//  matrix  |  9 | 14 |  8 | 12 |  1 |  7 |  2 |  5 | 
//  Arduino | 10 | 11 | 12 | 13 | A0 | A1 | A2 | A3 |
//  More info: https://www.prometec.net/matriz-led-8x8/
//  Useful resource for create symbols: http://embed.plnkr.co/3VUsekP3jC5xwSIQDVHx/preview
//  5/April/2018
/******************/


byte sp[]= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte c_1[] = {B00000000,B01111110,B01000010,B01000010,B01000010,B01000010,B01111110,B00000000};
byte c_2[] = {B00000000,B00000000,B00111100,B00100100,B00100100,B00111100,B00000000,B00000000};
byte c_3[] = {B00000000,B00000000,B00000000,B00011000,B00011000,B00000000,B00000000,B00000000};
byte jenny[] = {B00000000,B01111100,B00010000,B00010000,B00010000,B00010000,B01110000,B00000000};
byte flecha_1[] = {B00000000,B00001000,B00001100,B01111110,B00001100,B00001000,B00000000,B00000000};
byte flecha_2[] = {B00000000,B00001000,B00001100,B01111110,B01111110,B00001100,B00001000,B00000000};
byte heart[] = {B00000000,B01101100,B11111110,B11111110,B01111100,B00111000,B00010000,B00000000};
byte heart_outline[] = {B00000000,B01101100,B10010010,B10000010,B01000100,B00101000,B00010000,B00000000};

byte load1[] = {B00000000,B00000000,B00000000,B00000000,B00000000,B11111110,B10000010,B11111110};
byte load2[] = {B00000000,B00000000,B00000000,B00000000,B00000000,B11111110,B11000010,B11111110};
byte load3[] = {B00000000,B00000000,B00000000,B00000000,B00000000,B11111110,B11100010,B11111110};
byte load4[] = {B00000000,B00000000,B00000000,B00000000,B00000000,B11111110,B11110010,B11111110};
byte load5[] = {B00000000,B00000000,B00000000,B00000000,B00000000,B11111110,B11111010,B11111110};
byte load6[] = {B00000000,B00000000,B00000000,B00000000,B00000000,B11111110,B11111110,B11111110};
//byte load7[] = {B00000000,B00000000,B00000000,B00000000,B00000000,B11111111,B11111111,B11111111};

byte Selecciona( char c, byte fil)
{
  if (c == '1') return(c_1[fil]);
  if (c == '2') return(c_2[fil]);
  if (c == '3') return(c_3[fil]);
  if (c == '4') return(jenny[fil]);
  if (c == '5') return(heart[fil]);
  if (c == '6') return(flecha_1[fil]);
  if (c == '7') return(flecha_2[fil]);
  if( c == 'l' ) return (load1[fil]);  
  if( c == 'o' ) return (load2[fil]);
  if( c == 'a' ) return (load3[fil]);
  if( c == 'd' ) return (load4[fil]);
  if( c == 'i' ) return (load5[fil]);
  if( c == 'n' ) return (load6[fil]);
  //if( c == 'g' ) return (load7[fil]);  
  if (c == ' ') return( sp[fil]);
}

void setup() 
{   
  for (int j=2; j<19; j++){
    pinMode(j, OUTPUT);           
  }
  digitalWrite(18, LOW);
}

void SetChar(char p) 
{    
 Clear();
 for (int fil = 0; fil <8 ; fil++)
 {
    delayMicroseconds(350); 
    digitalWrite( fil + 10 , LOW) ; // Activamos la fila para el barrido
    //byte F = N[fil] ;
    byte F = Selecciona( p, fil);
    for (int col =7; col >= 0 ; col--)
    {
      delayMicroseconds(350); 
      digitalWrite(8-col, LOW);     //Bajamos la columna
      bool b = GetBit(F, col)  ;
      if (b){
        digitalWrite( 9 - col  ,HIGH); //Levantamos la columna, con su pin
      }      
      else {
        digitalWrite( 9 - col  ,LOW); // Si 0, apagamos
      }        
    }                                    // Solo si b es 1
    digitalWrite( fil + 10 , HIGH) ;          // Apagamos fila antes de salir   
  }
}


bool GetBit( byte N, int pos)
{                              // pos = 7 6 5 4 3 2 1 0
  int b = N >> pos ;         // Shift bits
  b = b & 1 ;                // coger solo el ultimo bit
  return b ;
}

void Clear()
{
  for (int j=2; j<10; j++)  // Valores de los pines de columna
    digitalWrite(j, LOW); // Todos apagados
    for (int k= 10 ; k<18 ; k++){
      digitalWrite(k, HIGH);  // Todas las filas cortadas
    }
}

String s;
long t;
char c;
void loop()
{
  s = "loadin n n n n";
  for ( int n = 0; n < 14; n++ )
   {
    t = millis();
    c = s[n];
    if(n < 6){
      while ( millis()< t + 1000)
      SetChar(c);  
    } else {
      while ( millis()< t + 380)
      SetChar(c);
    }
  }  

  delay(500);
      
  //Jenny
  s = "4";
  t = millis();
  c = s[0];
  while(millis() < t + 4000){
    SetChar(c);
  }    

  //Corazn
  s = "5";
  t = 0;    
  t = millis();
  c = s[0];
  while(millis() < t + 4000){
    SetChar(c);
  }

  //Flecha a la derecha parpadeando
  for(int i = 0; i < 6; i++){
    s = "6 ";
    for(int n = 0; n < 2; n++){
      t = millis();
      c = s[n];
      while(millis() < t + 600){
        SetChar(c);
      }
    }
  }

  //Enciende el foco con el transistor y el relay
  digitalWrite(18, HIGH);

  //Corazn eterno
  s = "5";
  c = s[0];
  while(1){
    SetChar(c);
  }    
}
Led matrix code
The code could be improved if you want to add too much animation in the matrix, but for now it works very well. Feel free to leave any suggestion :)

Custom parts and enclosures

Box made with cardboard
Img 20180415 110438687 pingxguimh
Magic box
Magic box1 tlepfpvtl4

Schematics

Full circuit schematic
Magic box bb 0gozdqzz3x

Comments

Similar projects you might like

Exploring Encoders - Step Trackers for Motors

Project tutorial by SciJoy

  • 2,970 views
  • 3 comments
  • 9 respects

Arduino Darkness Activated Ghost

Project tutorial by Technovation

  • 1,977 views
  • 2 comments
  • 10 respects

Ask the Magic 8 Ball!

Project tutorial by Team College Bound

  • 1,721 views
  • 0 comments
  • 7 respects

No Candy For YOU!

Project tutorial by Jonathan Tindal

  • 789 views
  • 5 comments
  • 6 respects

Magic Eyes

Project tutorial by Ayush Aggarwal

  • 724 views
  • 0 comments
  • 3 respects

Pranked! Moving Tissue Box | Circuito.io

Project tutorial by Arduino “having11” Guy

  • 3,957 views
  • 1 comment
  • 18 respects
Add projectSign up / Login