Arduino Uno mit Ethernet Shield W5100 Chip und RFID Leser RC5222 Programm hängt

Hallo Zusammen :slight_smile:

ich beschäftige mich mittlerweile schon eine ganze Zeit lang mit dem Arduino und seinen Möglichkeiten.
Nun habe ich mit meinem Uno erfolgreich eine TCP Verbindung zu meinem Server hergestellt.
Ebenfalls hatte ich in einem anderen Projket erfolgreich und problemlos ein Chiplesegerät gebastelt.
Jetzt wollte ich beide Projekte zusammen führen, da kommt es aber nun öfters zum Problem.
Beide Shields arbeiten über SPI. Das Ethnertshield arbeitet soweit ich weiß mit dem Pin 10 als SS.
Somit habe ich den RFID Leser mit Pin 3 als SS und Pin 2 als RST gestartet (Siehe Code).
Das ganze läuft auch eine weile und hängt sich dann immer an unbestimmten Stellen auf (Auch die Laufzeit ist völlig unterschiedlich).

Teilweise läuft das Programm nur ein paar Sekunden, noch bevor der Befehl kommt sich mit dem Server zu verbinden, dann aber auch wieder ein paar Minuten mit funktioniereder TCP Verbindung.

Hier mal kurz Links zu den Shields:

Meinen Code hab ich mal ungefiltert als INO beigefügt, ich hoffe ihr kommt damit zurecht.

Über Nachfragen oder gar Vorschläge freu ich mich jetzt schon, verzweifel da schon ein paar Stunden mehr dran...

#include <SPI.h>
#include <Ethernet.h>
#include <MFRC522.h> // RFID Bibliothek Laden

MFRC522 mfrc522(3, 2);

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xEE, 0xED
};
IPAddress ip(192, 168, 2, 143); // My Own IP 

IPAddress server(192, 168, 2, 8);
//IPAddress server(80, 153, 23, 235);

EthernetClient client;

unsigned long Last_message_Send;
unsigned long Last_message_Received;
byte TCP_Timeout = 0;

byte Relais = 8;
byte CHIP_LED = 9;
byte CHIP_LED_Timeout = 0;

int Schranke_Timeout = 0;
int Befehl105_Timeout = 0;

String RFID_Chips[40];

void setup() {
  pinMode(Relais, OUTPUT);
  pinMode(CHIP_LED, OUTPUT);
  pinMode(4, OUTPUT); //SD Karte wird nicht benötigt
  digitalWrite(4, HIGH); // Deswegen Ausgang auf HIGH gesetzt
  SPI.begin;
  Ethernet.begin(mac, ip);

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

  mfrc522.PCD_Init();

  delay(5000);
  Serial.println("End Setup");
}

boolean Connect() {
  Serial.println("connecting...");
  if (client.connect(server, 60001)) {
    delay(1000);
    Serial.println("connected");
    Senden("998$Arduino$001$");
    Last_message_Send = 0;
    Last_message_Received = 0;
    return true;
  } else {
    Serial.println("connection failed");
    return false;
  }
}

int free_ram ()
{
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
};

void Auswertung(String X) {
  Serial.println("Lese: " + X);
  String Befehl = Erste_Info(X);
  if (Befehl.equals("102")) { //Schranken Status
    String Status = Erste_Info(X);
    if (Status.equals("1")) {
      Serial.println("Schranke auf");
      Schranke_Timeout = -3;
      digitalWrite(Relais, HIGH);
      Senden("103$0$");
    } else {
      Serial.println("Schranke zu");
    }
  }
  if (Befehl.equals("105")) { // Chipnummern empfangen
    Befehl105_Timeout = 0;
    String E = Erste_Info(X);
    int Position = E.toInt();
    String E2 = Erste_Info(X);
    int Kein_Element = E2.toInt(); // 0 heißt kein Element, 1 heißt enthält ein Element an gegebener Position
    if ((Kein_Element > 0) && (Position < 40)) { // Element an Position einfügen
      RFID_Chips[Position] = X;
      Position = Position + 1;
      Senden("105$" + String(Position) + "$");
    } else { // Alle Positionen dahinter leeren
      Position = Position + 1 ;
      while (Position < 40) {
        RFID_Chips[Position] = "";
        Position = Position + 1;
      }
    }
  }
}

String Erste_Info(String & X) {
  String Erste_Information = "";
  while (X.length() > 0) {
    String B = X.substring(0, 1);
    if (X.length() > 1) {
      X = X.substring(1);
    } else {
      X = "";
    }
    if (!B.equals("$")) {
      Erste_Information = Erste_Information + B;
    } else {
      break;
    }
  }
  return Erste_Information;
}

void Senden(String X) {
  if (client.connected()) {
    client.println(X);
    Last_message_Send = 0;
    Serial.println("Schreibe in TCP: " + X);
  } else {
    Serial.println("Schreiben nicht verfügbar, Client not connected");
  }

}

byte RFID_Timeout = 10;

void loop() {


  if (client.connected()) {

    if (Befehl105_Timeout == 500) {
      Befehl105_Timeout = 0;
      Senden("105$1$");
    }
    Befehl105_Timeout = Befehl105_Timeout + 1;

    Last_message_Received = Last_message_Received + 1;
    Last_message_Send = Last_message_Send + 1;

    int Counter = -1;
    byte B;
    char Bytes[200];
    while (client.available()) {
      delay(10);
      Counter = Counter + 1;
      if (Counter > 5000) {
        break;
      }
      B = client.read();
      if (B != 13) {
        if (B != 10) {
          if (Counter < 200) {
            Bytes[Counter] = char(B);
          }
        }
      }
      if (B == 10) {
        char Bytes5[Counter + 1];
        int cou1 = 0;
        while (cou1 < Counter + 1) {
          Bytes5[cou1] = Bytes[cou1];
          cou1 = cou1 + 1;
        }
        Auswertung(String(Bytes5));
        Counter = -1;
        int cou = 0;
        while (cou < 200) {
          Bytes[cou] = 0;
          cou = cou + 1;
        }
      }
      Last_message_Received = 0;
    }




    if (Last_message_Received > 50 &&  Last_message_Send > 50) {
      Senden("102$");
    }
    if (!client.connected()) {
      Serial.println();
      Serial.println("disconnecting.");
      client.stop();
    }
    if (Last_message_Received > 150) {
      Serial.println("Client zu lange keine Antwort");
      Serial.println("Last Received = " + String(Last_message_Received));
      Serial.println("Last Send = " + String(Last_message_Send));
      Serial.println("disconnecting.");
      TCP_Timeout = 0;
      client.stop();
      delay(500);
    }
  }
  else {
    TCP_Timeout = TCP_Timeout + 1;
    Serial.println(String(TCP_Timeout));
    if (TCP_Timeout == 255) {
      Connect();
      TCP_Timeout = 0;
    }
  }

  if (CHIP_LED_Timeout < 25) {
    digitalWrite(CHIP_LED, LOW);
  }
  else {
    digitalWrite(CHIP_LED, HIGH);
  }
  if (CHIP_LED_Timeout == 50) {
    CHIP_LED_Timeout = 0;
    int l = free_ram;
    Serial.println("Freier Speicher: " + String(l));
  }
  CHIP_LED_Timeout = CHIP_LED_Timeout + 1;

  if (Schranke_Timeout < 0) {
    digitalWrite(Relais, HIGH);
    Schranke_Timeout = Schranke_Timeout + 1;
  } else {
    digitalWrite(Relais, LOW);
  }

  delay(10);
  if (RFID_Timeout == 100) {
    if (  mfrc522.PICC_IsNewCardPresent() &&  mfrc522.PICC_ReadCardSerial())  {
      String RFID1 = String(mfrc522.uid.uidByte[0], HEX);
      String RFID2 = String(mfrc522.uid.uidByte[1], HEX);
      String RFID3 = String(mfrc522.uid.uidByte[2], HEX);
      String RFID4 = String(mfrc522.uid.uidByte[3], HEX);
      RFID1.toUpperCase();
      RFID2.toUpperCase();
      RFID3.toUpperCase();
      RFID4.toUpperCase();
      if (RFID1.length() == 1) {
        RFID1 = "0" + RFID1;
      }
      if (RFID2.length() == 1) {
        RFID2 = "0" + RFID2;
      }
      if (RFID3.length() == 1) {
        RFID3 = "0" + RFID3;
      }
      if (RFID4.length() == 1) {
        RFID4 = "0" + RFID4;
      }
      Senden("106$" + RFID1  + RFID2 +  RFID3 +  RFID4 + "$");
      int c = 0;
      while (c < 40) {
        String Element = RFID_Chips[c];
        if (Element.length() > 0) {
          String IDs = Erste_Info(Element);
          IDs.replace(";", "$");
          while (IDs.length() > 7) {
            String RFID = Erste_Info(IDs);
            String B_1 = RFID.substring(0, 2);
            String B_2 = RFID.substring(2, 4);
            String B_3 = RFID.substring(4, 6);
            String B_4 = RFID.substring(6, 8);
            if ((RFID1.equals(B_1)) &&  (RFID2.equals(B_2) ) && (RFID3.equals(B_3) ) && ( RFID4.equals(B_4)) ) {
              Schranke_Timeout = -5;
              digitalWrite(Relais, HIGH);
              //gef = true;
              // Serial.println("WAR RICHTIG!!!!!!");
            }
          }
        }
        c = c +1 ;
      }
      RFID_Timeout = 0;
    }
  }
  else {
    RFID_Timeout = RFID_Timeout + 1;
  }
  delay(10);
}

UNO_TCPClient.ino (7.01 KB)

Bitte setze Deinen Sketch direkt ins Forum, wenn er nicht zu groß ist. Nutze dazu Codetags (oben links </> im Foreneditor oder [code] davor und [/code] dahinter - ohne die *).
Das kannst Du auch noch nachträglich durch Editieren tun. Bitte mach das, der Sketch ist besser zu lesen, besonders auf mobilen Geräten.

Mir fallen 2 Sachen auf. Wenn beide Geräte über SPI laufen, dann darf immer nur 1 aktiv sein. Ich sehe aber keine SS-Umschaltung (ich habe aber auch nicht in die Libs geschaut).

Du verwendest recht intensiv die Klase String. Das ist nicht gut für Deinen RAM, da der dadurch fragmentiert wird. Löse das lieber über char-Arrays. Hinweise dazu findest Du hier.

Gruß Tommy

Vielen Dank für deine Antwort, ich hab den Link nun vollständig gelesen und könnte mir auch gut vorstellen, dass das Problem dort begraben ist. Ich werde mal anfangen umzubauen und mich dann wieder melden :slight_smile:

Ich habe nun ein wenig gebastelt und vorläufig auch einiges aus meinem Projekt rausgeschmissen.
Ich habe zum Beispiel versucht, gerade die Chip IDS nicht mehr als Strings zu speichern.
Trotzdem hängt sich das Programm weg und startet neu. Das Protokoll im Monitor sieht so aus:

250
251
252
253
254
255
connecting...
connected
Schreibe in TCP: 998$$Arduino$001$
Habe was gelesen mit 24 Zeichen
Schreibe in TCP: 102$
Habe was gelesen mit 8 Zeichen
Schreibe in TCP: 102$
Habe was gelesen mit 8 Zeichen
Schreibe in TCP: 102$
Habe was gelesen mit 8 Zeichen
Schreibe in TCP: 102$
Habe was gelesen mit 8 Zeichen
Schreibe in TCP: 102$
Habe was gelesen mit 8 Zeichen
Schreibe in TCP: 10End Setup <- Hier bricht es auf einmal ab und beginnt von vorne..
1
2
3
4
5
6

Ist es immer noch das Problem, dass ich zu viel mit der Klasse String arbeite? Sehr viel weniger geht doch eig gar nciht mehr oder seh ich das falsch?

Vielen Dank für eure Hilfe :slight_smile:

#include <SPI.h>
#include <Ethernet.h>
#include <MFRC522.h> // RFID Bibliothek Laden

MFRC522 mfrc522(3, 2);

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xEE, 0xED
};
IPAddress ip(192, 168, 2, 143); // My Own IP ?

IPAddress server(192, 168, 2, 8);
//IPAddress server(80, 153, 23, 235);

EthernetClient client;

unsigned long Last_message_Send;
unsigned long Last_message_Received;
byte TCP_Timeout = 0;

byte Relais = 8;
byte CHIP_LED = 9;
byte CHIP_LED_Timeout = 0;

int Schranke_Timeout = 0;
int Befehl105_Timeout = 0;

class Chip {
  public:
    byte B_1;
    byte B_2;
    byte B_3;
    byte B_4;
};

Chip Chips[50];

void setup() {
  pinMode(Relais, OUTPUT);
  pinMode(CHIP_LED, OUTPUT);
  pinMode(4, OUTPUT); //SD Karte wird nicht benötigt
  digitalWrite(4, HIGH); // Deswegen Ausgang auf HIGH gesetzt
  SPI.begin;
  Ethernet.begin(mac, ip);

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

  mfrc522.PCD_Init();

  delay(5000);
  Serial.println("End Setup");
}

boolean Connect() {
  Serial.println("connecting...");
  if (client.connect(server, 60001)) {
    delay(1000);
    Serial.println("connected");
    Senden("998$Arduino$001$");
    Last_message_Send = 0;
    Last_message_Received = 0;
    return true;
  } else {
    Serial.println("connection failed");
    return false;
  }
}

int free_ram ()
{
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
};


void Auswertung(char Bytes1[], int leng) {
  int zaehler = 0;
  while (zaehler < leng)  {
       // Später weiter verarbeiten
    zaehler = zaehler + 1;
  }
  Serial.println("Habe was gelesen mit " + String(leng) + " Zeichen");
}

void Senden(String X) {
  if (client.connected()) {
    client.println(X);
    Last_message_Send = 0;
    Serial.println("Schreibe in TCP: " + X);
  } else {
    Serial.println("Schreiben nicht verfügbar, Client not connected");
  }

}

byte RFID_Timeout = 10;

void loop() {

  if (client.connected()) {

    if (Befehl105_Timeout == 500) {
      Befehl105_Timeout = 0;
      //Senden("107$");
    }
    Befehl105_Timeout = Befehl105_Timeout + 1;

    Last_message_Received = Last_message_Received + 1;
    Last_message_Send = Last_message_Send + 1;

    int Counter = -1;
    byte B;
    char Bytes[200];
    while (client.available()) {
      delay(10);
      Counter = Counter + 1;
      if (Counter > 5000) {
        break;
      }
      B = client.read();
      if (B != 13) {
        if (B != 10) {
          if (Counter < 200) {
            Bytes[Counter] = char(B);
          }
        }
      }
      if (B == 10) {
        char Bytes5[Counter + 1];
        int cou1 = 0;
        while (cou1 < Counter + 1) {
          Bytes5[cou1] = Bytes[cou1];
          cou1 = cou1 + 1;
        }

        Auswertung(Bytes5, Counter + 1);

        Counter = -1;
        int cou = 0;
        while (cou < 200) {
          Bytes[cou] = 0;
          cou = cou + 1;
        }
      }
      Last_message_Received = 0;
    }

    if (Last_message_Received > 50 &&  Last_message_Send > 50) {
      Senden("102$");
    }
    if (!client.connected()) {
      Serial.println();
      Serial.println("disconnecting.");
      client.stop();
    }
    if (Last_message_Received > 150) {
      Serial.println("Client zu lange keine Antwort");
      Serial.println("Last Received = " + String(Last_message_Received));
      Serial.println("Last Send = " + String(Last_message_Send));
      Serial.println("disconnecting.");
      TCP_Timeout = 0;
      client.stop();
      delay(500);
    }
  }
  else {
    TCP_Timeout = TCP_Timeout + 1;
    Serial.println(String(TCP_Timeout));
    if (TCP_Timeout == 255) {
      Connect();
      TCP_Timeout = 0;
    }
  }

  if (CHIP_LED_Timeout < 25) {
    digitalWrite(CHIP_LED, LOW);
  }
  else {
    digitalWrite(CHIP_LED, HIGH);
  }
  if (CHIP_LED_Timeout == 50) {
    CHIP_LED_Timeout = 0;
  }
  CHIP_LED_Timeout = CHIP_LED_Timeout + 1;

  if (Schranke_Timeout < 0) {
    digitalWrite(Relais, HIGH);
    Schranke_Timeout = Schranke_Timeout + 1;
  } else {
    digitalWrite(Relais, LOW);
  }

  delay(10);
  if (RFID_Timeout == 100) {
    if (  mfrc522.PICC_IsNewCardPresent() &&  mfrc522.PICC_ReadCardSerial())  {
      // Senden("106$" + RFID1  + RFID2 +  RFID3 +  RFID4 + "$");
      int c = 0;
      while (c < 50) {
        Chip chip1;
        chip1 = Chips[c];
        if (chip1.B_1 > 0) {
          if ((mfrc522.uid.uidByte[0] == chip1.B_1) && (mfrc522.uid.uidByte[1] == chip1.B_2) && (mfrc522.uid.uidByte[2] == chip1.B_3) && (mfrc522.uid.uidByte[3] == chip1.B_4)) {
            Schranke_Timeout = -5;
            digitalWrite(Relais, HIGH);
            //gef = true;
            // Serial.println("WAR RICHTIG!!!!!!");
          }
        }
        c = c + 1 ;
      }
      RFID_Timeout = 0;
    }
  }
  else {
    RFID_Timeout = RFID_Timeout + 1;
  }
  delay(10);
}

Es geht völlig ohne die Klasse String. Die notwendigen Infos hatte ich Dir verlinkt.

Alle Ausgaben mit konstanten Zeichenketten mit dem F-Makro in den PROGMEM schieben z.B.

Serial.println(F("End Setup"));

Welchen Arduino nutzt Du?

Gruß Tommy

Arduino Uno.

Ich werd mal sofort bei allen Println das F-Makro einfügen

So, ich wollte mich kurz zurückmelden. Mittlerweile läuft mein Projekt reibungslos. Ich habe allerdings festgestellt, dass die Probleme tatsächlich wahrscheinlich woanders begraben waren.

Zunächst habe ich den Uno extern mit Spannung versorgt, da an meinem USB Port zu viele Geräte hängen,
danach lief das Programm sauber durch. Ich habe auch leider noch eine Löstelle gefunden die nicht in Ordnung war, ob diese jedoch Probleme gemacht hat bin ich mir jetzt nicht sicher (War die MISO Leitung zum RC522)

Vielen Dank für deine Hilfe, die String umzubauen war definitiv auch nötig und damit hab ich auch was für eine saubere, nicht so Speicherintensive Programmierung gelernt :slight_smile:

Vielel Grüße, Daniel

Schön, dass es jetzt funktioniert. Es wäre schön, wenn Du den endgültigen Sketch hier noch einstellen könntest.

Gruß Tommy