Using an Arduino, a push button switch, and a speaker, I built a morse code machine that beeps as it is clicked and encodes the clicks into letters (I only programmed two letters so that I could write SOS, the “hello world” of morse.
Building the circuit was fairly simple. Most of the challenge was in coding.
Sketch
Results
It works! …eventually.
I’m thankful that the coding language in Arduino is so similar to Processing and P5, so I was able to figure out the logic of listening for a series of long or short button presses, to decode them into letters. It can probably be done with less variables and lines of code.
The code is not completely free of glitches – some clicks don’t trigger a letter (but they always trigger the tone). One persisting bug was that after a while the speaker started playing the tone, though the button wasn’t touched. Pressing the button then reset it.
I thought it had something to do with how the program detects the change in button state, so I changed
if(currentState>prevState){
on=true;
….
(and correspondingly for for on=false)
to:
if(currentState-prevState>0.5) {
on=true;
….
and later changed the value 0.5 to 0.9. It seems to have worked.
Code
// morse code machine (can actually only type S,O)
boolean pressed;
int currentState;
int prevState;
boolean on;
int duration;
int start;
int finish;
int signOne;
int signTwo;
int signThree;
int listening;
int letter[] = {0,0,0};
boolean fullLetter;
boolean gap;
int silence;
void setup() {
// put your setup code here, to run once:
pinMode(3,INPUT);
Serial.begin(9600);
pressed=false;
//currentState=LOW;
prevState=LOW;
listening=0;
fullLetter=false;
gap=false;
silence=0;
}
void loop() {
// put your main code here, to run repeatedly:
//get the state of the button
int currentState = digitalRead(3);
//Serial.println(currentState);
//did the button get pressed?
if(currentState-prevState>0.5) {
on=true;
gap=false;
start=millis();
silence=millis();
}
//did the button get released, and what was the length of the press
if(prevState-currentState>0.5) {
on=false;
finish=millis();
duration=finish-start;
listening++;
finish=0;
start=0;
}
// record the duration of press no. 1, 2, and 3
if (listening==1) {
letter[0]=duration;
}
if (listening==2) {
letter[1]=duration;
}
if (listening==3) {
letter[2]=duration;
fullLetter=true;
}
if (fullLetter) {
//check for S (short, short, short)
if (letter[0]<150 && letter[1]<150 && letter[2]<150) {
Serial.print(‘S’);
//Serial.print(“\t”);
}
//check for O (long, long, long)
if (letter[0]>150 && letter[1]>150 && letter[2]>150) {
Serial.print(‘O’);
//Serial.print(“\t”);
}
//reset for a new word
listening=0;
//letter[0]=0;
//letter[1]=0;
//letter[2]=0;
fullLetter=false;
gap=true;
silence=millis();
}
//put space between words
if (gap==true && millis()-silence>1500) {
Serial.print(“\t”);
//Serial.print(“fullLetter:”);
//Serial.print(fullLetter);
silence=millis();
//gap=false;
}
//play tone
if(on==true) {
tone(9,500);
delay(8);
}
if(on==false) {
tone(9,50);
}
prevState=currentState;
}
Posted in Fall '19 - Introduction to Physical Computation |