Visual Studio vs. IDE

Hallo,

kann mir jemand sagen wieso identischer Code

while (Serial.available() > 0) {  // wird durchlaufen solange Daten im Empfangspuffer

    Serial.println("while 1");

    byte_command = 0;
    byte nextion_data [4] = {0, 0, 0, 0};


    byte_command = Serial.read();  // hier sollte jetzt ein Befehlsbyte kommen :-)

    Serial.print("command gelesen ");
    Serial.println(byte_command);

in VS compiliert absoluten Unsinn ausgibt?
Nach HEX 0D wird die Ausgabe einfach abgeschnitten.


In der IDE kommt wie erwartet

Ich habe das extra auf Serial.print umgeschrieben, weil meine debug-Ausgaben auch abgeschnitten wurden.
Liegt aber augenscheinlich nicht am debug.

cu

bitte posten sie den gesamten code

Das kann ich machen, sind ein paar hundert Zeilen.
Und was soll dann anders sein, hier sind drei print-Befehle die hintereinander erscheinen müssen und mit IDE auch korrekt verarbeitet werden.

cu

mach ein in sich geschlossenes Beispiel.
Wenn du jetzt glaubst dass sind die 7 Zeilen, dann wird es für dich ja ein Leichtes sein, den Rest dazuzubauen um daraus ein lauffähiges Beispiel zu machen.

Zeigt das Beispiel dann den Fehler nicht, weist du dass es an diesen Zeilen nicht liegt.
Wenn doch - kannst du einen vollständig kompilierbaren Sketch zeigen und es wird sich jemand das Problem ansehen.

In beiden Fällen gewinnst du - entweder findest du den Fehler selber - oder es kann dir jemand helfen.

Der Grund, warum ich nach dem Code gefragt habe, war, um zu sehen, ob Sie irgendwo ein Speicherproblem haben oder ob der Speicher begrenzt wird, was zu erratischem Verhalten führt.

VS mag es z.B. nicht wenn eine Funktion noch nicht definiert ist wenn sie aufgerufen wurde...
Ich hatte vor kurzem das gleiche: Code ging in der Arduino IDE, nicht aus VS... Was hatte ich vergessen: #include <Arduino.h> :wink:

Da kommt es aber schon zu Compilier (bzw. Linker) Fehler. Aber nicht zu Ausgabefehler während der Laufzeit.

Dennoch braucht es ein Beispielcode, damit andere das Fehlverhalten bestätigen können und/oder auf Fehler hinweisen können und/oder das Verhalten erklären können.

Hier der Code, ich habe einfach main komplett eingekürzt.
main.cpp:

#include <Arduino.h>

#include "nextion.h"

NEXTION nextion;

void setup() {

  Serial.begin(115200);

  nextion.begin(25, 47);

}

void loop() {

  nextion.read();
  
  delay(5000);

}

nextion.h:

#ifndef nextion_h
#define nextion_h

#include <Arduino.h>


class NEXTION
{
private:
    
    
    int command_0;          // 0 bis command_0 Befehle ohne Datenbyte
    int command_1;          // command_0 - command_1 Befehle mit zwei Datenbytes
    int command_max = 63;   // max. 63 Befehle, command_1 - command_max Befehle mit zwei Datenbytes

    byte byte_command;

    int number_databytes;

    void printError(byte code);

public:

    byte nextion_command;
    byte nextion_data[4];

    void begin(int val_0, int val_1);
    void read();
    //void read(int val);  // Problem "offenes" Array
    //void read(char sign);

};


void NEXTION::begin(int val_0, int val_1) {

    if (val_0 > command_max || val_0 > val_1 || val_1 > command_max || val_0 < 0) Serial.println("Error begin");
    
    command_0 = val_0;
    command_1 = val_1;
}


void NEXTION::read() {

    if (Serial.available() == 0) {  // keine neuen Daten vom Display

      Serial.println("keine Daten");

       return;

    }

  while (Serial.available() > 0) {  // wird durchlaufen solange Daten im Empfangspuffer

    Serial.println("while 1");

    byte_command = 0;
    byte nextion_data[4] = {0, 0, 0, 0};


    byte_command = Serial.read();  // hier sollte jetzt ein Befehlsbyte kommen :-)

    Serial.print("command gelesen ");
    Serial.println(byte_command);
    
    if ((byte_command & 192) == 128) {  // Befehlsbyte (10xx xxxx)

      if ((byte_command & 32) > command_0) {  //anhängende Datenbytes

        if ((byte_command & 32) > command_1) {
          
          number_databytes = 4;
        
        }

        else {

          number_databytes = 2;
        
        }

        Serial.print("datenbytes? ");
        Serial.println(number_databytes);

        unsigned long millis_start = millis();
        bool timeout = false;

        while (Serial.available() < number_databytes) {  // warten bis zwei oder vier Bytes im seriellen Eingang

          Serial.println("while 2");

          if (millis() - millis_start > 2) {  // timeout bevor Datenbytes im Eingang
            
            Serial.println("timeout");

            timeout = true;
            break;

          }
        }

        if (timeout) {
          printError(2);
          Serial.begin(115200);  // Empfangspuffer leeren
          return;
        }

        else {  // Datenbytes einlesen

          for (int i = 0; i < number_databytes; i++) {
            
            byte incomming = Serial.read();

            Serial.print("incomming ");
            Serial.println(incomming);
            
            if ((incomming & 192) != 64) {

              printError(3);  // Fehler Datenbyte
              Serial.begin(115200);  // Empfangspuffer leeren
              return;
            
            }

            else {

              nextion_data[i] = incomming & 63;
            
            }
          }
        }  // Ende Datenbytes einlesen

      }
      
      return;

    }

    else {  // Fehler Befehlsbyte
      printError(1);
      Serial.begin(115200);  // Empfangspuffer leeren
      return;
    }
  }

  return;

}


void NEXTION::printError(byte code) {

  if (code == 1) Serial.println("Fehler Befehlsbyte");
  else if (code == 2) Serial.println("TimeOut Datenbytes");
  else if (code == 3) Serial.println("Fehler Datenbyte");
  
}

Die Ausgabe ist etwas anders, aber man sieht das die while-Schleife bei einer Eingabe (0xC4) zwischen zwei print-Befehlen abgebrochen wird.

Auslöser ist die Weigerung nextion_data mit Null zu füllen.


Es werden schon zu viele Werte angemeckert (?) und beim kompilieren .....

Die Suche hat mich dann aufs Glatteis geführt, was das erneute"byte" vor
nextion_data[4] = {0, 0,0, 0} erklärt.
Damit kriege ich m.E. die Werte zwar nicht nach "außen", aber innerhalb der while sollte das doch laufen? Was es in der IDE ja macht.

Der Übeltäter ist die Arrayzuweisung byte nextion_data[4] = {0, 0,0, 0}, lässt man die weg läuft es auch mit VS.

cu

Wenn Sie Ihre if/else-Struktur so gestalten, gibt es mögliche Fälle, in denen number_databytes nicht initialisiert wird.

  if ((byte_command & 192) == 128) {  // Befehlsbyte (10xx xxxx)
    if ((byte_command & 32) > command_0) {  //anhängende Datenbytes
      if ((byte_command & 32) > command_1) {
        number_databytes = 4;
      } else {
        number_databytes = 2;
      }
    }

Wenn es 2 ist, es sei denn, die anderen Bedingungen treffen zu, sollten Sie Folgendes tun.

  number_databytes = 2;
  if ((byte_command & 192) == 128) {  // Befehlsbyte (10xx xxxx)
    if ((byte_command & 32) > command_0) {  //anhängende Datenbytes
      if ((byte_command & 32) > command_1) {
        number_databytes = 4;
      }
    }
  }

Können Sie beschreiben, wie Sie alles verdrahtet haben ? Teilen Sie die UART sowohl mit dem Serial Monitor als auch mit dem Nextion-Bildschirm ?

Hallo,

du hast in der nextion.h

byte nextion_data[4]

2x definiert. Einmal public gewollt. Beim 2. willst dieses Array vermeintlich nullen, machst es aber nicht, du legst es lokal neu an. Tipp. Wenn der Compiler Fehlermeldungen ausgibt, fange immer mit dem Ersten an diese zu beseitigen. Eine nach der anderen.

a) die gepostete nextion.h ist unvollständig. Da fehlt ein schließendes #endif.
Besser wäre sowieso der neuere include guard mit #pragma once

b) rest wurde eigentlich eh schon alles geschrieben.
Auch die Arduino IDE reklamiert als Warning

In file included from C:\Daten\myrepository\Arduino\Forum no SVN\sketch_dec29a\sketch_dec29a.ino:3:0:
C:\Daten\myrepository\Arduino\Forum no SVN\sketch_dec29a\nextion.h: In member function 'void NEXTION::read()':
C:\Daten\myrepository\Arduino\Forum no SVN\sketch_dec29a\nextion.h:59:10: warning: variable 'nextion_data' set but not used [-Wunused-but-set-variable]
     byte nextion_data[4] = {0, 0, 0, 0};
          ^~~~~~~~~~~~

änderst du die Zeile in eine falsche Zuweisung

In file included from C:\Daten\myrepository\Arduino\Forum no SVN\sketch_dec29a\sketch_dec29a.ino:3:0:
C:\Daten\myrepository\Arduino\Forum no SVN\sketch_dec29a\nextion.h: In member function 'void NEXTION::read()':
nextion.h:59:34: error: cannot convert '<brace-enclosed initializer list>' to 'byte {aka unsigned char}' in assignment
     nextion_data[4] = {0, 0, 0, 0};
                                  ^
exit status 1
cannot convert '<brace-enclosed initializer list>' to 'byte {aka unsigned char}' in assignment

machst ein memset, kompiliert es fehlerfrei

memset(nextion_data, 0, sizeof(nextion_data));  // ersatz für //nextion_data[4] = {0, 0, 0, 0};

funktional hab ich es nicht geprüft.
Mach ich abhängig von deiner Reaktion vieleicht.

Verstehe ich nicht.

if ((byte_command & 63) > command_0) {  // anhängende Datenbytes

        if ((byte_command & 63) > command_2) {  // vier Datenbytes

          number_databytes = 4;

        }

        else {  // zwei Datenbytes

          number_databytes = 2;
        }

Das erste if entscheidet ob überhaupt Datenbytes kommen (oberhalb command_1), es also überhaupt benötigt wird.
Das zweite if legt 4 fest, da Befehl oberhalb von command_2 während else es für den Bereich zwischen command_1 und _2 auf zwei setzt.

Da das eine Testphase nach Erweiterung des Programms ist läuft alles über die gleiche Schnittstelle. Mit H-Term wird das Nextion simuliert.
In ähnlicher Form läuft das Programm über Serial2 mit einem Nextion.

Ich weiß, habe ich ja geschrieben, das war der Sinn des Ganzen.
Aber ich habe Null Ahnung warum hier zu viele Initialisierungswerte angemahnt werden? Array[4] sind m.E. Array[0] - Array[3]
Das lokale anlegen war eine falsche Fährte von

-> 4.

Ist im Original da, sorry.

Die ersten drei Zeilen Warnung in der IDE kommen natürlich bei mir auch, aber die habe ich als Hinweis verstanden, die Variable wird ja tatsächlich nicht verwendet.
Zur zweiten Fehlermeldung der IDE bin ich nicht gekommen da

for (int i = 0; i < 4; i++) {

    nextion_data[i] = 0;

  }

memset kannte ich nicht.
Funktioniert aber ... :+1:

Was ich aber nicht verstehe, was ist an meiner Zuweisung falsch?
Und warum bringt die lokale Variable in der while-Schleife diesen Fehler?
In der IDE hat die brav die Werte angenommen. die seriell reinkamen.

cu

Dann kann die auch weg!

Da ist weit und breit keine Zuweisung zu sehen.
Das ist eine Arraydefinition mit Initialisierung.

Wenn dort eine Zuweisung stattfinden würde, dann wäre dieses nicht möglich:
byte nextion_data[4] {0, 0, 0, 0};
Ist es aber.

ist halt so bei einem Array nicht möglich und deshalb bekommst du einen Fehler.

In diesem speziellem Fall, natürlich wird die ansonst verwendet.

Ja, ok, aber wie man es nennt hat doch keine Auswirkungen wie es funktionieren sollte.

cu

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