#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
//Define all the different component pins
#define btn 1 //Red button
#define btn2 2 //Green button
#define led1 15 //Red LED
#define led2 16 //Green LED
#define bzr 27 //Buzzer
#define dot_dash_ms 300 //Length of time for button presses
#define space_ms 500 //Time to print space
int main()
{
stdio_init_all();
//--------------------------Initialise all of the pins being used --------------------------//
gpio_init(btn);
gpio_init(btn2);
gpio_init(bzr);
gpio_init(led1);
gpio_init(led2);
gpio_set_dir(btn, GPIO_IN); //Pin button is wired to set as an input
gpio_set_dir(btn2, GPIO_IN); //Pin button is wired to set as an input
gpio_set_dir(bzr, GPIO_OUT); //Pin buzzer is wired to set as an output
gpio_set_dir(led1, GPIO_OUT); //Pin LED is wired to set as an output
gpio_set_dir(led2, GPIO_OUT); //Pin LED is wired to set as an output
gpio_pull_up(btn); //Button set to pull up so logic = 0 when pressed
gpio_pull_up(btn2); //Button set to pull up so logic = 0 when pressed
//Timer functions ints created for start of timer functions
int start = 0;
int stop = 0;
int elapsed = 0;
//------Booleans created for button presses, messages being printed to monitor & space printing between words-------//
bool pressed = 0;
bool space_printed = 0;
bool led2_on = 0;
bool info = 0;
bool msg_start = 0;
bool msg_end = 0;
// Morse table array made ('x' has been added to make all aspects of array the same length)
char morse_codes[36][6] = {
{'.','-','x','x','x','x'}, // A
{'-','.','.','.','x','x'}, // B
{'-','.','-','.','x','x'}, // C
{'-','.','.','x','x','x'}, // D
{'.','x','x','x','x','x'}, // E
{'.','.','-','.','x','x'}, // F
{'-','-','.','x','x','x'}, // G
{'.','.','.','.','x','x'}, // H
{'.','.','x','x','x','x'}, // I
{'.','-','-','-','x','x'}, // J
{'-','.','-','x','x','x'}, // K
{'.','-','.','.','x','x'}, // L
{'-','-','x','x','x','x'}, // M
{'-','.','x','x','x','x'}, // N
{'-','-','-','x','x','x'}, // O
{'.','-','-','.','x','x'}, // P
{'-','-','.','-','x','x'}, // Q
{'.','-','.','x','x','x'}, // R
{'.','.','.','x','x','x'}, // S
{'-','x','x','x','x','x'}, // T
{'.','.','-','x','x','x'}, // U
{'.','.','.','-','x','x'}, // V
{'.','-','-','x','x','x'}, // W
{'-','.','.','-','x','x'}, // X
{'-','.','-','-','x','x'}, // Y
{'-','-','.','.','x','x'}, // Z
{'.','-','-','-','-','x'}, // 1
{'.','.','-','-','-','x'}, // 2
{'.','.','.','-','-','x'}, // 3
{'.','.','.','.','-','x'}, // 4
{'.','.','.','.','.','x'}, // 5
{'-','.','.','.','.','x'}, // 6
{'-','-','.','.','.','x'}, // 7
{'-','-','-','.','.','x'}, // 8
{'-','-','-','-','.','x'}, // 9
{'-','-','-','-','-','x'} // 0
};
char letters[36] = {
'A','B','C','D','E','F','G','H','I',
'J','K','L','M','N','O','P','Q','R',
'S','T','U','V','W','X','Y','Z','1',
'2','3','4','5','6','7','8','9','0'
};
//--------------------Create buffers for the morse codes to be inputted into when button is pressed ------------------//
char morse_buffer[5]; // Stores the morse codes set @ 5 because that is the maximum amount of symbols that should be inputted
int morse_index = 0; // Stores where the next morse code symbols go when inputted
//-------------------------------------Create buffers for the outputted code------------------------------------//
char text_line[40]; //The output buffer to hold the readable letters, set to 40 as we only need 36 characters (A-Z/0-9)
int text_line_index = 0; //The line where the next char goes into before being outputted
//-----------------------------------Code to translate the morse to letters--------------------------------------//
char translate_morse(char *code, int code_len) //*code points to 1st symbol in the input buffer & code_len tells function how many symbols to read
{
for (int i = 0; i < 36; i++) //Loop through morse_codes array to see if input matches
{
int match = 1; //Start by telling function there is a match
for (int j = 0; j < code_len; j++) //Loop to compare inputted symbols to the ones in the table
{
if (morse_codes[i][j] != code[j]) //If any of the symbols in the row don't match, match changes to 0
{
match = 0;
break; //This stops the function comparing this part of the array as soon as a mismatch is found so it moves onto the next
}
}
//--------------Ensure stored code has no extra symbols beyond code_len-----------------//
if (match == 1 && morse_codes[i][code_len] == 'x')
{
return letters[i]; // When matched; letters can be returned immediately
}
}
printf("\nInvalid Morse code!\n"); //If there isn't a matching letter you get an error message
}
while (1)
{
//-------------Display operating instructions when button is pressed--------------//
if ((gpio_get(btn2)==1) && (msg_start == 0))
{
printf("Press green button to begin message\n"); //First message on screen
msg_start = 1;
}
else if (gpio_get(btn2) == 0) //If button 2 pressed
{
if ((led2_on == 0) && (info == 0)) //If LED2 & instructions arent printed to screen
{
gpio_put(led2, 1); //Turn LED2 on
led2_on = 1; //Leave LED2 on from now on until anything changes
//------------Print operation instructions to screen--------------------//
printf("Red button pressed <300ms = dit (.) & >300ms = dah (-)\r\n");
printf("A character will be translated after 500ms\r\n");
printf("Space between words will be printed after 1.5s\r\n\n");
printf("Translation: ");
info = 1; //Keep instructions printed once
}
}
//--------------------------Loops to start & stop timers when button is pressed--------------------------//
if (info == 1) //Loop only starts when operation instructions are printed to screen
{
if ((gpio_get(btn) == 1) && (pressed == 1)) //When button isn't pressed but pressed boolean now 1
{
stop = to_ms_since_boot(get_absolute_time()); //Get the time that the button was released
gpio_put(led1, 0); //Turn LED off
gpio_put(bzr, 0); //Turn buzzer off
pressed = 0; //Now pressed boolean back to 0
elapsed = stop - start; //Create an integer for how long the button has been pressed
if (elapsed < dot_dash_ms) //If timer is <300ms
{
morse_buffer[morse_index++] = '.'; //Input '.' into buffer
//printf(".");
}
else
{
morse_buffer[morse_index++] = '-'; //Otherwise input '-'
//printf("-");
}
sleep_ms(50);
}
else if (gpio_get(btn) == 0) //If button is pressed
{
if (pressed == 0) //Pressed boolean is still 0
{
start = to_ms_since_boot(get_absolute_time()); //Start timer
pressed = 1; //Set pressed boolean to 1
}
gpio_put(led1, 1); //Turn on red LED
gpio_put(bzr, 1); //Turn on buzzer
sleep_ms(50);
}
//-----------------Detect end of a letter or end of a word----------------//
if (pressed == 0) //When pressed boolean is now back to 0 after button press
{
int now = to_ms_since_boot(get_absolute_time()); //Get another time stamp
//-----------End of a letter------------------//
if (morse_index > 0 && (now - stop) > space_ms && (now - stop) < 3 * space_ms) //If the morse buffer has at least 1 character in it, the time period taken is >500ms & >1.5s
{
char letter = translate_morse(morse_buffer, morse_index); //Letter is now taken from inputting our morse codes into the 'translate_morse' function written earlier
text_line[text_line_index++] = letter; //Inputs the translated letter into the 'text_line' output buffer then moves onto the next space within it
morse_index = 0; //Morse index then reset
space_printed = 0; //Space printed set back to 0 so other spaces can be printed in message not just 1 space
}
//----------------End of word-----------------//
if ((now - stop) >= 3 * space_ms) //If time period taken >= 1.5s
{
if (morse_index == 0 && space_printed == 0) //Whilst no morse has been inputted & no spaces have been printed yet
{
text_line[text_line_index++] = ' '; //A space is added to the output buffer
//printf(" ");
space_printed = 1; //Space printed is now 1 so no more are printed
}
}
//--------------If there is a pause, print the output to monitor---------------//
if ((now - stop) > 10 && text_line_index > 0) //If time stamp is greater than 10ms & there is a character in text line
{
text_line[text_line_index] = '\0'; //Null terminator to change text_line into a string
printf("%s\r", text_line); //Print the character inside the string
text_line_index = 0; //Reset text_line back to 0
sleep_ms(50);
}
if ((now-stop) >= (120 * space_ms) && (msg_end == 0) && (led2_on == 1)) //If time since last press is >1min & message end boolean still 0 & LED2 is still on
{
printf("\n\n----------Transmission terminated!----------\r\n");
msg_end = 1; //Change message end boolean to 1 so it only prints once
gpio_put(led1, 0); //Turn off red LED
gpio_put(led2, 0); //Turn off green LED
gpio_put(bzr, 0); //Turn off buzzer
while (1)
{
sleep_ms (1000); //While loop in 'if' statement to stop program running until restart
}
}
}
}
}
}