#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
#define BUZZER 11
#define SMALLER_DELAY 128
PROGMEM const uint8_t morse_code_a_z[26] = {
0b01100000, // A .-
0b10010101, // B -...
0b10011001, // C -.-.
0b10010100, // D -..
0b01000000, // E .
0b01011001, // F ..-.
0b10100100, // G --.
0b01010101, // H ....
0b01010000, // I ..
0b01101010, // J .---
0b10011000, // K -.-
0b01100101, // L .-..
0b10100000, // M --
0b10010000, // N -.
0b10101000, // O ---
0b01101001, // P .--.
0b10100110, // Q --.-
0b01100100, // R .-.
0b01010100, // S ...
0b10000000, // T -
0b01011000, // U ..-
0b01010110, // V ...-
0b01101000, // W .--
0b10010110, // X -..-
0b10011010, // Y -.--
0b10100101, // Z --..
};
void send_bit(const bool& dash) {
lcd.print(dash ? '-' : '.');
analogWrite(BUZZER, 63);
delay((dash ? 3 : 1) * SMALLER_DELAY);
digitalWrite(BUZZER, LOW);
delay(1 * SMALLER_DELAY);
}
uint8_t hpos = 0;
void send_char(const char& c) {
// Send the character to the LCD
lcd.setCursor(hpos++, 0);
lcd.print(c);
// Position the cursor to the next line to start the .- sequence
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
}
void print_number(const char& number) {
if (!isDigit(number)) return;
send_char(number);
uint8_t num = number - '0';
for (uint8_t i = 0 ; i < 5 ; i++) {
if (num == i) num += 10;
if (num < 6 + i) send_bit(false);
else send_bit(true);
}
}
void print_character(char character) {
if (!isAlpha(character)) return;
if (isLowerCase(character)) character += 'A' - 'a';
send_char(character);
uint8_t code = morse_code_a_z[character - 'A'];
while (code != 0) {
switch (code >> 6) {
case 0:
break;
case 1:
send_bit(false);
break;
case 2:
send_bit(true);
break;
case 3:
Serial.print("Error while printing character: ");
Serial.println(character);
Serial.print("Got 3 in the 2 leftmost bits of code ");
Serial.println(code, BIN);
break;
default:
Serial.print("Error while printing character: ");
Serial.println(character);
Serial.print("Got ? in the 2 leftmost bits of code ");
Serial.println(code, BIN);
}
code <<= 2;
}
}
void print_whitespace() {
send_char(' ');
delay(3 * SMALLER_DELAY);
}
void print_char(const char& character) {
if (isWhitespace(character)) print_whitespace();
else if (isAlpha(character)) print_character(character);
else if (isDigit(character)) print_number(character);
else if (isPunct(character)) { send_char(character); delay(1 * SMALLER_DELAY); }
else if (character == '\0') {}
else if (character == '\1') { /* This happens at the end of every string, don't know why */ }
else {
Serial.print("Error: unknown character ");
Serial.print(character);
Serial.print(" (0b");
Serial.print((uint8_t)character, BIN);
Serial.println(")");
send_char('?');
analogWrite(BUZZER, 63);
delay(4 * SMALLER_DELAY);
digitalWrite(BUZZER, LOW);
delay(1 * SMALLER_DELAY);
}
delay(2 * SMALLER_DELAY);
}
void print_string(const char* characters, int len = 15) {
for (uint8_t pos = 0 ; pos <= len ; pos++) {
print_char(characters[pos]);
}
}
void reset_LCD() {
hpos = 0;
lcd.clear();
lcd.noCursor();
lcd.setCursor(0, 0);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
lcd.begin(16, 2);
reset_LCD();
pinMode(BUZZER, OUTPUT);
}
char* readStr() {
uint8_t idx = 0;
char* str = (char*)malloc(128 * sizeof(char));
while (Serial.available() && idx < 128) {
str[idx] = Serial.read();
idx++;
delay(2);
}
for ( ; idx < 128 ; idx++) {
str[idx] = '\0';
}
return str;
}
void serialEvent() {
while (Serial.available()) {
char* string;
Serial.setTimeout(-1);
string = readStr();
Serial.print("Received: ");
Serial.println(string);
char substr[16];
for (uint8_t c = 0 ; c < 128 && string[c] != '\0' && string[c] != '\r' && string[c] != '\n' ; c += 16) {
for (uint8_t offset = 0 ; offset < 15 ; offset++) {
if (string[c + offset] != '\0' && string[c + offset] != '\r' && string[c + offset] != '\n') {
substr[offset] = string[c + offset];
} else {
substr[offset] = '\0';
}
}
reset_LCD();
print_string(substr);
}
free((void*)string);
}
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 0);
}
void loop() {
}
Comments
Please log in or sign up to comment.