.................... | #include
<avr/pgmspace.h> #include <EEPROM.h> #include <LiquidCrystal.h> /*============================== Morsetrainer created 2011-05-25 by Ingo Strecker, DL6IS Geaendert von dk2os: Es kann zwischen Anzeige mit oder ohne Morsezeichen gewaehlt werden. ============================== 1 WpM = 5 BpM = 1200 ms 5 WpM = 25 BpM = 240 ms 10 WpM = 50 BpM = 120 ms 12 WpM = 60 BpM = 100 ms 20 WpM = 100 BpM = 60 ms 50 WpM = 250 BpM = 24 ms Folgende Angaben stammen aus Wikipedia: Morsecode Anfaenger kommen kaum ueber 5 WPM hinaus Die Pruefungsgeschwindigkeit fuer Funkamateure betrug 12 WPM Mit viel Uebung ueberschreitet man die 20 WPM-Marke. Sehr gute Funker schaffen ueber 50 WPM Der Weltrekord (Mitschrift von 5-er Buchstabengruppen) liegt bei 75,1 WPM 75,1 WpM = 375,5 BpM = 16 ms */ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ // Anzahl Zeichen des LCDs pro Zeile (min. 24) byte lcdColumns = 16; /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ // Nachbildung der ASCII-Tabelle mit Morsezeichen PROGMEM const char MorseLookup[57][7] = { ".----.", // ' "-.--.", // ( "-.--.-", // ) "", // * kein MorseLookup vorhanden ".-.-.", // + "--..--", // , "-....-", // - ".-.-.-", // . "-..-.", // / "-----", // 0 ".----", // 1 "..---", // 2 "...--", // 3 "....-", // 4 ".....", // 5 "-....", // 6 "--...", // 7 "---..", // 8 "----.", // 9 "---...", // : "-.-.-.", // ; "", // < kein MorseLookup vorhanden "-...-", // = "", // > kein MorseLookup vorhanden "..--..", // ? ".--._.", // @ ".-", // 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 "", // [ kein MorseLookup vorhanden "", // \ kein MorseLookup vorhanden "", // ] kein MorseLookup vorhanden "", // ^ kein MorseLookup vorhanden "..--.-" // _ }; //int Wert1 = 1; // Ohne Morsezeichen-Abstand zwischen den Buchstaben: 0 Mit...: 1 int Wert2 = 1; // Anzeigen des Morsecodes: 1 Keine Anzeige: 0 //LiquidCrystal lcd (7, 6, 5, 4, 3, 2); // initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //byte PinStrich = 12; //byte PinPunkt = 11; byte PinStrich = 7; byte PinPunkt = 6; byte PinSummer = 10; byte PinLED = 9; byte PinTaster = 8; byte current, previous = HIGH; byte count = 0; unsigned long firstTime; int WpM; int Periode; int BpM; String Klartext, Code = ""; byte Konsole; int useLED = 1; int useSummer = 1; int useCod = 1; int toneFreq = 800; // Tonfrequenz fuer Lautsprecher: 800 Hz int memSpeed = 0; // EEPROM int memLED = 1; // Adressen int memSummer = 2; // fuer int memCod = 1; // Ob der Morsecode angezeigt werden soll 1=Ja int memToneFreq = 3; // Variablenspeicher char Gegeben[9]; byte anzahlZeichen = 0; boolean getastet, gefunden = false; boolean pause = true; unsigned long ZeitVergangen = 0; void chooseSpeed() { // Gebe-Geschwindigkeit einstellen delay (200); lcd.clear(); lcd.setCursor (0, 0); lcd.print ("Gebe-Geschw.:"); do { BpM = WpM * 5; Periode = 1200 / WpM; // Dits pro Minute lcd.setCursor (0, 1); lcd.print ("WpM: "); lcd.print(WpM); lcd.print(", BpM: "); lcd.print(BpM); lcd.print (" "); if (!digitalRead (PinStrich)) { // Geschwindigkeit langsamer, min. 1 WpM -= 1; if (WpM < 1) WpM = 1; delay (200); } if (!digitalRead (PinPunkt)) { // Geschwindigkeit schneller, max. 75 WpM += 1; if (WpM >75) WpM = 75; delay (200); } } while (digitalRead (PinTaster)); delay (200); EEPROM.write (memSpeed, WpM); lcd.clear(); } void chooseOutput() { // Betriebsparameter festlegen delay (200); lcd.clear(); lcd.setCursor (0, 0); lcd.print ("LED/Sum ein/aus:"); do { lcd.setCursor (0, 1); lcd.print ("LED:"); lcd.print (useLED); lcd.print (" <|> Sum.:"); lcd.print (useSummer); if (!digitalRead (PinStrich)) { useLED = useLED ^ 1; delay (200); } if (!digitalRead (PinPunkt)) { useSummer = useSummer ^ 1; delay (200); } } while (digitalRead (PinTaster)); delay (200); EEPROM.write (memLED, useLED); EEPROM.write (memSummer, useSummer); lcd.clear(); lcd.setCursor (0, 0); lcd.print ("Tonfrequenz:"); do { lcd.setCursor (0, 1); lcd.print (toneFreq); lcd.print (" Hz"); if (!digitalRead (PinStrich)) { toneFreq -= 20; if (toneFreq < 500) toneFreq = 500; delay (200); } if (!digitalRead (PinPunkt)) { toneFreq += 20; if (toneFreq >1100) toneFreq = 1100; delay (200); } } while (digitalRead (PinTaster)); delay (200); EEPROM.write (memToneFreq, toneFreq / 10); lcd.clear(); } void chooseOutput2() { // Betriebsparameter festlegen delay (600); lcd.clear(); lcd.setCursor (0, 0); lcd.print ("Morsecode On/Off:"); do { lcd.setCursor (0, 1); lcd.print ("Morsecode:"); lcd.print (useCod); // lcd.print (" YYY.:"); lcd.print (useSummer); if (!digitalRead (PinStrich)) { useCod = useCod ^ 1; delay (600); } // if (!digitalRead (PinPunkt)) { // useSummer = useSummer ^ 1; // delay (600); } // } while (digitalRead (PinTaster)); delay (600); EEPROM.write (memCod, useCod); lcd.clear(); lcd.setCursor (0, 0); } void Morsen (byte Anzahl) { switch (Anzahl) { case 1: Code += "."; if (getastet) Gegeben[anzahlZeichen] = '.'; break; case 3: Code += "-"; if (getastet) Gegeben[anzahlZeichen] = '-'; break; case 98: Code += " "; // Abstand Buchstabe Klartext += " "; break; case 99: Code += " "; // Abstand Wort Klartext += " "; break; } displayMorsezeichen(); if ((Anzahl == 1) || (Anzahl == 3)) { //if (useSummer) digitalWrite (PinSummer, HIGH); // fuer Piezo-Summer mit Elektronik if (useSummer) tone (PinSummer, toneFreq); // fuer Lautsprecher if (useLED) digitalWrite (PinLED, HIGH); delay (Periode * Anzahl); // Morse-Symbol ausgeben //digitalWrite (PinSummer, LOW); // fuer Piezo-Summer mit Elektronik noTone(PinSummer); // fuer Lautsprecher digitalWrite (PinLED, LOW); delay (Periode); // Pause nach Symbol, 1 Dit if (getastet) anzahlZeichen++; } if (Anzahl == 98) PauseZeichen(); if (Anzahl == 99) PauseWort(); ZeitVergangen = millis(); } void PauseZeichen() { delay (Periode * 2); // Pause zwischen Buchstaben, 3 Dit's (1 Dit bereits gegeben) } void PauseWort() { delay (Periode * 6); // Pause zwischen Worte, 7 Dit's (1 Dit bereits gegeben) } void MorseZeichen (byte Konsole) { // Eingabe vom Computer auswerten byte index = 0; char Zeichen[10]; if (Konsole != 32) { //char* Zeichen = MorseLookup[Konsole-39]; strcpy_P (Zeichen, (char*)&MorseLookup[Konsole-39]); while (Zeichen[index] != '\0') { if (index == 0) Klartext += char(Konsole); else Klartext += " "; if (Zeichen[index] == '.') Morsen (1); else Morsen (3); index++; } Morsen (98); // Pause nach Buchstabe } else { Morsen (99); // Pause nach Wort } } // Scrollen der Zeilen void displayMorsezeichen() { // Morsezeichen und Klartext auf dem Display ausgeben // Wenn die Morsezeichen ausgegeben werden sollen: Wert2=1 if (useCod) { //if (Wert2 == 1) { if (Code.length() > lcdColumns) { while (Code.length() > lcdColumns) { Code = Code.substring(1); // Aehnlich scrollDisplayLeft(), aber ohne Display-Ueberlauf } } } if (Klartext.length() > lcdColumns) { while (Klartext.length() > lcdColumns) { Klartext = Klartext.substring(1); // Aehnlich scrollDisplayLeft(), aber ohne Display-Ueberlauf } } lcd.setCursor (0, 0); lcd.print (Klartext); // Anzeigen des Morsecodes, wenn Wert2 gleich 1 ist if (useCod) { // if (Wert2 == 1) { lcd.setCursor (0, 1); lcd.print (Code); } } void setup() { // lcd.begin (lcdColumns, 2); // LCD initialisieren // set up the LCD's number of columns and rows: lcd.begin(16, 2); // LCD initialisieren Serial.begin (9600); // serielle Schnittstelle aktivieren pinMode (PinPunkt, INPUT); digitalWrite (PinPunkt, HIGH); //Pullup-Widerstand aktivieren pinMode (PinStrich, INPUT); digitalWrite (PinStrich, HIGH); //Pullup-Widerstand aktivieren pinMode (PinTaster, INPUT); digitalWrite (PinTaster, HIGH); //Pullup-Widerstand aktivieren pinMode (PinSummer, OUTPUT); pinMode (PinLED, OUTPUT); // Variablen aus EEPROM lesen - Schreibzugriffe max. 100.000 laut Spezifikation, also aufpassen ;-) WpM = EEPROM.read (memSpeed); // Geschwindigkeit festlegen if (WpM == 255) WpM = 20; // falls noch nicht gespeichert, Standardgeschwindigkeit useLED = EEPROM.read (memLED); // LED ja/nein if (useLED == 255) useLED = 1; // falls noch nicht gespeichert, LED ein useSummer = EEPROM.read (memSummer); // Summer ja/nein if (useSummer == 255) useSummer = 1; // falls noch nicht gespeichert, Summer ein useCod = EEPROM.read (memCod); // Morsecode ja/nein if (useCod == 255) useCod = 1; // falls noch nicht gespeichert, Summer ein toneFreq = EEPROM.read (memToneFreq); // Tonfrequenz festlegen if (toneFreq == 255) toneFreq = 800; // falls noch nicht gespeichert, 800 Hz else toneFreq *= 10; BpM = WpM * 5; Periode = 1200 / WpM; // Dits pro Minute } void loop() { //lcd.print ("Willkommen!"); lcd.clear(); lcd.setCursor (0, 0); Code = ""; Klartext = ""; char buffer[10]; while (true) { // Tasten-Abfrage: http://arduino.cc/playground/Code/HoldButton current = digitalRead (PinTaster); if (current == LOW && previous == HIGH && millis() - firstTime > 200) { firstTime = millis(); // wenn Taste gedrueckt, Zeit merken if (count == 0) { lcd.clear(); lcd.setCursor (0, 0); lcd.print ("Gebe-Geschwindigkeit"); lcd.setCursor (0, 1); lcd.print ("festlegen"); } } if (current == LOW && ((millis() - firstTime) % 1000) < 20 && millis() - firstTime > 500) { if (count >= 1) { lcd.clear(); lcd.setCursor (0, 0); lcd.print ("Betriebsparameter"); lcd.setCursor (0, 1); lcd.print ("festlegen"); } count++; // Zaehler jede Sekunde inkrementieren } if (current == HIGH && previous == LOW && count >=0 && count < 1) { chooseSpeed(); // Taste <1 Sekunde gedrueckt } if (current == HIGH && previous == LOW && count >=1) { chooseOutput(); // Taste >=1 Sekunde gedrueckt } if (current == HIGH && previous == LOW && count >=2) { chooseOutput2(); // Taste >=2 Sekunde gedrueckt lcd.clear(); lcd.setCursor (0, 0); } if (current == HIGH) { count = 0; // Taste nicht gedrueckt, dann Zaehler resetten } previous = current; // Status der Taste uebernehmen // Ende Tasten-Abfrage if (!digitalRead (PinPunkt)) { getastet = true; Morsen (1); } if (!digitalRead (PinStrich)) { getastet = true; Morsen (3); } if (Serial.available()) { Konsole = Serial.read(); if ((Konsole >= 97) && (Konsole <= 122)) Konsole -= 32; // toUpperCase Grossbuchstaben if (Konsole > 122) Konsole = 32; MorseZeichen (Konsole); } // Buchstaben-Pause if ((millis() - ZeitVergangen > Periode * 2) && (getastet == true) || (anzahlZeichen == 7)) { Gegeben[anzahlZeichen + 1] = '\0'; for (byte i=0; i < 57; i++) { strcpy_P(buffer, (char*)&MorseLookup[i]); if (strcmp (buffer, Gegeben) == 0) { gefunden = true; Klartext += char(i+39); if (useCod) { // if (Wert2 == 1) { Klartext += " "; // Wenn diese Zeile, dann haben die Buchstaben Abstand // 20120226 } } } if (!gefunden) { Klartext += "# "; } Code += " "; for (byte i=0; i <= anzahlZeichen - 2; i++) { if (useCod) { // if (Wert2==1) { Klartext += " "; // Wenn diese Zeile, dann haben die Buchstaben Abstand (siehe oben die eine Zeile) // 20120226 } } displayMorsezeichen(); anzahlZeichen = 0; for (byte i=0; i < sizeof(Gegeben) - 1; i++) { // jede Stelle der Variable auf Null Gegeben[i] = '\0'; } getastet = false; gefunden = false; pause = false; } // Wort-Pause if ((millis() - ZeitVergangen > Periode * 5) && (!pause)) { Code += " "; if (useCod) { // if (Wert2 == 1) { Klartext += " "; } displayMorsezeichen(); pause = true; } } } |