[gelöst]Problem mit Morsestation

Guten Tag,

wir haben ein Problem mit unserem Projekt.
Es handelt sich um eine Morsestation, bestehend aus einem Arduino Uno, einem LCD-Dislpay(16x2), einem Laser-Modul, einem Speaker(Piezo) und drei Tastern.

Über Taster 1 lassen sich alle Buchstaben des Alphabets nacheinander durchschalten
(angezeigt in Zeile 1 des LCDs), Taster 2 dient zum
einlocken des gewählten Buchstabens in der unteren Zeile des LCDs und schiebt den Cursor danach um eine Stelle nach rechts.

Am Ende soll dort das gewünschte Wort stehen, welches im nächsten Schritt über Taster 3 zum Morsen freigegeben wird.

Laser und Speaker führen dann die im Switch Case hinterlegten Morsecodes aus.

Dies funktioniert problemlos, solange das eingegebene Wort nicht mehr als fünf Stellen hat.
Sobald ein Wort sechs Buchstaben oder mehr hat, werden schon ab der ersten Stelle nur noch die Lasersignale übertragen, Ton vom Speaker jedoch nicht.

Da dieses Problem sehr speziell ist, konnten wir über Google noch keine Lösung finden, hoffen nun aber hier Hilfe finden zu können.

Bitte habt Rücksicht mit unserem Code, wir sind keine Programmierer sondern blutige Anfänger.

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

int x = 0;
int s = 0;
int schalterPin6 = 6;
int schalterPin8 = 8;
int schalterPin9 = 9;
int laserpin = 7;
int speaker = 10;
static char t[16];

void setup() {
  // set up the LCD's number of columns and rows:
  Serial.begin(9600);
  pinMode(schalterPin6, INPUT);
  pinMode(schalterPin8, INPUT);
  pinMode(schalterPin9, INPUT);
  pinMode(laserpin, OUTPUT);
  pinMode(speaker, OUTPUT);
  lcd.begin(16, 2);
}

void loop() {

  int schalterBuchstWechs = digitalRead(schalterPin6);
  int schalterBuchstLogin = digitalRead(schalterPin8);
  int schalterBuchstSend =  digitalRead(schalterPin9);
  
  lcd.setCursor(0, 0);
  char alphabet[26] = "";
  alphabet[0] = 'a';
  alphabet[1] = 'b';
  alphabet[2] = 'c';
  alphabet[3] = 'd';
  alphabet[4] = 'e';
  alphabet[5] = 'f';
  alphabet[6] = 'g';
  alphabet[7] = 'h';
  alphabet[8] = 'i';
  alphabet[9] = 'j';
  alphabet[10] = 'k';
  alphabet[11] = 'l';
  alphabet[12] = 'm';
  alphabet[13] = 'n';
  alphabet[14] = 'o';
  alphabet[15] = 'p';
  alphabet[16] = 'q';
  alphabet[17] = 'r';
  alphabet[18] = 's';
  alphabet[19] = 't';
  alphabet[20] = 'u';
  alphabet[21] = 'v';
  alphabet[22] = 'w';
  alphabet[23] = 'x';
  alphabet[24] = 'y';
  alphabet[25] = 'z';

  if (schalterBuchstWechs == HIGH)
  {
    delay(250);
    x = x + 1;
    if (x > 25)
    {
      x = 0;
    }
    
  }

  lcd.print(alphabet[x]);

  if (schalterBuchstLogin == HIGH)
  {

    lcd.setCursor(s, 2);
    lcd.print(alphabet[x]);
    t[s] = alphabet[x] ;
    Serial.print(t[0]);
    s = s + 1;
    delay(250);
  }

if (schalterBuchstSend == HIGH)
  {
  for (int i=0;i<s;i++)
 { 
   // t[i] = alphabet[x] ;
    //int l = t[i];

    switch (t[i]) {
    
    case 'a': 
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(100);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(100);
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(300);
    digitalWrite(7, LOW);
    noTone(10);
    delay(300); 
      break;
      
    case 'b':
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(300);
    digitalWrite(7, LOW);
    noTone(10);
    delay(100);
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(100);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(100);
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(100);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(100);
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(100);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(300);
      break;
      
    case 'c':
    
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(300);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(100);
    // dot
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(100);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(100);
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(300);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(100);
    // dot
    digitalWrite(7, HIGH);
    tone(10,1000);
    delay(100);
    
    digitalWrite(7, LOW);
    noTone(10);
    delay(300);
      break;
      
  // [...] bis zum Buchstaben Z (siehe Anhang für *.ino File)
      
  }
  
  }
  }

}

MfG Termi

Morse28_07_.ino (13.3 KB)

Das hat möglicherweise nicht unbedingt etwas mit dem eigentlichen Problem zu tun, aber:

lcd.setCursor(s, 2);

schreibt bei der LCD-Library, die ich benutze* in die 3. Zeile des LCD (denn die Zählung beginnt bei 0).
Du verwendest ein LCD mit nur 2 Zeilen... Besser wäre deshalb wohl:

lcd.setCursor(s, 1);
Serial.print(t[0]);

Gibt im Seriellen Monitor immer nur das erste gewählte Zeichen aus.
Richtiger wäre wohl:

Serial.print(t[s]);

*) kann natürlich sein, dass die Library, die du verwendest das anders handhabt - glaube ich aber nicht, denn weiter oben steht
lcd.setCursor(0, 0);

Danke uxomm für den:

uxomm:

Serial.print(t[0]);Serial.print(t[s]);

... hät' ich vermutlich übersehen. Das LCD hab ich auch als erstes gehabt...

termi999:
Sobald ein Wort sechs Buchstaben oder mehr hat, werden schon ab der ersten Stelle nur noch die Lasersignale übertragen, Ton vom Speaker jedoch nicht.

Gut gemeinter Rat: Du prüfst die Tasten auf HIGH
Das mag gehen, aber es ist störanfällig.
Mach das anders rum, indem Du auf LOW prüfst.
Der PIN geht dann über den Taster nach GND
UND: die PIN ohne externen Widerstand mit pinMode(SchalterPin, INPUT_PULLUP) initialisieren.

Ich hab mal ein wenig umgebaut; Noch mit Prüfung auf HIGH aber mit geändertem LCD.
Alllerdings habe ich kein Board bei, um das zu testen.
Versuch es einfach.

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd (rs, en, d4, d5, d6, d7);

int x = 0;
int s = 0;
int schalterPin6 = 6;
int schalterPin8 = 8;
int schalterPin9 = 9;
int laserpin = 7;
int speaker = 10;
char t[16];
char alphabet[] = {"abcdefghijklmnopqrstuvwxyz"};

void setup()
{
  // set up the LCD's number of columns and rows:
  Serial.begin (9600);
  pinMode (schalterPin6, INPUT);
  pinMode (schalterPin8, INPUT);
  pinMode (schalterPin9, INPUT);
  pinMode (laserpin, OUTPUT);
  pinMode (speaker, OUTPUT);
  lcd.begin (16, 2);
  lcd.setCursor (0, 0);
}

void kurz()
{
  digitalWrite (7, HIGH);
  tone (10, 1000);
  delay (100);
  digitalWrite (7, LOW);
  noTone (10);
  delay (100);
}

void lang()
{
  digitalWrite (7, HIGH);
  tone (10, 1000);
  delay (300);
  digitalWrite (7, LOW);
  noTone (10);
  delay (300);
}

void loop()
{
  int schalterBuchstWechs = digitalRead (schalterPin6);
  int schalterBuchstLogin = digitalRead (schalterPin8);
  int schalterBuchstSend =  digitalRead (schalterPin9);
  if (schalterBuchstWechs == HIGH)
  {
    lcd.setCursor (0, 0);
    lcd.print (alphabet[x]);
    x++;
    if (x > 25)
    {
      x = 0;
    }
    delay (250);
  }
  if (schalterBuchstLogin == HIGH)
  {
    lcd.setCursor (s, 1);
    lcd.print (alphabet[x]);
    t[s] = alphabet[x] ;
    Serial.print (t[s]);
    s++;
    if (s > 15)
    {
      s = 0;
    }
    delay (250);
  }
  if (schalterBuchstSend == HIGH)
  {
    for (int i = 0; i < s; i++)
    {
      // t[i] = alphabet[x] ;
      //int l = t[i];
      Serial.println (i);
      Serial.println (s);
      switch (t[i])
      {
// *INDENT-OFF*
       case 'a':kurz();lang();break;
       case 'b':lang();kurz();kurz();kurz();break;
       case 'c':lang();kurz();lang();kurz();break;
       case 'd':lang();kurz();kurz();break;
       case 'e':kurz();break;
       case 'f':kurz();kurz();lang();kurz();break;
       case 'g':lang();lang();kurz();break;
       case 'h':kurz();kurz();kurz();kurz();break;
       case 'i':kurz();kurz();break;
       case 'j':kurz();lang();lang();lang();break;
       case 'k':lang();kurz();lang();break;
       case 'l':kurz();lang();kurz();kurz();break;
       case 'm':lang();lang();break;
       case 'n':lang();kurz();break;
       case 'o':lang();lang();lang();break;
       case 'p':kurz();lang();lang();kurz();break;
       case 'q':lang();lang();kurz();lang();break;
       case 'r':kurz();lang();kurz();break;
       case 's':kurz();kurz();kurz();break;
       case 't':lang();break;
       case 'u':kurz();kurz();lang();break;
       case 'v':kurz();kurz();kurz();lang();break;
       case 'w':kurz();lang();lang();break;
       case 'x':lang();kurz();kurz();lang();break;
       case 'y':lang();kurz();lang();lang();break;
       case 'z':lang();lang();kurz();kurz();break;
        default:break;
// *INDENT-ON*
      }
    }
    s = 0;
    x = 0;
  }
}

(deleted)

(deleted)

Peter-CAD-HST:
Das ist eine smarte Lösung Damen hoch :slight_smile:

Nun fehlt noch der Abstand zwischen Wörtern.

Ach smart wäre anders.
Dann müsste die Zeile:

if (x > 25)

als erstes geändert werden in:

if (x>=sizeof(alphabet))

Weiterhin müsste bei der Übernahme des Buchstaben x wieder auf 0 und nicht erst beim senden.

Dann könnte im Alphabet ein " " stehen und es wäre ein zusätzliches case für die Wortpause.

Zudem ist mein lang() nicht richtig. Er macht da ein Buchstabenende draus.

Der OP sollte ja nur mal testen, ob das auch funktioniert mit mehr als 5 Zeichen.

73 de Peter, es gd dx

Ich musste jetzt blank nachschlagen :wink:

Ach, meine letzte QSL-Karte stammt IMHO aus '91 und nur CB-Funk ...

[edit - wenn der OP hier noch mitliest:]
Kleine Änderungen zum nacharbeiten.

Zeile 46 alt:
delay (300);
Zeile 46 neu:
delay (100);

Zeile 58 alt:
if (x > 25)
Zeile 58 neu:
if (x>=sizeof(alphabet));

Zwischen Zeile 117 und 118
alt:
}
}

neu:
}
delay(200);
}
[/edit]

Peter-CAD-HST:
Nun fehlt noch der Abstand zwischen Wörtern.
Der Abstand zwischen Wörtern ist sieben Punkte lang, manchmal aber auch nur 5-6 Punkte.

Nochmal komplett überarbeitet - sollte eigentlich passen.

/*
   Forumsketch - Morsezeichen ausgeben
   https://forum.arduino.cc/index.php?topic=697732.msg4689745#msg4689745
*/

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd (rs, en, d4, d5, d6, d7);

const int schalterPin6 = 6;
const int schalterPin8 = 8;
const int schalterPin9 = 9;
const int laser = 7;
const int speaker = 10;
const int dit = 100;  // Millisekunden eines Taktes
unsigned int x = 0;
unsigned int s = 0;
char t[16];
char alphabet[] = {"abcdefghijklmnopqrstuvwxyz "}; // das letzte Zeichen ist ein Space

void setup()
{
  // set up the LCD's number of columns and rows:
  Serial.begin (115200);
  pinMode (schalterPin6, INPUT_PULLUP); // Taste reagiert auf LOW
  pinMode (schalterPin8, INPUT_PULLUP);
  pinMode (schalterPin9, INPUT_PULLUP);
  pinMode (laser, OUTPUT);
  pinMode (speaker, OUTPUT);
  lcd.begin (16, 2);
  lcd.setCursor (0, 0);
}

void sende (const char *Zeichen)
{
  int i = 0;
  //  while (Zeichen[i] != '\0') // prüft auf Ende der Zeichenkette
  while (isPrintable (
           Zeichen[i])) // bessere Variante prüft ob Zeichen druckbar
// *INDENT-OFF*
   {
    digitalWrite (laser, HIGH);
    tone (speaker, 1000);
    if (Zeichen[i] == '.') { delay (dit);}
    else if (Zeichen[i] == '-') { delay (dit * 3); }
      else { delay(dit); tone (speaker, 500); delay (dit); }
    digitalWrite (laser, LOW);
    noTone (speaker);
    delay (dit);
    i++;
   }
// *INDENT-ON*
}


void loop()
{
  int schalterBuchstWechs = digitalRead (schalterPin6);
  int schalterBuchstLogin = digitalRead (schalterPin8);
  int schalterBuchstSend =  digitalRead (schalterPin9);
  if (schalterBuchstWechs == LOW)
  {
    lcd.setCursor (0, 0);
    if (x >= sizeof (alphabet) - 1)
    {
      x = 0;
    }
    lcd.print (alphabet[x]);
    x++;
    delay (250);
  }
  if (schalterBuchstLogin == LOW)
  {
    lcd.setCursor (s, 1);
    lcd.print (alphabet[x]);
    t[s] = alphabet[x] ;
    s++;
    if (s > 15)
    {
      s = 0;
    }
    x = 0;
    delay (250);
  }
  if (schalterBuchstSend == LOW)
  {
    for (unsigned int i = 0; i <= s; i++)
    {
      switch (t[i])
      {
// *INDENT-OFF*
       case 'a': sende(".-");break;
       case 'b': sende("-...");break;
       case 'c': sende("-.-.");break;
       case 'd': sende("-..");break;
       case 'e': sende(".");break;
       case 'f': sende("..-.");break;
       case 'g': sende("--.");break;
       case 'h': sende("....");break;
       case 'i': sende("..");break;
       case 'j': sende(".---");break;
       case 'k': sende("-.-");break;
       case 'l': sende(".-..");break;
       case 'm': sende("--");break;
       case 'n': sende("-.");break;
       case 'o': sende("---");break;
       case 'p': sende(".--.");break;
       case 'q': sende("--.-");break;
       case 'r': sende(".-.");break;
       case 's': sende("...");break;
       case 't': sende("-");break;
       case 'u': sende("..-");break;
       case 'v': sende("...-");break;
       case 'w': sende(".--");break;
       case 'x': sende("-..-");break;
       case 'y': sende("-.--");break;
       case 'z': sende("--..");break;
       case ' ': delay(dit*5);break;
        default:break;
// *INDENT-ON*
      }
      delay (dit * 2);
    }
    s = 0;
    x = 0;
  }
}

@uxomm

schreibt bei der LCD-Library, die ich benutze* in die 3. Zeile des LCD (denn die Zählung beginnt bei 0).
Du verwendest ein LCD mit nur 2 Zeilen...

Da wäre ich mir nicht so sicher.

Ich kenne ein LCD Display das 1x16 ist aber programmtechnisch 2x8 organisiert ist.
Könnte es bei 2x18 auch geben.
Sicher sagen kann es nur der TO.

Grüße Uwe

Moin,

erstmal vielen Dank für die schnellen Antworten. Besonderen Dank an my_xy_projekt für die Mühe unseren gesamten Sketch umzuschreiben.

@uxomm

Danke für den Hinweis, macht Sinn ja. Hat aber trotzdem wie gewünscht bei uns funktioniert.
Wegen Serial.print(t[0]); statt Serial.print(t[s
das hatten wir nur genutzt, weil wir den ersten Wert im Array prüfen wollten. Haben wir vergessen rauszunehmen vor dem hochladen.

@Peter-CAD-HST

"Die Variable s wird nicht zurückgesetzt." Ja richtig, war erstmal so gedacht, da wir, nachdem ein Wort eingeben und gesendet wurde, den Arduino neustarten. Wir wollen uns aber noch einen eleganteren Weg zum resetten überlegen.

@my_xy_projekt

Haben gerade deinen umgebauten Sketch hochgeladen und getestet - gibt aber viele Probleme.

Mit der while (isPrintable(Zeichen*)), gibt es keine Ausgabe auf dem Bildschirm. Egal welchen Taster man drückt. Sowohl das durchschalten der Buchstaben, als auch das einlocken der gewünschten Buchstaben wird nicht angezeigt. Nachdem auskommentieren dieser while gibt es Ausgabe auf dem Bildschirm.*
Probleme:
startet man den Arduino wird auf dem Bildschirm zunächst nichts angezeigt. Drückt man den schalterBuchstLogin wird aber ein a eingespeichert. Drückt man schalterBuchstWechs zeigt er ein a auf dem Bildschirm an, drückt man den Taster weiter geht er wie gewünscht das Alphabet durch. Jedoch wird durch Druck des schalterBuchstLogin immer ein Buchstabe vorher eingespeichert. Er ist also um einen zurück.
Beim drücken von schalterBuchstSend "morst" er die ersten beiden Buchstaben, dann bricht er ab.
Jetzt zur guten Nachricht: haben das Buchstaben-Array aus dem Sketch von my_xy_projekt genommen und unseres dadurch ersetzt. Also statt
char alphabet[26] = "";

  • alphabet[0] = 'a';*
  • alphabet[1] = 'b';*
  • alphabet[2] = 'c';*
  • alphabet[3] = 'd';*
  • alphabet[4] = 'e';*
  • alphabet[5] = 'f';*
  • alphabet[6] = 'g';*
  • alphabet[7] = 'h';*
  • alphabet[8] = 'i';*
  • alphabet[9] = 'j';*
  • alphabet[10] = 'k';*
  • alphabet[11] = 'l';*
  • alphabet[12] = 'm';*
  • alphabet[13] = 'n';*
  • alphabet[14] = 'o';*
  • alphabet[15] = 'p';*
  • alphabet[16] = 'q';*
  • alphabet[17] = 'r';*
  • alphabet[18] = 's';*
  • alphabet[19] = 't';*
  • alphabet[20] = 'u';*
  • alphabet[21] = 'v';*
  • alphabet[22] = 'w';*
  • alphabet[23] = 'x';*
  • alphabet[24] = 'y';*
  • alphabet[25] = 'z';*
    nun
    char alphabet[] = {"abcdefghijklmnopqrstuvwxyz "};
    Und voila jetzt funktioniert alles wie gewünscht, er bricht nicht nach 5 gesendeten Buchstaben ab, sondern spielt bis zu 16 hintereinander ab. Super!
    Wir werden jetzt noch versuchen unser switch case zu kürzen, wie my_xy_projekt das getan hat.
    Kann sich jemand erklären warum nur die Änderung des Alphabet-Arrays schon die Lösung war? Wir sind verwirrt, aber glücklich das es jetzt wie gewünscht funktioniert.

Moin,

termi999:
"Die Variable s wird nicht zurückgesetzt." Ja richtig, war erstmal so gedacht, da wir, nachdem ein Wort eingeben und gesendet wurde, den Arduino neustarten. Wir wollen uns aber noch einen eleganteren Weg zum resetten überlegen.

Haben gerade deinen umgebauten Sketch hochgeladen und getestet - gibt aber viele Probleme.

Mit der while (isPrintable(Zeichen*)), gibt es keine Ausgabe auf dem Bildschirm. Egal welchen Taster man drückt. Sowohl das durchschalten der Buchstaben, als auch das einlocken der gewünschten Buchstaben wird nicht angezeigt. Nachdem auskommentieren dieser while gibt es Ausgabe auf dem Bildschirm.*
Probleme:
startet man den Arduino wird auf dem Bildschirm zunächst nichts angezeigt. Drückt man den schalterBuchstLogin wird aber ein a eingespeichert. Drückt man schalterBuchstWechs zeigt er ein a auf dem Bildschirm an, drückt man den Taster weiter geht er wie gewünscht das Alphabet durch. Jedoch wird durch Druck des schalterBuchstLogin immer ein Buchstabe vorher eingespeichert. Er ist also um einen zurück.
Beim drücken von schalterBuchstSend "morst" er die ersten beiden Buchstaben, dann bricht er ab.
[/quote]
Das mit der Var s hab ich im Sketch gelöst indem die nach dem Senden einfach resettet wird.
Die Probleme sind lösbar.
Die Übernahme des falschen Buchstaben habe ich schon gefunden. Hochgezählt wird x nach dem Tastendruck und steht dann bei der Übernahme 1 zuweit.
Das mit dem senden schau ich gleich nochmal drauf, was da passiert.
Ich bau mal ein paar Ausgaben auf dem seriellen Monitor ein und las das hier laufen.

my_xy_projekt:
Die Probleme sind lösbar.

Neue Version. Da ich heute wieder ein Board habe, konnte das auch ausprobiert werden...

geändert:

  • x wird mit der Größe des alphabet-array initialisiert. Dadurch wird beim ersten Tastendruck immer der Überlauf provoziert und x auf 0 gesetzt. Gleiches passiert nach dem senden.
  • das hochzählen von x geschieht mit dem Tastendruck vor der Ausgabe
  • wenn s überläuft, wird die Zeile gelöscht um Verwirrung zu vermeiden
  • ne Handvoll serieller Ausgaben zur Kontrolle
  • Nach dem Senden Reset der Variablen und löschen des Display
/*
   Forumsketch - Morsezeichen ausgeben
   https://forum.arduino.cc/index.php?topic=697732.msg4690410#msg4690410
*/

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd (rs, en, d4, d5, d6, d7);

const int auswahlPin = 6;
const int uebernahmePin = 8;
const int sendePin = 9;
const int laser = 7;
const int speaker = 10;
const int dit = 100;  // Millisekunden eines Taktes
unsigned int x;
unsigned int s = 0;
char t[16];
char alphabet[] = {"abcdefghijklmnopqrstuvwxyz "}; // das letzte Zeichen ist ein Space

void setup()
{
  Serial.begin (115200);
  pinMode (auswahlPin, INPUT_PULLUP);
  pinMode (uebernahmePin, INPUT_PULLUP);
  pinMode (sendePin, INPUT_PULLUP);
  pinMode (laser, OUTPUT);
  pinMode (speaker, OUTPUT);
  lcd.begin (16, 2);
  lcd.setCursor (0, 0);
  x = sizeof (alphabet); // initialisiert mit Gesamtlänge des Array
}

void sende (const char *Zeichen)
{
  int i = 0;
  Serial.print ("uebergebenes Zeichen: ");
  Serial.print (Zeichen);
  Serial.print (" / Sende: ");
  //  while (Zeichen[i] != '\0') // prüft auf Ende der Zeichenkette
  while (isPrintable (Zeichen[i])) // bessere Variante prüft ob Zeichen druckbar
// *INDENT-OFF*
   {
    Serial.print(Zeichen[i]);
    digitalWrite (laser, HIGH);
    tone (speaker, 1000);
    if (Zeichen[i] == '.') { delay (dit);}
    else if (Zeichen[i] == '-') { delay (dit * 3); }
      else { delay(dit); tone (speaker, 500); delay (dit); }
    digitalWrite (laser, LOW);
    noTone (speaker);
    delay (dit);
    i++;
   }
   Serial.println();
// *INDENT-ON*
}


void loop()
{
  int schalterBuchstWechs = digitalRead (auswahlPin);
  int schalterBuchstLogin = digitalRead (uebernahmePin);
  int schalterBuchstSend =  digitalRead (sendePin);
  if (schalterBuchstWechs == LOW)
  {
    x++;
    if (x >= sizeof (alphabet) - 1) // prüft ob x größer als Anzahl Zeichen im Array
    {
      x = 0;
    }
    lcd.setCursor (0, 0);
    lcd.print (alphabet[x]);
    delay (250);
  }
  if (schalterBuchstLogin == LOW)
  {
    t[s] = alphabet[x] ;
    lcd.setCursor (s, 1);
    lcd.print (t[s]);
    s++;
    if (s > 15)
    {
      s = 0;
      lcd.setCursor (s, 1);
      lcd.print ("                ");
    }
    Serial.print ("t ist ");
    Serial.println (t);
    delay (250);
  }
  if (schalterBuchstSend == LOW)
  {
    Serial.print ("Sende Zeichen ");
    Serial.println (s);
    for (unsigned int i = 0; i <= s; i++)
    {
      switch (t[i])
      {
// *INDENT-OFF*
       case 'a': sende(".-");break;
       case 'b': sende("-...");break;
       case 'c': sende("-.-.");break;
       case 'd': sende("-..");break;
       case 'e': sende(".");break;
       case 'f': sende("..-.");break;
       case 'g': sende("--.");break;
       case 'h': sende("....");break;
       case 'i': sende("..");break;
       case 'j': sende(".---");break;
       case 'k': sende("-.-");break;
       case 'l': sende(".-..");break;
       case 'm': sende("--");break;
       case 'n': sende("-.");break;
       case 'o': sende("---");break;
       case 'p': sende(".--.");break;
       case 'q': sende("--.-");break;
       case 'r': sende(".-.");break;
       case 's': sende("...");break;
       case 't': sende("-");break;
       case 'u': sende("..-");break;
       case 'v': sende("...-");break;
       case 'w': sende(".--");break;
       case 'x': sende("-..-");break;
       case 'y': sende("-.--");break;
       case 'z': sende("--..");break;
       case ' ': delay(dit*5);break;
        default:break;
// *INDENT-ON*
      }
      delay (dit * 2);
    }
    s = 0;
    x = sizeof (alphabet);
    lcd.clear();
  }
}

Ausgabe auf dem serMon:

10:52:54.869 -> t ist a
10:52:55.102 -> t ist aa
10:52:55.368 -> t ist aaa
10:52:59.964 -> t ist aaab
10:53:01.595 -> t ist aaabc
10:53:04.226 -> t ist aaabcd
10:53:08.789 -> t ist aaabcde
10:53:10.298 -> t ist aaabcdef
10:53:13.493 -> Sende Zeichen 8
10:53:13.493 -> uebergebenes Zeichen: .- / Sende: .-
10:53:14.293 -> uebergebenes Zeichen: .- / Sende: .-
10:53:15.095 -> uebergebenes Zeichen: .- / Sende: .-
10:53:15.894 -> uebergebenes Zeichen: -... / Sende: -...
10:53:17.095 -> uebergebenes Zeichen: -.-. / Sende: -.-.
10:53:18.494 -> uebergebenes Zeichen: -.. / Sende: -..
10:53:19.499 -> uebergebenes Zeichen: . / Sende: .
10:53:19.900 -> uebergebenes Zeichen: ..-. / Sende: ..-.

Moin my_xy_projekt,

danke für die schnelle Antwort.

Haben den Sketch gerade so ausprobiert,

folgende Probleme:

-Schalter auf LOW funktioniert nicht, nach Änderung auf HIGH in den ifs funktioniert es
-erster Durchlauf mit einem Wort mehrer Buchstaben funktioniert jetzt super
-er scheint jedoch das t-array bzw. die s-variable nicht richtig zu resetten, denn wenn man im Folgenden Durchgang ein kürzeres Wort nimmt, z.B. 4 Buchstaben statt vorher 5, nutzt er für die fünfte Stelle die vom vorherigen Wort

Edit:/ Haben den Fehler dafür gefunden:

for (unsigned int i = 0; i <= s; i++) muss
for (unsigned int i = 0; i < s; i++)

Läuft jetzt soweit sehr gut und sieht sehr viel schöner/schlanker aus, danke dafür my_xy_projekt. Auch die Ausgabe aufn seriellen Monitor ist ganz toll!

Noch ne Frage, weil wir da bissl aufm Schlauch stehen. Wir hätten gerne, dass der Bildschirm direkt nachm Arduino-Start, den ersten Buchstaben, also "a" anzeigt. Momentan ist es so, dass wir erst den auswahlPin drücke müssen, damit das a erscheint. Drückt man da dann direkt den uebernahmePin, zeigt er ein fehlerhaftes Symbol an.

termi999:
Noch ne Frage, weil wir da bissl aufm Schlauch stehen. Wir hätten gerne, dass der Bildschirm direkt nachm Arduino-Start, den ersten Buchstaben, also "a" anzeigt. Momentan ist es so, dass wir erst den auswahlPin drücke müssen, damit das a erscheint. Drückt man da dann direkt den uebernahmePin, zeigt er ein fehlerhaftes Symbol an.

Bei der Variablendeklaration aus

alt: unsigned int x;
neu: unsigned int x=0;

Im setup():

alt: x=sizeof(alphabet)
neu: auskommentieren:
und darunter einfügen:
neu: lcd.print (alphabet[x]);

im loop():
Den Teil am Ende:

x = sizeof (alphabet);
lcd.clear();

ersetzen durch:
x = 0;
lcd.clear();
lcd.setcursor(0,0);
lcd.print(alphabet[x])

Und da siehst Du schon, das es eigentlich sinnvoll wäre für den Start eine eigene Funktion zu schreiben.
Aber probier erstmal aus, ob es das ist, was Du willst.

termi999:
-Schalter auf LOW funktioniert nicht, nach Änderung auf HIGH in den ifs funktioniert es

Doch das geht, wenn Du mein erstes Post liest. Dazu muss Deine Schaltung umgebaut werden. Meine Aufbau funktioniert so.

Das prüfen auf HIGH birgt die Gefahr, das Dir ggfls. ne Neonröhre in die Schaltung spuckt. Sobald der Pegel am DigitalPin einen bestimmten Wert überschritten hat, weil Energie einstreut, meint der Code ein HIGH erkannt zu haben.
prüfst Du auf LOW, müsste jemand die Energie wegnehmen :wink:

my_xy_projekt:
Doch das geht, wenn Du mein erstes Post liest. Dazu muss Deine Schaltung umgebaut werden. Meine Aufbau funktioniert so.

Das prüfen auf HIGH birgt die Gefahr, das Dir ggfls. ne Neonröhre in die Schaltung spuckt. Sobald der Pegel am DigitalPin einen bestimmten Wert überschritten hat, weil Energie einstreut, meint der Code ein HIGH erkannt zu haben.
prüfst Du auf LOW, müsste jemand die Energie wegnehmen :wink:

Oh ja, entschuldige bitte, haben wir glatt übersehen. Den Aufbau werden wir morgen so mal testen.

my_xy_projekt:
Und da siehst Du schon, das es eigentlich sinnvoll wäre für den Start eine eigene Funktion zu schreiben.
Aber probier erstmal aus, ob es das ist, was Du willst.

Ja mit den Änderungen ist es jetzt genau wie gewünscht. Perfekt!

Nochmals vielen Dank für die schnelle Hilfe.

Grüße

termi999:
Ja mit den Änderungen ist es jetzt genau wie gewünscht. Perfekt!

Dann gibt es hier das vollständig mit Funktion fürs Display und kleiner Erweiterung im Sendeteil :slight_smile:
Brauchst nur noch die Zahlen ergänzen.

Viel Spass damit - und wenn ihr durch seit, geh ins erste Post und schreib zusätzlich ein Erledigt oder Gelöst in die Betreffzeile.

/*
   Forumsketch - Morsezeichen ausgeben
   https://forum.arduino.cc/index.php?topic=697732.msg4690561#msg4690561
*/

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd (rs, en, d4, d5, d6, d7);

const int auswahlPin = 6;
const int uebernahmePin = 8;
const int sendePin = 9;
const int laser = 7;
const int speaker = 10;
const int dit = 100;  // Millisekunden eines Taktes
unsigned int x;
unsigned int s = 0;
char t[16];
char alphabet[] = {"abcdefghijklmnopqrstuvwxyz "}; // das letzte Zeichen ist ein Space

void setup()
{
  Serial.begin (115200);
  pinMode (auswahlPin, INPUT_PULLUP);
  pinMode (uebernahmePin, INPUT_PULLUP);
  pinMode (sendePin, INPUT_PULLUP);
  pinMode (laser, OUTPUT);
  pinMode (speaker, OUTPUT);
  lcd.begin (16, 2);
  displaystart();
  }

void sende (const char *Zeichen)
{
  int i = 0;
  Serial.print ("uebergebenes Zeichen: ");
  Serial.print (Zeichen);
  Serial.print (" / Sende: ");
  //  while (Zeichen[i] != '\0') // prüft auf Ende der Zeichenkette
  while (isPrintable (Zeichen[i])) // bessere Variante prüft ob Zeichen druckbar
// *INDENT-OFF*
   {
    Serial.print(Zeichen[i]);
    digitalWrite (laser, HIGH);
    tone (speaker, 1000);
    if (Zeichen[i] == '.') { delay (dit);}
    else if (Zeichen[i] == '-') { delay (dit * 3); }
      else { delay(dit); tone (speaker, 500); delay (dit); }
    digitalWrite (laser, LOW);
    noTone (speaker);
    delay (dit);
    i++;
   }
   Serial.println();
// *INDENT-ON*
}

void displaystart()
{
  x = 0;
  lcd.clear();
  lcd.setCursor (0, 0);
  lcd.print (alphabet[x]);
}

void loop()
{
  int schalterBuchstWechs = digitalRead (auswahlPin);
  int schalterBuchstLogin = digitalRead (uebernahmePin);
  int schalterBuchstSend =  digitalRead (sendePin);
  if (schalterBuchstWechs == LOW)
  {
    x++;
    if (x >= sizeof (alphabet) - 1) // prüft ob x größer als Anzahl Zeichen im Array
    {
      x = 0;
    }
    lcd.setCursor (0, 0);
    lcd.print (alphabet[x]);
    delay (250);
  }
  if (schalterBuchstLogin == LOW)
  {
    t[s] = alphabet[x] ;
    lcd.setCursor (s, 1);
    lcd.print (t[s]);
    s++;
    if (s > 15)
    {
      s = 0;
      lcd.setCursor (s, 1);
      lcd.print ("                ");
    }
    Serial.print ("t ist ");
    Serial.println (t);
    delay (250);
  }
  if (schalterBuchstSend == LOW)
  {
    Serial.print ("Sende Zeichen ");
    Serial.println (s);
    sende("-.-.-"); // Spruchanfang
    for (unsigned int i = 0; i < s; i++)
    {
      switch (t[i])
      {
// *INDENT-OFF*
       case 'a': sende(".-");break;
       case 'b': sende("-...");break;
       case 'c': sende("-.-.");break;
       case 'd': sende("-..");break;
       case 'e': sende(".");break;
       case 'f': sende("..-.");break;
       case 'g': sende("--.");break;
       case 'h': sende("....");break;
       case 'i': sende("..");break;
       case 'j': sende(".---");break;
       case 'k': sende("-.-");break;
       case 'l': sende(".-..");break;
       case 'm': sende("--");break;
       case 'n': sende("-.");break;
       case 'o': sende("---");break;
       case 'p': sende(".--.");break;
       case 'q': sende("--.-");break;
       case 'r': sende(".-.");break;
       case 's': sende("...");break;
       case 't': sende("-");break;
       case 'u': sende("..-");break;
       case 'v': sende("...-");break;
       case 'w': sende(".--");break;
       case 'x': sende("-..-");break;
       case 'y': sende("-.--");break;
       case 'z': sende("--..");break;
       case ' ': delay(dit*5);break;
        default:break;
// *INDENT-ON*
      }
      delay (dit * 2);
    }
    sende(".-.-."); // Spruchende
    s = 0;
    displaystart();
  }
}

Sehr schön. Das mit Start und Ende wird uns jetzt auch helfen bei dem nächsten Projekt - eine Decoder-Station, die die gesendeten Lasersignale empfängt und übersetzt :smiley:

Sketch läuft 1A, lassen die Taster jetzt auch auf LOW prüfen(das ist ja viel einfacher). Danke für die Mühe,

Gruß

Termi

(deleted)

termi999:
Das mit Start und Ende wird uns jetzt auch helfen bei dem nächsten Projekt - eine Decoder-Station, die die gesendeten Lasersignale empfängt und übersetzt :smiley:

Hab' ich mir gedacht...

Peter-CAD-HST:
Moin termi999

und als nächstes Projekt ein Morsezeichen-Dekoder? :slight_smile:

Gruss Peter
und gesund bleiben

Moin Peter,

ja da setzen wir uns jetzt ran!

my_xy_projekt:
Hab' ich mir gedacht...

:smiley: :smiley: :smiley: