Introduction: Arduino Morse Code Writer

I made a robot that can convert any given text into Morse code and then write it down!!
It's made out of cardboard and Lego and for the electronics I used Arduino and only two motors.

Supplies

Arduino Uno board
Stepper motor
Micro servo SG90
ULN2003 stepper motor driver module
Power supply module
Breadboard
4× Jumper wires
6× Female-to-Male dupont wires
9V1A Adapter
USB cable
Cardboard
2× Wooden dowels
2× Springs
Straw
White paper
Lego
Super glue
Hot glue gun
Elastic band ( to make a pen holder)
Scissors
Cutter

Step 1: Building the Base

Start by building the base.
Mine is 4 studs wide and 20 studs long, after building one layer with those lengths, I built a one stud wide boarder around it leaving a gap on one side to leave space for the stepper motor, then I added tile pieces to the middle part where the paper strip will be. Using Lego made it very sturdy and easy to modify.
To make the paper roll, I cut strips of A4 paper 1.2cm wide ( I chose this width because it's the same width as the Lego wheel I used, you can make yours bigger or smaller depending on your wheel) and I glued their ends together to form one very long strip, then I wrapped it around the wheel.

Step 2: The Servo Piece

For this step you need:

  • two wooden dowels 4cm long
  • two springs 2cm long
  • one straw cut to two pieces 2cm long each
  • one 12cm by 4cm piece of cardboard
  • two 4cm by 1.5cm pieces of cardboard
  • one 4cm by 2cm piece of cardboard


First, glue the dowels to one of the 4 by 1.5 pieces, then insert the springs and the straws in the dowels, then glue the other cardboard piece on the other side to hold everything in place.

Second, glue the 4cm by 2cm piece on top of the straws.

Third, flip the whole piece over and glue a small dowel to the back of it, not in the middle but slightly to the left. (I forgot to add the small dowel in the first picture)

Finally, cut a hole in the big piece of cardboard the size of the front of the servo motor and glue the motor in, then glue the piece we just made with the dowels to the big piece so that when the servo moves, it pushes the small dowel down which in turn pushes the springs down too.


I ended up cutting about 3cm from the bottom part of the 12cm by 4cm piece and gluing two more 4cm by 1.5cm pieces to it, then covering that with a 5.5cm by 4cm piece of cardboard.
And to hold the marker I made a small loop of elastic band and glued it to a small piece of cardboard then I glued that to the 4cm by 2cm piece which will move down when the servo starts. These additions stopped the marker from moving from side to side when the springs come back up.

Step 3: Adding the Servo Motor and the Paper Roll to the Base

I added two more bricks to one side of the base to support the servo piece and I glued it in place.
Then I added the wheel to the far end of the base.

Step 4: Building the Stepper Motor Frame

This step was a bit of a challenge, because the motor wasn't made to fit with Lego perfectly. However, I did manage to do it by using the two holes in the motor to secure it to in place. Next, I glued a Lego wheel to the tip of the motor and then I put it right next to the base on the side that I left open in step 1.

Step 5: Finishing Touches

I added two arc pieces to cover the wheel to fix the paper in place. And I added two smaller arc pieces one to hold the wires of the stepper motor and another one to hold the paper. Lastly, I changed the stepper motor wheel to a slightly bigger one that moved the paper better than the old wheel.

Step 6: Electronics

Finally, you have to connect the motors to the Arduino and upload the code.

We will start with the servo motor, connect the brown wire (the ground wire) to the GND pin, then the red wire (the power wire) to the 5V pin, and the orange wire(the signal wire) to the Dig #5 pin. Next, the stepper motor, connect 1N1 to Dig #11, 1N2 to Dig #10, 1N3 to Dig #9, 1N4 to Dig #8, the 5V to the positive side of the breadboard and the ground pin to the negative side of the breadboard. And don't forget to connect the power supply module to the breadboard making sure that its positive and negative sides align correctly to the corresponding sides on the breadboard. If you forget to do so, you will reverse the power to your project, and you don't want to do that.

For the code, I wrote four methods, one to write a dot, one to write a dash, and two to leave space between each letter and each word. That way, I can just call these methods when I need them instead of writing it again for every letter. Then I wrote a for loop that goes through each letter of the text and write it, Inside it, I wrote an if statement for each letter but you can write it in a switch statement if you prefer. Of course you can add to the code to enable the program to read numbers. When all the wiring is ready, just copy and paste the code to your IDE. Don't forget to install the stepper, servo, and string libraries. After that, you're good to go.

How it works

When the Arduino starts the program looks at the first letter of the text., and depending on which one it is, it calls the functions that writes it in Morse code. For example, when the dot function is called, the servo motor is set to 160 which moves the pen down, then it's set back to 90 which lets the springs come back up moving the pen with them. And if the dash function is called, the servo moves the pen down, then the stepper motor rotates the wheel which pulls the paper making the pen write a dash. And if one of the space functions are called the stepper motor rotates but with the pen up so it pulls the paper making a space between the letters or the words. When it's done, it goes to the next letter and repeats the same process. I hope you like it ;)

The code

#include <Arduino.h>
#include <Stepper.h>
#include <Servo.h>
#include <string.h>

const int stepsPerRevolution = 150; // This is the variable for the stepper motor 
String sentence = "*hello";   //Change this variable to write different words but only write in small letters and start your word with "*" 
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
Servo myServo;

// This is the method that makes the robot write a dot
void dot() {
  Serial.println("dot start");
  myServo.write(160);
  delay(1000);
  myServo.write(90);
  delay(1000);
  myStepper.step(stepsPerRevolution);
  delay(1000);
  Serial.println("dot done");
}

// This is the method that makes the robot write a dash
void dash() {
  Serial.println("dash start");
  myServo.write(160);
  delay(1000);
  myStepper.step(stepsPerRevolution);
  delay(1000);
  myServo.write(90);
  delay(1000);
  myStepper.step(stepsPerRevolution);
  delay(1000);
  Serial.println("dash done");
}

// This is the method that makes the robot leave a space between each letter
void space() {
  Serial.println("space start");
  myServo.write(90);
  delay(1000);
  myStepper.step(200);
  delay(1000);
  Serial.println("space done");
}

// This is the method that makes the robot leave a bigger space between each word
void bigSpace() {
  myServo.write(90);
  myStepper.step(250);
  delay(1000);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  myStepper.setSpeed(100);
  myServo.attach(5);
  

    int first = sentence.indexOf('*');
    // this for loop goes through each letter of the string and then calls the right methods to write it down
  for (int i = 0; i < sentence.length(); i++) {
        if (sentence.charAt(first + i) == 'a') {
            Serial.print(".- ");
            dot();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'b') {
            Serial.print("-... ");
            dash();
            dot();
            dot();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'c') {
            Serial.print("-.-. ");
            dash();
            dot();
            dash();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'd') {
            Serial.print("-.. ");
            dash();
            dot();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'e') {
            Serial.print(". ");
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'f') {
            Serial.print("..-. ");
            dot();
            dot();
            dash();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'g') {
            Serial.print("--. ");
            dash();
            dash();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'h') {
            Serial.print(".... ");
            dot();
            dot();
            dot();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'i') {
            Serial.print(".. ");
            dot();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'j') {
            Serial.print(".--- ");
            dot();
            dash();
            dash();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'k') {
            Serial.print("-.- ");
            dash();
            dot();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'l') {
            Serial.print(".-.. ");
            dot();
            dash();
            dot();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'm') {
            Serial.print("-- ");
            dash();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'n') {
            Serial.print("-. ");
            dash();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'o') {
            Serial.print("--- ");
            dash();
            dash();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'p') {
            Serial.print(".--. ");
            dot();
            dash();
            dash();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 'q') {
            Serial.print("--.- ");
            dash();
            dash();
            dot();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'r') {
            Serial.print(".-. ");
            dot();
            dash();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 's') {
            Serial.print("... ");
            dot();
            dot();
            dot();
            space();
        } else if (sentence.charAt(first + i) == 't') {
            Serial.print("- ");
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'u') {
            Serial.print("..- ");
            dot();
            dot();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'v') {
            Serial.print("...- ");
            dot();
            dot();
            dot();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'w') {
            Serial.print(".-- ");
            dot();
            dash();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'x') {
            Serial.print("-..- ");
            dash();
            dot();
            dot();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'y') {
            Serial.print("-.-- ");
            dash();
            dot();
            dash();
            dash();
            space();
        } else if (sentence.charAt(first + i) == 'z') {
            Serial.print("--.. ");
            dash();
            dash();
            dot();
            dot();
            space();
        } else if (sentence.charAt(first + i) == ' ') {
            Serial.print("/ ");
            bigSpace();
        }  
    
  }
}

void loop() {
  //Don't write anything here
}

Step 7: Troubleshooting

The wheel is not moving

There might be too much friction between the wheel and the paper, try elevating the wheel a bit or changing it.

The wheel pulls the paper but then it keeps rotating without pulling the paper

Make sure you glued the wheel in the center of the stepper motor

The dots and dashes are connected

Check if the dot, dash and space functions are written correctly, they should be like this:

// This is the method that makes the robot write a dot
void dot() { Serial.println("dot start"); myServo.write(160); delay(1000); myServo.write(90); delay(1000); myStepper.step(stepsPerRevolution); delay(1000); Serial.println("dot done"); }
// This is the method that makes the robot write a dash
void dash() {
  Serial.println("dash start");
  myServo.write(160);
  delay(1000);
  myStepper.step(stepsPerRevolution);
  delay(1000);
  myServo.write(90);
  delay(1000);
  myStepper.step(stepsPerRevolution);
  delay(1000);
  Serial.println("dash done");
}
// This is the method that makes the robot leave a space between each letter
void space() {
  Serial.println("space start");
  myServo.write(90);
  delay(1000);
  myStepper.step(200);
  delay(1000);
  Serial.println("space done");
}