Go Down

Topic: Switch Case - in Funktion gefangen (Read 685 times) previous topic - next topic

Ratpack

Hallo Zusammen, nach einer kleinen Pause geht es jetzt weiter im Programm.

Statt einen Arduino Nano verwende ich jetzt einen ESP8266.

Ich möchte ein Signal (0 bis 4) per UDP an den ESP senden. Dieses Signal soll dann mein "switch case" ändern. Der Code sieht bisher wie folgt aus:


Code: [Select]


//Laden von Bibiliotheken
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

//Netzwerkdaten
const char* ssid = "Netzwerk";
const char* password = "Passwort";
const int serverPort = 8266; // Port Webserver

// UDP Protokolldaten
WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
char incomingPacket[255];  // buffer for incoming packets

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "ok";        // a string to send back

void setup() {
  Serial.begin(115200);
  Serial.println("Here i am ");

  Serial.printf("Verbindung herstellen mit %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" verbunden");
  Serial.println(WiFi.localIP());

  long rssi = WiFi.RSSI();
  Serial.print("Signalstaerke(RSSI) des AP: ");
  Serial.print(rssi);
  Serial.print(" dBm");

  Udp.begin(localUdpPort);
  Serial.println();
  Serial.printf("Empfangsbereit für %s, auf UDP Port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);


}



void loop() {
  // Wenn Daten verfügbar sind, einlesen
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // und die Daten in Buffer speichern
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    delay(10);

   
    switch (packetBuffer) {
      case '0': status = 0; break;
      case '1': status = 1; break;
      case '2': status = 2; break;
      case '3': status = 3; break;
      case '4': status = 4; break;
   
  }
 
  // status auswerten
  if (status == 0) ruhemodus();
  if (status == 1) rausdrehen();
  if (status == 2) reindrehen();
  if (status == 3) messen();
  if (status == 4) kalibrieren();
}

    // Antwortnachricht senden
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
 }


Mein Problem ist, dass beim Compilieren der folgende Fehler auftaucht:
 
Programm_Arduino_Nano_final_test:98:25: error: switch quantity not an integer

     switch (packetBuffer) {

                         ^

Mehrere Bibliotheken wurden für "ESP8266WiFi.h" gefunden
 Benutzt: C:\***\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\ESP8266WiFi
exit status 1
switch quantity not an integer


Kann mir jemand einen Tipp geben, woran es liegt?

Beste Grüße
Tim

combie

#31
Oct 21, 2019, 03:41 pm Last Edit: Oct 21, 2019, 03:42 pm by combie
Quote
Kann mir jemand einen Tipp geben, woran es liegt?
Klar!
Der Type deines packetBuffer ist kein Integer.
Und Switch mag nur Integer Typen.
(das steht aber auch so in der Meldung)
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Serenifly

#32
Oct 21, 2019, 03:44 pm Last Edit: Oct 21, 2019, 03:44 pm by Serenifly
Wo ist das Problem mit der Fehlermeldung? Switch geht nur mit Integern. Ein Array ist kein Integer. Sagt klar was falsch ist

Du kannst bestimmte Array Indizes vergleichen, aber wie soll ein ganzes Array '1' oder '2' sein?

Ratpack

#33
Oct 21, 2019, 03:53 pm Last Edit: Oct 21, 2019, 03:54 pm by Ratpack
Switch geht doch auch mit char? Jedenfalls hatte ich das mittels serieller eingabe bereits hinbekommen.
https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/

Code: [Select]
// Funktionen noch mit Serial read
  if (Serial.available() > 0) {
    char input = Serial.read();
    switch (input) {
      case '0': status = 0; break;
      case '1': status = 1; break;
      case '2': status = 2; break;
      case '3': status = 3; break;
      case '4': status = 4; break;
    }


Und den Buffer habe ich doch als char definiert.
Code: [Select]
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet

Oder übersehe ich etwas`?

Serenifly

Integer heißt einfach nur Ganzzahl. char ist auch ein Integer-Datentyp. Ein Byte groß mit Vorzeichen

Quote
Und den Buffer habe ich doch als char definiert.
Nein. Was denkst du was die eckigen Klammern machen?

Ratpack

Danke, weis jetzt was du meinst. Ich probiere mal weiter rum und berichte.

Ratpack

So, ich bin jetzt soweit dass es für mich funktioniert.
Vielleicht magst du mal einen Blick drauf werfen und mir sagen ob das so konform ist:

Code: [Select]


//Laden von Bibiliotheken
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

//Netzwerkdaten
const char* ssid = "Netzwerk";
const char* password = "Passwort";
const int serverPort = 8266; // Port Webserver

// UDP Protokolldaten
WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "ok";        // a string to send back





void setup() {
 
  Serial.begin(115200);
  Serial.println("Here i am ");

  Serial.printf("Verbindung herstellen mit %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" verbunden");
  Serial.println(WiFi.localIP());

  long rssi = WiFi.RSSI();
  Serial.print("Signalstaerke(RSSI) des AP: ");
  Serial.print(rssi);
  Serial.print(" dBm");

  Udp.begin(localUdpPort);
  Serial.println();
  Serial.printf("Empfangsbereit für %s, auf UDP Port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);



}



void loop() {
  // Wenn Daten verfügbar sind, einlesen
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // und die Daten in Buffer speichern
    Udp.read(packetBuffer, 1);
    Serial.println("Contents:");
    Serial.println(packetBuffer[0]);

    delay(10);

   
    switch (packetBuffer[0]) {
      case '0': status = 0; break;
      case '1': status = 1; break;
      case '2': status = 2; break;
      case '3': status = 3; break;
      case '4': status = 4; break;
   
  }
 
  // status auswerten
  if (status == 0) ruhemodus();
  if (status == 1) rausdrehen();
  if (status == 2) reindrehen();
  if (status == 3) messen();
  if (status == 4) kalibrieren();
}

    // Antwortnachricht senden
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
 }


Serenifly

Eigentlich ist es überflüssig. Um von einer ASCII Ziffer zwischen '0' und '9' auf den Integer-Wert zu kommen muss man nur '0' substrahieren. Siehe ASCII Tabelle

Aber es funktioniert, dann kannst du es auch so lassen

Ratpack

#38
Oct 28, 2019, 03:43 pm Last Edit: Oct 28, 2019, 03:44 pm by Ratpack
Hallo Zusammen,

ich habe jetzt ein weiteres Problem mit meinem array.
Nach einmaligem starten der Funktion messen, gibt er mir nach erneutem Aufruf der Funktion nur noch die gespeicherten Werte heraus. Ich habe schon versucht mit memse() 0 das array zu leeren, dann bekomme ich aber lauter nullen als messwerte ausgegeben. Hier noch mal der Code:

Code: [Select]



// UDP Protokolldaten
WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "ok";        // a string to send back

//Messen
const byte messpin = A0;
byte status = 0;
unsigned long altzeit;
const unsigned long messzyklus = 1;
byte i = 0; // Arrayindex
int messwert[250];

void setup() {
  // Einmalig ausführender Code
  Serial.begin(115200);
  Serial.println("Here i am ");

  Serial.printf("Verbindung herstellen mit %s ", ssid);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" verbunden");
  Serial.println(WiFi.localIP());

  long rssi = WiFi.RSSI();
  Serial.print("Signalstaerke(RSSI) des AP: ");
  Serial.print(rssi);
  Serial.print(" dBm");

  Udp.begin(localUdpPort);
  Serial.println();
  Serial.printf("Empfangsbereit für %s, auf UDP Port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}



void loop() {
  // Wenn Daten verfügbar sind, einlesen
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // und die Daten in Buffer speichern
    Udp.read(packetBuffer, 1);
    Serial.println("Contents:");
    Serial.println(packetBuffer[0]);


    delay(10);

    // Antwortnachricht senden
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }

  switch (packetBuffer[0]) {
    case '0': status = 0; memset(packetBuffer, 0, sizeof(packetBuffer)); break;
    case 49 : status = 1; memset(packetBuffer, 0, sizeof(packetBuffer)); break;
    case '2': status = 2; memset(packetBuffer, 0, sizeof(packetBuffer)); break;
    case '3': status = 3; memset(packetBuffer, 0, sizeof(packetBuffer)); break;
    case '4': status = 4; memset(packetBuffer, 0, sizeof(packetBuffer)); break;
  }

  // status auswerten
  if (status == 0) ruhemodus();
  if (status == 1) rausdrehen();
  if (status == 2) reindrehen();
  if (status == 3) messen();
  if (status == 4) kalibrieren();
}



// Messen der Spannung des Positionssensors
void messen() {
  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());


  if (i < 250) { // Array füllen
    if (millis() - altzeit >= messzyklus) {
      altzeit = millis();
      if (i == 0) Serial.println("messen aktiv");
      messwert[i] = analogRead(messpin)*(3.3 / 1023);
      i++;
      delay(1);
      Serial.println(messwert[i]);
    }
  }
  else {  // Ausgabe der Werte
    Serial.println("messen fertig");
    for (i = 0; i < 250; i++) {
      Serial.print(i); Serial.print("\t");
      Serial.println(messwert[i]);
      Udp.write(messwert[i]);

    }
    Udp.endPacket();
    status = 0; // status rücksetzen
  }

}





Gibt es eine möglichkeit, nach durchlaufen einer Funktion das Array komplett zu löschen?
Ich stelle mir vor, dass nach aktivierung der Funktion "messen" das Array gefüllt wird und die Daten ausgibt um Anschluss wieder vernichtet zu werden.

Beste Grüße
Tim

Tommy56

Nach der Ausgabe würde ich i wieder auf 0 setzen, ohne jetzt tiefer einzusteigen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Ratpack

Funktioniert natürlich prima. So langsam seh ich den Wald vor lauter Bäume nicht mehr. Danke dir.

postmaster-ino

Hi

Manches Mal hilft Es, wenn man Variablen sprechende Namen gibt und nicht überall die Gleiche verwendet.
Klar habe ich auch hier und da 'x' oder 'b' als temporäre Schleifen-Variable - dort dann aber temporär/lokal.
Dein Problem hier war, daß Du 'i' global definierst (ganz nebenbei auch lokal und das globale 'i' überdeckst) und auch als Schleifen-Variable missbrauchst.
Kein Wunder, daß 'i' dann den Endwert der Schleife inne hat (wobei das 'i' auch bis zu diesem Wert beim Befüllen benutzt wird - unterm Strich der gleiche Wert).

Das hat mit Bäumen recht wenig zu tun - gib dem 'i' einen vernünftigen Namen, benutze als temp-Variablen eben temp-Variablen (extra dafür deklariert) oder eben lokale Schleifen-Läufer.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Ratpack

Danke für dein Feedback. Das mit den mehreren i's habe ich geändert und ansonsten auch mal alles kommentiert.

Go Up