Impulseingänge per Netzwerk versenden

Moin,
ich habe zwei Arduino-Unos, 6 mechanische Wasserdurchfluss-Impulsgeber, die bei einer bestimmten Literzahl einen "Kurzschluss" erzeugen, den ich über die Digitaleingänge aufnehmen kann.
Das funktioniert auch sehr gut. Nun möchte ich diese Werte per Netzwerk versenden. Dafür habe ich diesen Code benutzt:

static byte oldVals[8];
//Prüft ob ein Impuls auf pin X erfolgt ist
boolean impulsEingabe(int pin)
{
  byte val= digitalRead(pin);
  byte result=false;
  if (val==LOW && oldVals[pin]==HIGH) result=true;
  oldVals[pin]=val;
  return result;
}

void setup() {
  Serial.begin(9600);
  Serial.println("Starting");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    Ethernet.begin(mac, ip,dns,gateway);
  }
  
  Serial.println("Started  ");
  Serial.println(Ethernet.localIP());
  for (int i = 2; i <=6;i++){
      pinMode(i, INPUT_PULLUP); // Pins 2-6 aktivieren/lesend
      impulsEingabe(i);
  
  }

//  client.setClientTimeout(100);
  
}

void loop() {
  //Nur für Keepalive Meldung 
  if (alive % 10000 == 0){
    Serial.println("Looping"); 
    
  }
  alive ++;
  alive = alive % 10000;
  for (int i = 2; i <= 6;i++){
    
    //Prüfen ob ein Impuls auf i kam
    if (impulsEingabe(i)){
      Serial.print("Got impuls on Pin ");
      Serial.print(String(i));
      Serial.print(" = ");
      Serial.println(String (impulsPins[i]));
      impulsCounters[i]++;
    }


      //Ergibt die aktuelle Anzahl der Impulse mit Modulo einen Restwert von 0 0
      // && ist die Anzahl der Impulse > 0
      // && ist die Netzwerkverbindung frei? 
      //Wenn ja, verbinden, den Impuls an den Server melden, Anzahl der Impulse reduzieren
      if (impulsCounters[i] % impulsModulo[i] == 0 && impulsCounters[i] > 0){
        if (!client.connected() && !connected){
         //Serial.println("Found impuls and send" + String (impulsPins[i]));
         connected = true;
         if (client.connect(server, 80)) {
          
          //Serial.println("connected");
          client.print("GET /getImpulse.php?pulseId=");
          client.print(String(impulsPins[i]));
          client.println(" HTTP/1.1");
          client.println("Host: host.de");
          client.println("Connection: close");
          client.println();
          impulsCounters[i] = 0;
          Serial.print("New Value for impulsCounters[");
          Serial.print(String(i));
          Serial.print("]=");
          Serial.println(String (impulsCounters[i]));
          client.stop();
          connected = false;
         }else{
          Serial.println("Verbindung zum Server nicht möglich");
          connected = false;
         }
      }else{
          Serial.println("Gleichzeitiges senden");
        
      }
      }
    }
  }

Den relevanten Teil habe ich nochmal mit Pseudocode hier:

static byte oldVals[8];
//Prüft ob ein Impuls auf pin X erfolgt ist
boolean impulsEingabe(int pin)
{
   return gabEsEinenImpulsAufPin(pin);
}

void setup() {
  initialisiereSerialPort(9600);
  initialisiereEthernet()
  
  //bereitePins2bis6Vor();
  pinMode(2, INPUT_PULLUP); // Pins 2-6 aktivieren/lesend
  pinMode(3, INPUT_PULLUP); // Pins 2-6 aktivieren/lesend
  pinMode(4, INPUT_PULLUP); // Pins 2-6 aktivieren/lesend
  pinMode(5, INPUT_PULLUP); // Pins 2-6 aktivieren/lesend
  pinMode(6, INPUT_PULLUP); // Pins 2-6 aktivieren/lesend

  
}

void loop() {
  //Nur für Keepalive Meldung 
  gibAlle10000DurchläufeEinenStatusAus();
  prüfePin2Bis6undSetzeDenZählerHoch()
  
  if (gibtEsNichtBearbeiteteZähler()){
      if(derzeitKeineVerbindung()){
        if (!client.connected() && !connected){
         connected = true;
         if (client.connect(server, 80)) {
          client.print("GET /getImpulse.php?pulseId=");
          client.print(String(impulsPins[i]));
          client.println(" HTTP/1.1");
          client.println("Host: host.de");
          client.println("Connection: close");
          client.println();
          //Setze die Impulse wieder auf 0
          impulsCounters[i] = 0;
          client.stop();
          connected = false;
         }else{
          Serial.println("Verbindung zum Server nicht möglich");
          connected = false;
         }
      }
    }
  }

Zur Konfiguration:

  • Der Code läuft auf zwei Arduinos. Die IP und die Mac Adresse sind unterschiedlich konfiguriert
  • Das erste Arduino läuft fehlerfrei, das zweite macht Probleme
  • Das erste Arduino hat zwei 0,5l Zähler und einen 0,0215l Zähler, das zweite genau andersrum zwei 0,0215l und einen 0,5l Zähler
  • Die verwendete Hardware ist identisch

Die Modulo Abfrage ist für unterschiedliche Zählertypen gedacht. Bei den 0,0215l Zählern soll nur alle 20 Impulse ein Signal geschickt werden.

Nun zum eigentlichen Problem:
Das Arduino hängt sich nach einer gewissen Zeit auf (mal nach einer Minute, mal 5, mal nach 10)
In der seriellen Ausgabe sehe ich keine weiteren Aktivitäten mehr.
Die serielle Ausgabe hängt scheinbar immer woanders, im Regelfall nach "Found impuls and send" oder nach "connected".

Ich vermute, dass entweder der Server zu langsam antwortet, ein Timeout passieren müsste, oder dass das Arduino in irgendeiner Form überlastet wird. An den Zählern hängen Pumpen die ca 600l pro Stunde bewegen. Das sind bei den beiden 0,0215l Zählern jeweils ca. 7 Impulse pro Sekunde, also alle 1,5 Sekunden ein Signal an den Server.

In der Arduino Programmierung bin ich nicht sehr fit bzw. am lernen, deshalb vermute ich irgendeinen Anfängerfehler. So weiß ich z.B. gar nicht, ob der Else-Fall "Gleichzeitiges senden" überhaupt eintreffen kann und wenn ja in welchem Szenario.

Wenn ich das eigentliche Senden auskommentiere, dann rennt das Arduino locker 15min durch (danach habe ich abgebrochen). Es muss also etwas mit dem Ethernet-Shield bzw. meiner Ansteuerung zu tun haben.

Ich bin für jeden Hinweis dankbar und hoffe, dass der Code verständlich ist.

Hi

Wie viel Speicher hast Du noch frei?
Da Du String benutzt, vermute ich, daß Die der Speicher ausgeht und Dieser dann überläuft.

Serial.print(String(i));
client.print(String(impulsPins*));*
Schmeiß Da die String(...) raus - das .print macht aus einer Zahl eh schon einen Text (also gibt die Zahl ziffernweise aus).
MfG

Hallo
Wie hoch sind denn die Frequenzen die du senden willst
Durchflussmesser die ich so kenne laufen mit 30- 2000 Hz
Vorschlag auf der Senderseite die Frequenz messen und das Ergebniss jede Sekunde senden .

Heinz

Moin,
vielen Dank für eure Nachrichten.

Die Stringkonvertierung habe ich mal deaktiviert und teste jetzt.

Parallel dazu messe ich mal die Frequenzen durch, das klingt auf jeden Fall nach einer guten Idee.

Danke!