.................... #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;
    }
  }
}




Nach oben
Top