Char Zeichenfolge mit Seriellem Monitor einlesen und anzeigen

Hallo, ich hab Probleme mit meinem Scetch, ich würde gerne, nach dem ich den Sketch hochgeladen hab den Seriellen Monitor öffnen, hier sollte der mit Serial.println("Zeichenfolge eingeben z.B. 12345678"); erzeugte Text erscheinen. In der Folge möchte ich eine bis zu zwanzig Zeichenfolge mit Serial.read einlesen der Variable "Zeichenfolge" zuordnen und anschliesend mit Serial.println(Zeichenfolge); am Seriellen Monitor anzeigen.
Ich bekomm da immer die Fehlermeldung: return-statement with a value, in function returning 'void' [-fpermissive].

Ich würde mich sehr freuen, wenn mir hier jemand helfen könnte.

void setup() {
  Serial.begin(9600);
}
void loop() {
  Serial.println("Zeichenfolge eingeben z.B. 12345678");
  char Zeichenfolge[20];  
  int i = 0;
  while (1) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      if (inChar == '\n') {
        Zeichenfolge[i] = '\0';
        Serial.flush();
        return 0;
      }
      if (inChar != '\r') {
        Zeichenfolge[i] = inChar;
        i++;
      }
    }
  }
  Serial.println(Zeichenfolge);
}

Sie deklarieren eine Funktion, die nichts zurückgibt (void)

und möchten dann ein int zurückgeben?

Dieser post auf Englisch könnte nützlich sein ➜ Serial Input Basics

Bitte poste Code grundsätzlich in Code-Tags. Das macht das Lesen des Codes - und damit das Helfen - wesentlich einfacher. Am einfachsten Du kopierst den Code in der IDE über Bearbeiten->Für Forum kopieren . Dann sind die Codetags dabei.
Du kannst auch deinen Eingangspost korrigieren, indem Du den Code markierst, und dann in der Buttonleiste über dem Text </> drückst.

Wozu überhaupt eine Endlosschleife? loop() ist doch bereits deine Endlosschleife - eine weitere brauchst Du nicht.

Formatiere den sketch besser

Serial.println(Zeichenfolge); ist in der Falschen geschwungenen Klammer. Er ist außerhalb der While(1) und wird darum nie ausgeführt.

"Serial.println("Zeichenfolge eingeben z.B. 12345678");" gehört in die setup

Grüße Uwe

Hallo, recht herzlichen Dank für euer Interesse mir zu helfen.
Hallo MicroBahner, tut mir leid, dass ich den Code nich richtig eingefügt hab, ich bin heute zum ersten mal hier im Forum. Ich füg ihn nochmal ein mit "Für Forum kopieren".

Mein Problem ist ja, dass ich eine Zeichenfolge nur dann, einmal, einlesen und der Variabel
"Zeichenfolge" zuweisen möchte solange Serial.available, also der Serielle Monitor geöffnet ist.
Ich hab deshalb versucht die Schleife mit return 0; für eine erneutes öffnen des Seriellen Monitors/Eingabe und Wertänderung der Var.-"Zeichenfolge" zurückzusetzen. Solange keine erneute Eingabe über den Seriellen Monitor erfolgt soll die Var.-"Zeichenfolge" ihren Wert in der Loop-Schleife behällt.

void setup() {
  Serial.begin(9600);
}


void loop() {

Serial.println("Zeichenfolge eingeben z.B. 12345678");

  char Zeichenfolge[20];  

  int i = 0;
  while (1) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      if (inChar == '\n') {
        Zeichenfolge[i] = '\0';
        Serial.flush();        
      }

      if (inChar != '\r') {
        Zeichenfolge[i] = inChar;
        i++;
      }
    }
  }

 
  Serial.println(Zeichenfolge);
}

Hallo Uwefed, danke für deine Antwort,
wenn ich die Aufforderung zur Eingabe der Zeichenfolge : ```
Serial.println("Zeichenfolge eingeben z.B. 12345678"); im Setup steht, wird die Aufforderung nur ein mal während des Programmstart ausgeführt und ist im Loop-Programmablauf nicht mehr möglich, ich muß aber im Loop den Wert der Var.-Zeichenfolge ändern können.

Serial.println(Zeichenfolge); hab ich schon an mehreren Positionen probiert aber ich bekom nur
z.B. Zeilenfolge ist 12345
dann erhalteich im Serial Monitor die Ausgabe entweder:
Zeichenfolge eingeben z.B. 12345678
12345
12345
12345
usw.
oder wenn ich ```
Serial.println(Zeichenfolge);
wie dargestellt in der vorletzten Zeile aufrufe, keine Anzeige?

Wie gesagt, loop ist deine Schleife, Du brauchst keine weitere. Versuch's mal so:

void setup() {
    Serial.begin(9600);
}

int i = 0;
bool aufforderungEingeben = true;
char Zeichenfolge[20];

void loop() {
    if ( aufforderungEingeben ) {
        Serial.println("Zeichenfolge eingeben z.B. 12345678");
        aufforderungEingeben = false;
    }
    if (Serial.available() > 0) {
        char inChar = Serial.read();
        if (inChar == '\n') {
            Zeichenfolge[i] = '\0';
            Serial.println(Zeichenfolge);
            aufforderungEingeben = true;
            i = 0;
        } else {
            if (inChar != '\r' ) {
                Zeichenfolge[i++] = inChar;
            }
        }
    }
}

Verstehst Du wie das ohne innere Schleifen abläuft?

Hallo MicroBahner, auch dir recht herzliches Danke für dein Interesse und Bemühen mir zu helfen und ich möchte deine Aufmerksamkeit auch nicht überstrapazieren.
Ich hab dein Sketch hochgeladen, der funktioniert bei mir leider nicht, am Seriellen Monitor keinerlei Anzeige.
Im Prinzip verstehe ich deine Programmablauf den du mit bedingten if-Verzweigungen aufgebaut hast, danke.

Was hast Du denn für einen Arduino? Ich habe das auf einen Nano hochgeladen, und da funktioniert es problemlos.
Letzendlich baut es ja komplett auf deinem Code auf, nur dass ich die inneren Schleifen alle aufgelöst habe.

Da hast du einen Denkfehler...

Hallo MicroBahner, danke für dein Schreiben. Also das Problem ist etwas Komplex. Vorab möchte ich erwähnen, dass ich schon seit Jahren kleinere Projekte für mich privat mit verschiedenen Arduino's realisiere. Da ich das System Arduino für mich eher als Werkzeug nutze war mein bisheriges vorgehen immer so, dass ich einen Arduino und die entsprechende Sensoren, Shields, Motoren usw. kaufte, die entsprechende Bibliotheken installierte und dann die beiliegenden Beispiel-Sketche für meine Anwendung anpasste. Meine Informatikkenntnis basiert darauf dass ich für mich beruflich gelegentlich EXCEL-Tabellen mit VBA programmiere. Na ja, wenn man etwas eben nur gelegentlich macht ist auch die Kenntnis entsprechend.
Jetzt hab ich mich an ein etwas komplexeres Projekt gewagt. Da unser Haus mit Gas beheizt wird möchte ich ein Arduino mit entsprechendem Gas-Sensor im Heizraum verbauen der mir im Fall dass Gas austritt eine SMS auf mein Handy sendet. Für das Projekt hab ich einen Arduino-MKR-GSM-1400 gekauft, mit entsprechendem Sensor, Antenne, Akku und Gehäuse. Der MKR-GSM-1400 ist schon richtig teuer. Nun hab ich das Board und die entsprechende Bibliotheken installiert und wollte das beiliegende Beispiel: MKRGSM/SendSMS nutzen, das läuft auch alles ganz gut an, alles wird erkannt und GSM wird auch initialisiert und der Text "Enter a mobile number:" angezeigt, nur beim eingebeb der Ziel-Mobil-Telefonnummer wird diese nicht übernommer, hier gibt es das Eingabeproblem. Ich hab dir mal den Beispiel-Sketch: SendSMS angefügt.

/*
 SMS sender

 This sketch, for the MKR GSM 1400 board,sends an SMS message
 you enter in the serial monitor. Connect your Arduino with the
 GSM shield and SIM card, open the serial monitor, and wait for
 the "READY" message to appear in the monitor. Next, type a
 message to send and press "return". Make sure the serial
 monitor is set to send a newline when you press return.

 Circuit:
 * MKR GSM 1400 board
 * Antenna
 * SIM card that can send SMS

 created 25 Feb 2012
 by Tom Igoe
*/

// Include the GSM library
#include <MKRGSM.h>

#include "arduino_secrets.h" 
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[] = SECRET_PINNUMBER;

// initialize the library instance
GSM gsmAccess;
GSM_SMS sms;

void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("SMS Messages Sender");

  // connection state
  bool connected = false;

  // Start GSM shield
  // If your SIM has PIN, pass it as a parameter of begin() in quotes
  while (!connected) {
    if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
      connected = true;
    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("GSM initialized");
}

void loop() {

  // enter mobile number
  Serial.print("Enter a mobile number: ");
  char remoteNum[20];  // telephone number to send sms
  readSerial(remoteNum);
  Serial.println(remoteNum);

  // sms text
  Serial.print("Now, enter SMS content: ");
  char txtMsg[200];
  readSerial(txtMsg);
  Serial.println("SENDING");
  Serial.println();
  Serial.println("Message:");
  Serial.println(txtMsg);

  // send the message
  sms.beginSMS(remoteNum);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nCOMPLETE!\n");
}


int readSerial(char result[]) {      // Read input serial
  int i = 0;
  while (1) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      if (inChar == '\n') {
        result[i] = '\0';
        Serial.flush();
        return 0;
      }
      if (inChar != '\r') {
        result[i] = inChar;
        i++;
      }
    }
  }
}

Ich hab nun versucht das Problem zu lokalisieren und vermute dieses im Unterprogramm "int readSerial(char result[])", wie du siest ist der Code für einen Laien schon nicht ganz einfach, das Hauptproblem ist wohl "return 0".
Dann hab ich versucht die Funktion des Unterprogramm in ein eigenständiges kleines Sketch zu schreiben mit dem ich mich an Dich/Euch wandte, da ich es einfach nicht zum laufen bekomme.
Das Sketch soll wenn ich es ausführe und den Seriellen Monitor öffne die Aufforderung zur eingabe einer Zeichenfolde anzeigen. Nun die Zeichenfolge eintragen und mit Send oder Return übernommen, darauf hin sollte die eingegebene Zeichenfolge unterhalb der Eingabeaufforderung dargestellt und der entsprechenden Variabel zugeordnet sein.
Da der MKR-GSM-1400 nicht billig war und ich diesen gerne nutzen möchte bin ich für jede Hilfe hierzu sehr sehr dankbar.

Ok, das ist schonmal was ganz anderes. Es ist immer gut, wenn man im Ausgangspost den verwendeten Arduino angibt. Da gibt es ja inzwischen eine ganze Menge, und wenn nichts angegeben wird, geht man halt von den 'standard'-Arduinos ( UNO/Nano) aus.
Nun habe ich so ein Board nicht, und dementsprechend auch keinerleic Erfahrung damit.

Da muss man dann schon ein paar Dinge beachten :wink: . Bei Boards mit nativem USB-Port ist wichtig, dass man nach dem Serial.begin auf den Aufbau der Verbindung wartet, wie das in dem Beispielsketch ja auch gemacht wird:

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

Sonst funktioniert hinterher die serielle Schnittstelle mit hoher Wahrscheinlichkeit nicht.
Und in der Tat, durch das return 0; kann man den Code nicht so einfach nach loop verpflanzen, sondern sollte in einer eigenen Funktion bleiben. Wobei die Funktion readSerial() mMn nicht gerade als Vorbild dienen sollte - um es mal vorsichtig auszudrücken :slight_smile: Dass readSerial() während der Eingabe blockierend ist, muss bei dem Aufbau des Beispiels wohl so bleiben.

Woran merkst DU , dass die Nummer nicht übernommen wird?
Ich habe dein Beispiel mal einfach umd die GSM-Teile 'entschlackt', dass nur noch das Lesen und Ausgeben über die serielle Schnittstelle bleibt, und auf einem Leonardo mit nativem USB getestet:

/*
 SMS sender

 This sketch, for the MKR GSM 1400 board,sends an SMS message
 you enter in the serial monitor. Connect your Arduino with the
 GSM shield and SIM card, open the serial monitor, and wait for
 the "READY" message to appear in the monitor. Next, type a
 message to send and press "return". Make sure the serial
 monitor is set to send a newline when you press return.

 Circuit:
 * MKR GSM 1400 board
 * Antenna
 * SIM card that can send SMS

 created 25 Feb 2012
 by Tom Igoe
*/

void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("SMS Messages Sender");

  Serial.println("Test initialized");
}

void loop() {

  // enter mobile number
  Serial.print("Enter a mobile number: ");
  char remoteNum[20];  // telephone number to send sms
  readSerial(remoteNum);
  Serial.println(remoteNum);

  // sms text
  Serial.print("Now, enter SMS content: ");
  char txtMsg[200];
  readSerial(txtMsg);
  Serial.println("SENDING");
  Serial.println();
  Serial.println("Message:");
  Serial.println(txtMsg);

  /* send the message
  sms.beginSMS(remoteNum);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nCOMPLETE!\n");*/
}


int readSerial(char result[]) {      // Read input serial
  int i = 0;
  while (1) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      if (inChar == '\n') {
        result[i] = '\0';
        Serial.flush();
        return 0;
      }
      if (inChar != '\r') {
        result[i] = inChar;
        i++;
      }
    }
  }
}

Ergibt im seriellen Monitor:

SMS Messages Sender
Test initialized
Enter a mobile number: 0170123456789
Now, enter SMS content: SENDING

Message:
Zu sendende SMS-Nachricht
Enter a mobile number:

P.S. noch ein HInweis zum seriellen Monitor bei Boards mit nativer Schnittstelle: Der serielle Monitor ist nicht in der Lage die USB Verbindung automatisch neu aufzubauen, nachdem er sie einmal verloren hat. Bei Boards mit serieller Schnittstelle wird die USB Verbingung aber erstmal unterbrochen, wenn man da ein Reset macht. Danch geht deshalb auf dem seriellen Monitor erstmal gar nichts mehr. Den musst Du nach einem manuellen Board-Reset neu starten.

Weitere Schleifen sind - so wie meistens verwendet - sogar schlecht. Anfänger denken meistens nicht daran wie langsam die serielle Schnittstelle ist und meinen das wird in einem Rutsch gesendet.
Praktisch bricht eine while available() Schleife aber sofort nach dem ersten Zeichen ab wenn es sonst zu keine Verzögerungen kam

Hallo MicroBahner, danke für dein schreiben und Verständnis, hättest ja auch sagen können solche Projekte sind nur für Profis, aber ich denke die Arduino-Welt soll eine Brücke sein um einen erleichterten Zugang zur Elektronik/Informatik auch für Laien zu sein.
Zu deiner Frage "Woran merkst DU , dass die Nummer nicht übernommen wird?"
Nach dem ich den Original-Sketch: SendSMS hochgeladen hab und den Seriellen Monitor öffne kommt sofort in der ersten Zeile "SMS Messages Sender" und nach etwa 15 Sekunden in der zweiten Zeile "GSM initialized" und in der dritten Zeile nahezu zeitgleich "Enter a mobile number:". Wenn ich nun eine Zahlenreihe zB. meine Handynummer eingebe und mit Senden oder mit Return übergebe werden die eingegebenen Zeichen(Handynummer) nicht angezeigt und
auch die Textzeilen wie "Now, enter SMS conect:" , "Sending", "Message" usw. werden nicht angezeigt, also endet das Sketch beim übergeben der Handynummer?

Ich hab auch dein editierten Sketch hochgeladen, dazu danke für deine Mühe, und wenn ich den Seriellen Monitor öffne die erste Zeile mit "SMS Message Sender" in der zweiten Zeile " Test initialized" und in der dritten Zeile die Eingabeaufforderung "Enter a mobile number:" aber auch hier und egal wie ich meine Handynummer übergebe ob Senden oder Return, das Sketch läuft nicht in die nächsten Schritte.

Was hast Du beim seriellen Monitor als Zeilenendezeichen eingestellt? Da muss auf jeden Fall 'Neue Zeile (NL)' dabei sein. Sonst wird das Ende der Eingabe nicht erkannt.

Hallo MicroBahner, schon vorweg, das war das Problem, bei mir hatte ich "kein Zeilenende" ausgewählt. Nach dem ich auf "Neue Zeile" umgestellt hab läuft der Sketch, klasse!
Ich freu mich wie Bolle dass es funktioniert und ich freue mich dich im Forum getroffen zu haben denn ohne deine Hilfsbereitschaft währe ich wohl noch immer orientierungslos auf Fehlersuche.
Also recht herzliches Danke für dein Interesse und deine Bereitschaft mit Sachverstand zu helfen, Danke. :+1:

Super, freut mich, dass ich dir helfen konnte :sunglasses:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.