Seriell gesendeter Befehl funktioniert nicht wenn er über ESP8266 kommt

Hallo,
Ich bin noch ziemlich neu im Arduino Bereich und hoffe ihr könnt mir vielleicht bei einem Problem helfen, bei dem ich nicht weiter komme.
Konkret soll ein seriell eingegebenes Wort mit einem auf dem Arduino Uno hinterlegten Wort verglichen werden und wenn sie übereinstimmen wird eine Aktion ausgeführt.
Das ganze funktioniert auch, solange ich die Eingabe über USB Kabel und Seriellen Monitor mache.
Nun soll der Befehl aber drahtlos per WLAN geschickt werden. Ich habe dafür ein ESP8266 Modul angeschlossen, mit ESPLink bespielt und kann mich jetzt mit dem Netzwerk des ESP verbinden und über die Konsole mit dem Uno kommunizieren. Nur lösen die gleichen Worte, die per USB gesendet funktionieren, jetzt keine Aktion mehr aus und strcmp liefert bei Vergleich mit dem hinterlegten Befehl eine Zahl ungleich Null.

Der Code sieht aktuell so aus:

[code]
#include <Servo.h>                                                     // Servobibliothek einbinden
//#include <string.h>                                                    // String Bibliothek einbinden

#define A 2
#define B 3
#define C 4
#define D 5

#define E 6
#define F 7
#define G 11
#define H 12

#define ganze_drehung 10070                                            // 10336 Halfsteps für eine ganze Drehung des Roboters im Kreis
#define ger_lin 1000                                                   // Halfsteps, die gerade gefahren werden 

int halfstep_next = 0;

int halfstep_pattern[8][4] = {
  1, 0, 0, 0,
  1, 1, 0, 0,
  0, 1, 0, 0,
  0, 1, 1, 0,
  0, 0, 1, 0,
  0, 0, 1, 1,
  0, 0, 0, 1,
  1, 0, 0, 1
};

char Befehle[3][10] = {{"HVN"}, {"Vierecke"}, {"gerade"}};             // Worte, welche der Arduino kennt und mit der Eingabe über den Seriellen Port vergleichen kann

const int BUFFER_SIZE = 100;
char buf[BUFFER_SIZE];


//Servo Stiftheber;                                                      // Stiftheber wird Name, mit dem der Servo angesteuert wird







void setup() {
  //Stiftheber.attach(8);                                                // Servo hängt an Digital PIN 8

  Serial.begin(115200);                                                // Seriellen Port starten um über Bluetooth/WLAN zu kommunizieren; Datenrate 115200 bps (bits per second = Baudrate)-> geht nicht am Leonardo

  while (!Serial) {
    ;                                                                   // Warten bis der serielle Port eine Verbindung hat
  }

  Serial.println("Arduino ist bereit");                                 // Um direkt zu sehen ob eine Verbindung erfolgreich war


  pinMode(A, OUTPUT);                                                  // Alle Pins an denen die Stepper hängen geben OUTPUT Signale
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(E, OUTPUT);
  pinMode(F, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(H, OUTPUT);

  delay(5000);
}

void write(int a, int b, int c, int d, int x) {                         // Sendet die Zustände für den jeweils aktuellen Schritt an die Motortreiber
  int schreibarray[8];


  if (x == 0)                                                           // vorwärts
  {
    for (int i = 0; i < 8; i++)
    {
      if (i == 0 || i == 4)
        schreibarray[i] = a;
      if (i == 1 || i == 5)
        schreibarray[i] = b;
      if (i == 2 || i == 6)
        schreibarray[i] = c;
      if (i == 3 || i == 7)
        schreibarray[i] = d;
    }
  }

  if (x == 1)                                                           // rückwärts
  {
    for (int i = 0; i < 8; i++)
    {
      if (i == 0 || i == 4)
        schreibarray[i] = d;
      if (i == 1 || i == 5)
        schreibarray[i] = c;
      if (i == 2 || i == 6)
        schreibarray[i] = b;
      if (i == 3 || i == 7)
        schreibarray[i] = a;
    }
  }


  if (x == 2)                                                           // linksdrehung
  {
    for (int i = 0; i < 8; i++)
    {
      if (i == 0 || i == 7)
        schreibarray[i] = a;
      if (i == 1 || i == 6)
        schreibarray[i] = b;
      if (i == 2 || i == 5)
        schreibarray[i] = c;
      if (i == 3 || i == 4)
        schreibarray[i] = d;
    }
  }

  if (x == 3)                                                           // rechtsdrehung
  {
    for (int i = 0; i < 8; i++)
    {
      if (i == 3 || i == 4)
        schreibarray[i] = a;
      if (i == 2 || i == 5)
        schreibarray[i] = b;
      if (i == 1 || i == 6)
        schreibarray[i] = c;
      if (i == 0 || i == 7)
        schreibarray[i] = d;
    }
  }


  digitalWrite(A, schreibarray[0]);                                   // Motor 1
  digitalWrite(B, schreibarray[1]);
  digitalWrite(C, schreibarray[2]);
  digitalWrite(D, schreibarray[3]);


  digitalWrite(E, schreibarray[4]);                                   // Motor 2
  digitalWrite(F, schreibarray[5]);
  digitalWrite(G, schreibarray[6]);
  digitalWrite(H, schreibarray[7]);

}


void halfstep(int x)
{
  write(halfstep_pattern[halfstep_next][0], halfstep_pattern[halfstep_next][1], halfstep_pattern[halfstep_next][2], halfstep_pattern[halfstep_next][3], x);
  halfstep_next++;
  if (halfstep_next == 8)
    halfstep_next = 0;
  delay(1);
}



/*void heben()                                                           // heben den Stifts
  {
  Stiftheber.write(90);
  delay(300);
  }

  void senken()                                                           // senken den Stifts
  {
  Stiftheber.write(0);
  delay(300);
  } */

void rechts()                                                          // dreht den roboter um 90Grad nach rechts
{
  int i = 0;
  while (i < (ganze_drehung / 4)) {
    halfstep(3);
    i++;
  }
}

void re_45()                                                           // dreht 45 Grad nach rechts
{
  int i = 0;
  while (i < (ganze_drehung / 8)) {
    halfstep(3);
    i++;
  }
}

void li_45()                                                          // dreht 45 Grad nach links
{
  int i = 0;
  while (i < (ganze_drehung / 8)) {
    halfstep(2);
    i++;
  }
}

void links()                                                          // dreht den roboter um 90Grad nach links
{
  int i = 0;
  while (i < (ganze_drehung / 4)) {
    halfstep(2);
    i++;
  }
}

void gerade()                                                         // fährt die oben festgelegte Anzahl an Schritten geradeaus
{
  int i = 0;
  while (i < ger_lin) {
    halfstep(0);
    i++;
  }
}

void schraeg()                                                        // berechnet Anzahl der nötigen Schritte für den diagonalen Weg im inneren des Vierecks und fährt diese
{
  int i = 0;
  int j = sqrt(2) / 2 * ger_lin;
  while (i < j) {
    halfstep(0);
    i++;
  }
}


void HVN()  {                                                                 //  Haus vom Nikolaus
  gerade();
  rechts();
  gerade();
  rechts();
  gerade();
  rechts();
  gerade();
  rechts();
  re_45();
  schraeg();
  schraeg();
  links();
  schraeg();
  links();
  schraeg();
  links();
  schraeg();
  schraeg();
}

void Vierecke() {                                                           // Es werden Vierecke gezeichnet  -> hauptsächlich zu Testzwecken -> rechtsdrehung der Vierecke= zu viele Schritte für ganze Drehung angesetzt; linksdrehung = zu wenige
  for (int i = 0; i < 3; i++) {
    gerade();
    rechts();
    gerade();
    rechts();
    gerade();
    rechts();
    gerade();
    rechts();
  }
}






void loop() {

  //HVN();

  //delay(10000);




  if (Serial.available() > 0) {                                                                       // Test der seriellen Kommunikation
    memset(buf, 0, BUFFER_SIZE);                                                                      // Werte in buf auf 0 setzen
    int rlen = Serial.readBytesUntil('\n', buf, BUFFER_SIZE);                                         // ankommende Bytes lesen und länge speichern


    Serial.print("I received: ");                                                                     // ausgeben was angekommen ist
    for (int i = 0; i < rlen; i++)
      Serial.print(buf[i]);
    Serial.print("\n");


    Serial.print(strcmp(buf, Befehle[2]));                                                             //ausgabe des Ergebnisses von strcmp -> vergleich mit dem Wort "gerade"
    Serial.print("\n");


    if (strcmp(buf, Befehle[0]) == 0)
    {
      Serial.print("Das Haus vom Nikolaus wird gezeichnet");
      Serial.print("\n");
      HVN();
    }


    if (strcmp(buf, Befehle[1]) == 0)
    {
      Serial.print("Vierecke zum Testen der Zeichengenauigkeit werden gezeichent");
      Serial.print("\n");
      Vierecke();
    }

    if (strcmp(buf, Befehle[2]) == 0)
    {
      Serial.print("Eine Gerade Linie wird gezeichnet");
      Serial.print("\n");
      gerade();
    }
  }


}
[/code]

schickt denn dein "ESPLink" nach dem Befehl auch wirklich nur ein \n ... und nicht vieleicht ein \r\n oder eventuell gar kein Zeilenende?

Was gibt der Serielle Monitor zur Kontrolle aus?

Hallo,
ich rate jetzt mal, Du hast einen ESP8266-01 und den beim Uno an pin0 und pin1 angeschlossen und nutzt damit die serielle HW-Schnittstelle des Uno.
Du hast das richtig angeschlossen ? (überkreut und auf die Spannung geachtet) Du nutzt auf beiden Seiten die gleiche Geschwindigkeit ?
Das ist allerdings ein bisschen unglücklich da du nun mit dem Monitor nicht mehr kontrollieren kannst was vom ESP tatsächlich gesendet wird. Du kannst am Uno eine Softwareschnittstelle nutzten, das geht aber nur bis 9600 sicher.
Ich vermute ebenfalls das die Endzeichen unterschiedlich sind und nicht richtig abgefragt werden.
Heinz

dachte das wäre immer mit dem \n zu ende :see_no_evil:
wie finde ich denn raus welche Zeichen da am Ende ankommen?
Habe jetzt gerade mal ausgeben lassen wie lang rlen bei USB bzw. ESP ist und beim ESP ist es immer 1 Zeichen länger, also scheint da schon das ganze Problem zu liegen

Meintest du den Rückgabewert von strcmp? Der ist bei beiden Varianten beim gleichen Wort immer gleich, außer das Wort stimmte mit dem hinterlegten überein. Dann war es beim einen 0 und beim anderen 13.

nein. Bitte kopier den ganzen Seriellen Output raus, in beiden Varianten
a) wenn du es händisch eingibst und
b) was die Serielle Schnittstelle Ausgibt wenn der ESP den gleichen Befehl sendet (und dann nicht das richtige passiert.

Ja genau, das ist ein ESP8266-01S.
Ist an Pin 0 und 1 und über Kreuz mit dem ESP verbunden. Von Arduino zu ESP ist noch ein Spannungsteiler drin um auf die 3,3V zu kommen. Geschwindigkeiten sind auch gleich eingestellt (115200)

Danke schonmal für eure Antworten

Da ist hinten ein \r dran.
ersetze den Teil

    for (int i = 0; i < rlen; i++)
      Serial.print(buf[i]);

mit einer Ausgabe in HEX

    for (int i = 0; i < rlen; i++)
    {
      Serial.print(buf[i], HEX);
      Serial.print(' ');
    }

Was siehst Du auf dem Seriellen Monitor?

Das ist die Ausgabe wenn's vom ESP kommt

Arduino ist bereit
I received: 54 65 73 74 D 
5
-19
I received: 48 61 6C 6C 6F D 
6
-31
I received: 67 65 72 61 64 65 D 
7
13

Und das über USB

Arduino ist bereit
I received: 54 65 73 74 
4
-19
I received: 48 61 6C 6C 6F 
5
-31
I received: 67 65 72 61 64 65 
6
0
Eine Gerade Linie wird gezeichnet

Die Zahl unter I received ist rlen, und darunter strcmp mit "gerade"

Das D :wink:
0x0D oder DEC: 13 ist CarrigeReturn. (\r)
Darum mache ich sowas mit dem unitl nicht, sondern prüfe auf Steuercode mit isControl oder isPrintable
Du könntest als Hack auf das letzte Zeichen prüfen:

  if (Serial.available() > 0)                                                                         // Test der seriellen Kommunikation
  {
    int rlen = Serial.readBytesUntil('\n', buf, BUFFER_SIZE);                                         // ankommende Bytes lesen und länge speichern
    Serial.print("I received: ");                                                                     // ausgeben was angekommen ist
    for (int i = 0; i < rlen; i++)
    {
      Serial.print(buf[i], HEX);
      Serial.print(' ');
    }
    if (isControl(buf[rlen-1]))
    {
      buf[rlen-1] = '\0';
      rlen--;
    }

Es funktioniert jetzt alles wie es soll. Vielen Dank euch dreien :pray:

1 Like

Problem gelöst? Mach nen Haken ran.

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