#include #include "rgb_lcd.h" #include SoftwareSerial mySerial(10, 11); rgb_lcd lcd; #define DOT false #define DASH true #define MAX_CHAR_LENGTH 6 #define BUTTON A0 #define LIGHTSENSOR A1 #define pinLED 5 #define BUZZER 4 #define PULSE_THRESHOLD 250 #define LETTER_SEPARATION 600 #define WORD_SEPARATION 8000 const struct MorseTree *tree = NULL; int ledPin = 13; int colorR = 0; int colorG = 0; int colorB = 100; String answerString = String(""); String answer = "Yellow"; String readString; int answerLength = answer.length(); int value; int button = 0; int pulseThreshold = 0; int letterSeparation = 0; int wordSeparation = 0; void initMorse(int lbutton, int lpulseThreshold, int lletterSeparation, int lwordSeparation) { tree = generateMorseTree(); button = lbutton; pulseThreshold = lpulseThreshold; letterSeparation = lletterSeparation; wordSeparation = lwordSeparation; } struct MorseTree { // '-' unless this is a leaf node char character; struct MorseTree *dotChild; struct MorseTree *dashChild; }; struct MorseData { char character; bool code[MAX_CHAR_LENGTH]; byte codeLength; }; void initMorseTree(struct MorseTree *tree) { tree -> character = '-'; tree -> dotChild = NULL; tree -> dashChild = NULL; } struct MorseTree *newMorseTree() { struct MorseTree *tree = (struct MorseTree *) malloc(sizeof(struct MorseTree)); initMorseTree(tree); return tree; } void addTreeMember(struct MorseTree *tree, struct MorseData &data) { struct MorseTree *current = tree; for (byte i = 0; i < data.codeLength; i++) { boolean currentSymbol = data.code[i]; if (currentSymbol == DOT) { if (current -> dotChild == NULL) current -> dotChild = newMorseTree(); current = current -> dotChild; } else { if (current -> dashChild == NULL) current -> dashChild = newMorseTree(); current = current -> dashChild; } } // now current must be a leaf node current -> character = data.character; } void addTreeMembers(struct MorseTree *tree, struct MorseData data[], byte dataLength) { for (byte i = 0; i < dataLength; i++) addTreeMember(tree, data[i]); } void addAlphabet(struct MorseTree *tree) { struct MorseData data[] = { {'A', {DOT, DASH}, 2}, {'B', {DASH, DOT, DOT, DOT}, 4}, {'C', {DASH, DOT, DASH, DOT}, 4}, {'D', {DASH, DOT, DOT}, 3}, {'E', {DOT}, 1}, {'F', {DOT, DOT, DASH, DOT}, 4}, {'G', {DASH, DASH, DOT}, 3}, {'H', {DOT, DOT, DOT, DOT}, 4}, {'I', {DOT, DOT}, 2}, {'J', {DOT, DASH, DASH, DASH}, 4}, {'K', {DASH, DOT, DASH}, 3}, {'L', {DOT, DASH, DOT, DOT}, 4}, {'M', {DASH, DASH}, 2}, {'N', {DASH, DOT}, 2}, {'O', {DASH, DASH, DASH}, 3}, {'P', {DOT, DASH, DASH, DOT}, 4}, {'Q', {DASH, DASH, DOT, DASH}, 4}, {'R', {DOT, DASH, DOT}, 3}, {'S', {DOT, DOT, DOT}, 3}, {'T', {DASH}, 1}, {'U', {DOT, DOT, DASH}, 3}, {'V', {DOT, DOT, DOT, DASH}, 4}, {'W', {DOT, DASH, DASH}, 3}, {'X', {DASH, DOT, DOT, DASH}, 4}, {'Y', {DASH, DOT, DASH, DASH}, 4}, {'Z', {DASH, DASH, DOT, DOT}, 4}, }; addTreeMembers(tree, data, 26); } void addNumbers(struct MorseTree *tree) { struct MorseData data[] = { {'1', {DOT, DASH, DASH, DASH, DASH}, 5}, {'2', {DOT, DOT, DASH, DASH, DASH}, 5}, {'3', {DOT, DOT, DOT, DASH, DASH}, 5}, {'4', {DOT, DOT, DOT, DOT, DASH}, 5}, {'5', {DOT, DOT, DOT, DOT, DOT}, 5}, {'6', {DASH, DOT, DOT, DOT, DOT}, 5}, {'7', {DASH, DASH, DOT, DOT, DOT}, 5}, {'8', {DASH, DASH, DASH, DOT, DOT}, 5}, {'9', {DASH, DASH, DASH, DASH, DOT}, 5}, {'0', {DASH, DASH, DASH, DASH, DASH}, 5}, }; addTreeMembers(tree, data, 10); } void addPunctuation(struct MorseTree *tree) { struct MorseData data[] = { {'.', {DOT, DASH, DOT, DASH, DOT, DASH}, 6}, {',', {DASH, DASH, DOT, DOT, DASH, DASH}, 6}, {'?', {DOT, DOT, DASH, DASH, DOT, DOT}, 6}, }; addTreeMembers(tree, data, 3); } struct MorseTree *generateMorseTree() { struct MorseTree *tree = newMorseTree(); initMorseTree(tree); addAlphabet(tree); addNumbers(tree); addPunctuation(tree); return tree; } void waitFor(int pin, int state) { do { // spin until the pin reads the given state while (digitalRead(pin) != state) { } // delay, to verify the reading delay(5); // continue if the reading has changed } while (digitalRead(pin) != state); } boolean getNextSymbol() { waitFor(button, HIGH); digitalWrite(pinLED, HIGH); digitalWrite(BUZZER, HIGH); unsigned long start = millis(); waitFor(button, LOW); digitalWrite(pinLED, LOW); digitalWrite(BUZZER, LOW); unsigned long end = millis(); unsigned long pulseLength = end - start; // Serial.println(pulseLength); if (pulseLength > pulseThreshold) return DASH; else return DOT; } boolean shouldTimeOut() { unsigned long start = millis(); while (digitalRead(BUTTON) == LOW) { if (millis() - start > letterSeparation) return true; } return false; } boolean shouldBeSpace() { unsigned long start = millis(); while (digitalRead(BUTTON) == LOW) { if (millis() - start > wordSeparation) return true; } return false; } char getNextChar() { static boolean lastCharWasSpace = false; const struct MorseTree *current = tree; byte symbolCount = 0; if (!lastCharWasSpace && shouldBeSpace()) { lastCharWasSpace = true; return ' '; } lastCharWasSpace = false; while (true) { symbolCount++; boolean currentSymbol = getNextSymbol(); // Serial.println(currentSymbol == DOT ? "DOT" : "DASH"); if (currentSymbol == DOT) current = current -> dotChild; else current = current -> dashChild; if (current == NULL) return '-'; if (shouldTimeOut() || symbolCount >= MAX_CHAR_LENGTH) return current -> character; } // should never get here return '!'; } void lcdReset() { delay(1000); answerString.remove(0, 10); lcd.clear(); startUp(); } void startUp() { colorG = 0; colorB = 100; colorR = 0; lcd.setRGB(colorR, colorG, colorB); lcd.print("Yellow"); lcd.setCursor(0, 1); } void setup() { pinMode(BUTTON, INPUT); pinMode(LIGHTSENSOR, INPUT); pinMode(pinLED, OUTPUT); pinMode(ledPin, OUTPUT); value = analogRead(LIGHTSENSOR); initMorse(BUTTON, PULSE_THRESHOLD, LETTER_SEPARATION, WORD_SEPARATION); mySerial.begin(9600); Serial.begin(57600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } lcd.begin(16, 2); startUp(); } void loop() { while ( mySerial.available() ) { // While there is data in the buffer delay( 3 ); char cc = mySerial.read(); readString += cc; // build the string - “on” or “off” } if ( readString.length() >0 ) { mySerial.println( readString ); if ( readString == "on" ) { digitalWrite( ledPin, HIGH) ; } if ( readString == "off" ) { digitalWrite( ledPin, LOW ); } readString=""; } value = analogRead(LIGHTSENSOR); char c = getNextChar(); if(value<1) { lcd.clear(); answerString.remove(0, 10); startUp(); } else { answerString.concat(c); Serial.print(answerString); lcd.print(c); } if(answerString == answer) { delay(1000); lcd.clear(); colorG = 100; colorB = 0; colorR = 0; lcd.setRGB(colorR, colorG, colorB); lcd.print("Correct!"); delay(1000); answerString.remove(0, 10); lcdReset(); } else if(answerString.length() > answerLength) { delay(1000); lcd.clear(); colorR = 100; colorB = 0; colorG = 0; lcd.setRGB(colorR, colorG, colorB); lcd.print("Incorrect!"); lcdReset(); } }