Electromechanical Game: Morse Code
Project Info: Fa22-ME-0030-01-Electronics & Controls I, Individual Project
Project Type: Electromechanical Game
Project Timeline: 2 weeks (October-November 2022)
Skills and Techniques: Design and fabrication, controlling Adafruit Feather through CircuitPython
OVERVIEW
Brief: Build an electromechanical game with the following characteristics:
It is controlled by a Feather microcontroller.
It has at least one electromechanical element that moves, like a motor or a solenoid.
It has some kind of user input, like buttons, knobs, joysticks, sensors, or the like
It is NOT exactly like a game that already exists, like skeeball or checkers. It can be similar to existing games, but should be creative to some extent
Step 1: Define & Ideate
Background
My personal learning goal: Get more comfortable with feather programming and control a stepper motor and two buttons in coordination. I want to be able to learn how to make effective use of CircuitPython and find simpler ways to control
Description: The user pushes “dotting” or "dashing” buttons to translate Morse code signals into actual words that will be printed on the screen. Different combinations (dot and dash) generate different letters that will form words when combined. An LED light signals the user when a button is clicked and blinks the length of a dot or dash depending on which button is pressed. When the user is done creating the letter, after a certain wait time, they move on to a different letter as the feather starts processing from the beginning (reset). An arm on a spinning wheel points out to specific letters as the user inputs signals. Letters go around the wheel like a clock so the arm moves clockwise or counterclockwise. A dot is a single unit while a dash is 2 units, which means 2 times longer.
Parts & Components
A stepper motor: controls the wheel with an arm that spins and points out to letters
H-bridge: enables the motor to spin in both directions and controls the arm
N-channel and P-channel MOSFETs, Barrel Jack, Screw terminal, Resistors
Adafruit Feather RP2040 microcontroller
Resistors (x2)
Push buttons (x2)
PCB (Printed Circuit Board)
Capacitors (x3), Voltage regulators (5V and 3V), Barrel jack, Screw terminal, Power supply, Connector pins
Breadboard
Jumper wires
Alligator clips
Box (plywood)
Step 2: Develop
Hardware
Printed Circuit Board (PCB)
I utilized the PCB I created for the previous project as a breadboard power supply, which was helpful in spatial organization. The PCB plugs directly into a breadboard, accepts power from a plug from a 12 V wall adapter, and emits 12 V, 5 V, and 3.3 V. The PCB powers the stepper motor through the H-bridge. I designed the PCB on KiCad as shown on the 3D view diagram attached on the right.
Breadboard Prototype
For better visual representation and organization, I made sure to connect the negative (-) column to the ground and stick out wires for further wiring and grounding of components including LED lights and the motor driver board.
Wiring the Stepper Motor
Following instructions and tutorials I found online, I wired the NEMA 17 stepper motor to a
L298N motor driver board since I wanted the motor to spin in both directions, clockwise and counterclockwise. Using the four control pins IN1, IN2, IN3, and IN4 which control the switches of the H-Bridge circuit inside the L298N chip, I learned how to control both the speed and the spinning direction of the stepper motor. I then wired them to chosen GPIO output pins on the feather microcontroller. On the other hand, I supplied the 5V from the PCB to the feather microcontroller.
3D Modelling and Printing : Motor Attachment/Wheel Arm
Because the stepper motor directly controls the wheel arm that spins and lands on a letter, I created a secure motor attachment that would also act as the arm. The attachment fits on and attaches to the motor shaft and stays attached securely enough to handle the amount of torque that stalls the motor when it is operating at 12 V. I designed it on Onshape for convenience and printed on Prusa 3D printers with PLA filament.
Challenge: It was hard to size the motor attachment accurately so that it would be tight enough and move with the motor, without slipping. My first trial ended up being unsuccessful because I measured the stepper motor shaft and the D shape at its end and put the exact dimensions and did not give a margin. The 3D print ended up being too small and the shaft did not fit. Thus, I realized I should account for filament shrinkage (although it is very low with PLA, around 0.5-1%), and made my second design 1% bigger in size.
Box (Enclosure)
To enclose the electromechanical components, I laser cut a box from plywood with box joints (2D to 3D) so that the sides of the box would click easily. I used the laser joint feature on Onshape to create joints at desired quantity and length.
I made sure that the wooden sides are stuck in place by hot gluing through the joints. I made sure the create accurately sized holes for LED lights, push buttons, THE power cable, and the USB-C cable for the feather.
Code: Software
We used the Mu Editor which works well with Adafruit CircuitPython boards, including the Feather for the project to be able to connect with the computer. I made use of various CircuitPython libraries (import board, digitalio, time and adafruit_motor stepper) helpful codes for the stepper motor and the LED lights provided by the class.
Python Dictionary
Because I am converting dot-dash combination signals into a string of letters as input is received by clicking a dot or dash push button by the users, I made use of Python Dictionaries. Creating a dictionary allowed me to store data as key-value pairs for Morse Code-to-letter conversion. I mapped dot-dash combinations to specific letters and the assigned numbers for each letter for stepper motor calculations around the wheel. Here are two examples from the alphabet: ".-": ("A", 1), "-...": ("B", 2).
State Machine
This morse code conversion game essentially functions based on 3 different states: waiting for user input, dotting, or dashing. Using a state machine architecture in the code was ideal and convenient since state machine is a decision-making logic that determines when to move to a particular state based on a set of conditions and executes a response accordingly. As the user presses the dot or dash buttons, the code should do the following:
wait for user input (STATE_WAIT)
if the user input is dotting (presses the dot switch)
process the dot symbol(s) (STATE_DOT)
blink the LED light for 0.25 seconds
wait for further user input
dotting (if the dot switch is pressed again, repeat the dot state)
dashing (if the dash switch is pressed, process dashing (STATE_DASH)
no input (if more than 2 seconds elapse, go back to the waiting state, STATE_WAIT)
process dot/dash combinations, update each time
check the dictionary to identify any matches
print the corresponding letter
spin the motor accordingly and land on the specific letter on the wheel, based on the corresponding number value which signals the motor how many steps to travel
Motor Spin & Letter Landing
I used the stepper command from the adafruit_motor library for the stepper motor. The number of rotations set by default is 400 steps so I adjusted one step to be equal to 400/26 based on 26 letters of the alphabet. In this way, as the code processes and identifies each letter with a specific number value, the motor will spin accordingly.
Challenge
I wanted to make the game faster, more efficient, and sustainable by making the motor spend minimal energy. If the motor traveled clockwise only, it meant that often times when going to a new letter that comes before in the alphabet, the motor would pass the starting point (letter A) and spin more than half a rotation. Because I had an H-bridge in my circuit, I was able to make the motor spin counterclockwise as well based on the position of the next inputted letter in the alphabet relative to the previously inputted letter.
It was challenging to consider and insert multiple cases for calculations based on the numerical difference between each letter so that the motor would spin in the clockwise or counterclockwise direction. I first used absolute value in calculations but soon realized that it made the code more complicated and when I tried different examples it did not work at all times. So going from general to more specific, first defined 2 main cases: the difference between the value of the next letter and the previous letter being positive or negative. I then compared the values for both clockwise and counterclockwise steps to each other and then signaled the motor to spin accordingly.
MORSE CODE VIDEO
Reflection
As someone unfamiliar with Python, designing an electromechanical game with a strong coding component was a big challenge for me. Although I did borrow some libraries from Circuit Python such as the stepper motor and the LED lights, I had to do additional research into Python dictionaries and the concept of a state machine. First using pen and paper for each stage, I defined the range of actions for each stage depending on user input and then continuously tested for each state and different cases, including edge cases. I learned how to debug in a patient way, put tester print statements inside code to check it works in all conditions, and follows a top-down order from one state to another.