UIPEthernet crashes Serial and code

Hello friends,

I recently bought several ENC28J60 to connect my Arduino to the Ethernet. Testing a “WebClient” worked fine, so the hardware is fine!

Using another code I measured two sensors properly.

That’s why I wanted to merge these two codes and came to the following lines:

#include <UIPEthernet.h>

#define DEBUG

#define IntervallMessung 2000 //Wie lange wird vor Auswertung gemessen
#define InterruptPin1 2
#define InterruptPin2 3
volatile unsigned long MillisMessbeginn = 0;
volatile unsigned long MillisMessende = 0;
volatile unsigned long MillisDifferenz = 0; //Misst Messzeit
volatile unsigned long counts1 = 0; //Signal-Zähler
volatile unsigned long counts2 = 0;
volatile float cpm1 = 0; //Count pro Zeit
volatile float cpm2 = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = { "www.abc.de"};
EthernetClient client;


void setup() {
Ethernet.begin(mac);

  #ifdef DEBUG
    Serial.begin(9600);
    Serial.println(F("Starte Device")); Serial.println(F(""));
  #endif

pinMode(InterruptPin1, INPUT_PULLUP);
pinMode(InterruptPin2, INPUT_PULLUP);

VariablenZuruecksetzen();

attachInterrupt( digitalPinToInterrupt(InterruptPin1), MesseImpulse1, RISING);
attachInterrupt( digitalPinToInterrupt(InterruptPin2), MesseImpulse2, RISING);

  #ifdef DEBUG
    Serial.print(F("MillisMessbeginn: "));
    Serial.print(MillisMessbeginn);
    Serial.print(F(", MillisMessende: "));
    Serial.println(MillisMessende);
  #endif
} 


void loop() {

  if ( millis() >= MillisMessende && millis() >= MillisMessbeginn ) //prüft, ob die Messzeit abgelaufen ist
  {
  noInterrupts();
MillisDifferenz = millis() - MillisMessbeginn; //Tatsächliche Messzeit
cpm1 = counts1 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 1
cpm2 = counts2 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 2

  #ifdef DEBUG
    Serial.print(F("MillisDifferenz: "));
    Serial.println(MillisDifferenz);
    Serial.print(F("Sonde 1:\t"=);
    Serial.print(counts1,DEC);
    Serial.print(F(" ips,\t"));
    Serial.println(cpm1,2);
    Serial.print(F("Sonde 2:\t"));
    Serial.print(counts2,DEC);
    Serial.print(F(" ips,\t"));
    Serial.println(cpm2,2);
  #endif

DatenSenden();
VariablenZuruecksetzen();

  #ifdef DEBUG
    Serial.print("\n\nMillisMessbeginn: ");
    Serial.print(MillisMessbeginn);
    Serial.print(", MillisMessende: ");
    Serial.println(MillisMessende);
  #endif

  interrupts();
  };


  if ( millis() < MillisMessbeginn ) //prüft, ob die Messzeit abgelaufen ist
  {
  noInterrupts();
    VariablenZuruecksetzen();
  interrupts();
  }

//Ethernet.maintain();
}


void MesseImpulse1() {
  counts1++;
}


void MesseImpulse2() {
  counts2++;
}


void VariablenZuruecksetzen() {
  counts1 = 0; // setzt die Zähler zurück
  counts2 = 0; // setzt die Zähler zurück
  MillisMessbeginn = millis(); //Zeitpunkt zum Start der Messsung
  MillisMessende = MillisMessbeginn + IntervallMessung; //Zeitpunkt zum Beenden der Messung
}


void DatenSenden()
{
  #ifdef DEBUG
    Serial.print("MillisDifferenz: ");
    Serial.println(MillisDifferenz);
    Serial.print("Sonde 1:\t");
    Serial.print(counts1,DEC);
    Serial.print(" ips,\t");
    Serial.println(cpm1,2);
    Serial.print("Sonde 2:\t");
    Serial.print(counts2,DEC);
    Serial.print(" ips,\t");
    Serial.println(cpm2,2);
  #endif
  #ifdef DEBUG
    Serial.print("MillisDifferenz: ");
    Serial.println(MillisDifferenz);
    Serial.print("Sonde 1:\t");
    Serial.print(counts1,DEC);
    Serial.print(" ips,\t");
    Serial.println(cpm1,2);
    Serial.print("Sonde 2:\t");
    Serial.print(counts2,DEC);
    Serial.print(" ips,\t");
    Serial.println(cpm2,2);
  #endif
  #ifdef DEBUG
    Serial.print("MillisDifferenz: ");
    Serial.println(MillisDifferenz);
    Serial.print("Sonde 1:\t");
    Serial.print(counts1,DEC);
    Serial.print(" ips,\t");
    Serial.println(cpm1,2);
    Serial.print("Sonde 2:\t");
    Serial.print(counts2,DEC);
    Serial.print(" ips,\t");
    Serial.println(cpm2,2);
  #endif

  #ifdef DEBUG
    Serial.println("Versand gestartet...");
  #endif
  //Ethernet.begin(mac); delay(1000);
  //client.connect(server, 80); delay(1000);
  #ifdef DEBUG
    Serial.println("connecting...");
  #endif


  if (client.connect(server, 80)==-1) {
    Serial.println("-1");
  }
  
  if (client.connect(server, 80)==-2) {
    Serial.println("-2");
  }
  
  if (client.connect(server, 80)==-3) {
    Serial.println("-3");
  }
  
  if (client.connect(server, 80)==-4) {
    Serial.println("-4");
  }
  
  if (client.connect(server, 80)) {
     #ifdef DEBUG
       Serial.print("localIP:     ");
       Serial.println(Ethernet.localIP());
       Serial.print("subnetMask:  ");
       Serial.println(Ethernet.subnetMask());
       Serial.print("gatewayIP:   ");
       Serial.println(Ethernet.gatewayIP());
       Serial.print("dnsServerIP: ");
       Serial.println(Ethernet.dnsServerIP());
       Serial.println("connected..."); Serial.println("");
     #endif
    client.print("GET /upload_data.php?zuluft=");
    client.print(cpm1);
    client.print("&&abluft=");
    client.print(cpm2);
    client.print(" HTTP/1.0\r\n");
    client.print("Host: ");
    client.print(server);
    client.println("\r\nUser-Agent: arduino-ethernet\r\nConnection: close\r\n\r\n");
    client.stop();
  } else {
    #ifdef DEBUG
      Serial.println("connection failed");
    #endif
  }
}

The code starts correctly. The serial monitor shows the following lines:

Starte Device
MillisMessbeginn: 8314, MillisMessende: 10314
MillisDifferenz: 2000
Sonde 1: 0 ips, 0.00
Sonde 2: 0 ips, 0.00
MillisDifferenz: 2000
Sonde 1: 0 ips, 0.00
Sonde 2: 0 ips, 0.00
MillisDifferenz: 2000
Sonde 1: 0 ips, 0.00
Sonde 2: 0 ips, 0.00
MillisDifferenz: 2000
Sonde 1: 0 ips, 0.

This means: The code starts, shows start and end of the measurement and the deviation and the measurements (no sensor activated).
The lines with “Sonde 1” and “Sonde 2” are properly showed from the void loop and the function DatenSenden().
BUT: In the last lines of “Sonde 1” and “Sonde 2” the code crashes, and the ethernet-connection is not established.

Does someone see the problem in my code?

Thank you very much for your help!

Serial.print(F("Sonde 1:\t" = );

Verify/Compile in Arduino 1.6.11 (IDE) flags this line with the error expected ')' before ';' token.

Missing the second closing parenthesis? Serial.print(F("Sonde 1:\t"));

Hello,

thank you - I already changed this. Unfortunately the code still crashes. I uploaded the last version of the script to the attachment (and changed floats to unsigned long). I’m afraid without any response of the compiler I’m lost :confused:

Thanks for every help!

Skript.ino (5.92 KB)

Hello again,

I have reorganised the code, so I hope it is better understandable for you now!

#include <UIPEthernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = { "www.abc.de"};
EthernetClient client;

#define DEBUG

#define IntervallMessung 10000
#define InterruptPin1 2
#define InterruptPin2 3
volatile unsigned long MillisMessbeginn = 0;
volatile unsigned long MillisMessende = 0;
volatile unsigned long MillisDifferenz = 0;
volatile unsigned long counts1 = 0;
volatile unsigned long counts2 = 0;
volatile float cpm1 = 0;
volatile float cpm2 = 0;


void setup() {
  Ethernet.begin(mac);
  #ifdef DEBUG
    Serial.begin(9600); // only use serial when debugging
  #endif

VariablenZuruecksetzen();
pinMode(InterruptPin1, INPUT_PULLUP);
pinMode(InterruptPin2, INPUT_PULLUP);
attachInterrupt( digitalPinToInterrupt(InterruptPin1), MesseImpulse1, RISING);
attachInterrupt( digitalPinToInterrupt(InterruptPin2), MesseImpulse2, RISING);
} 


void loop() {

  if ( millis() >= MillisMessende && millis() >= MillisMessbeginn ) //prüft, ob die Messzeit abgelaufen ist
  {
  noInterrupts();

  MillisDifferenz = millis() - MillisMessbeginn; //Tatsächliche Messzeit
  cpm1 = (float)counts1 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 1
  cpm2 = (float)counts2 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 2

  #ifdef DEBUG
    Serial.print(F("MillisDifferenz: "));
    Serial.println(MillisDifferenz);
    Serial.print(F("Sonde 1:\t"));
    Serial.print(counts1);
    Serial.print(F(" counts,\t"));
    Serial.print(cpm1);
    Serial.println(F(" cpm"));
    Serial.print(F("Sonde 2:\t"));
    Serial.print(counts2);
    Serial.print(F(" counts,\t"));
    Serial.print(cpm2);
    Serial.println(F(" cpm"));
  #endif

DatenSenden();
VariablenZuruecksetzen();

  interrupts();
  };


  if ( millis() < MillisMessbeginn ) //prüft, ob die Laufzeit zurückgesprungen ist
  {
  noInterrupts();
    VariablenZuruecksetzen();
  interrupts();
  }

Ethernet.maintain();
}


void MesseImpulse1() {
  counts1++;
}

void MesseImpulse2() {
  counts2++;
}

void VariablenZuruecksetzen() {
  counts1 = 0; // setzt die Zähler zurück
  counts2 = 0; // setzt die Zähler zurück
  MillisMessbeginn = millis(); //Zeitpunkt zum Start der Messsung
  MillisMessende = MillisMessbeginn + IntervallMessung; //Zeitpunkt zum Beenden der Messung

  #ifdef DEBUG
    Serial.print(F("\nMillisMessbeginn: "));
    Serial.print(MillisMessbeginn);
    Serial.print(F(", MillisMessende: "));
    Serial.println(MillisMessende);
  #endif
}

void DatenSenden()
{
//  Serial.println(F("\nconnecting...\n"));

  if (client.connect(server, 80)) {

     Serial.print(F("localIP:     "));
     Serial.println(Ethernet.localIP());
     Serial.print(F("subnetMask:  "));
     Serial.println(Ethernet.subnetMask());
     Serial.print(F("gatewayIP:   "));
     Serial.println(Ethernet.gatewayIP());
     Serial.print(F("dnsServerIP: "));
     Serial.println(Ethernet.dnsServerIP());
     Serial.println(F("connected...\n"));

    client.print(F("GET /upload.php?zuluft="));
    client.print(cpm1);
    client.print(F("&&abluft="));
    client.print(cpm2);
    client.print(F(" HTTP/1.0\r\nHost: "));
    client.print(server);
    client.println(F("\r\nConnection: close\r\n\r\n"));
  } else {
    Serial.println(F("connection failed"));
  }


  if (!client.connected()) {
    Serial.println(F("\ndisconnecting."));
    client.stop();
  }
}

I even changed ther serial.print with the (F(xyz))-function, and because I was afraid to overburden the memory I changed to an Arduino Mega.
Does anybody have an idea to help me?

attachInterrupt( digitalPinToInterrupt(InterruptPin1), MesseImpulse1, RISING);

The input to the digitalPinToInterrupt() function is NOT the interrupt number!

  noInterrupts();

  MillisDifferenz = millis() - MillisMessbeginn; //Tatsächliche Messzeit
  cpm1 = (float)counts1 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 1
  cpm2 = (float)counts2 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 2

  #ifdef DEBUG
    Serial.print(F("MillisDifferenz: "));

Do NOT do Serial.print()s or floating point arithmetic with interrupts disabled. ALL that you should be doing with interrupts disabled is copying and resetting variables. NOTHING more.

I'll read more of it when you have corrected the fundamental flaws in the code.

Hello PaulS,

ad 1) You are right - I have used the instructions at https://www.arduino.cc/en/Reference/AttachInterrupt

ad 2) That’s the perfect tip - the code is working after some small changes! Originally I was afraid of doing a web-request without “noInterrupts();”, because interrupts might have disturbed the request.
Now I have inserted two additional functions to “attach” and “detach” the InterruptPins before starting the web-request. Probably that’s no elegant way to solve it, but missing some signals for a time of less than one second is ok for my application.

Here’s my sketch - maybe you see some potential to optimize it:

#include <UIPEthernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = { "www.abc.de"};
EthernetClient client; //setzt Pointer

//#define DEBUG

#define IntervallMessung 60000 //Wie lange wird vor Auswertung gemessen
#define InterruptPin1 2
#define InterruptPin2 3
volatile unsigned long MillisMessbeginn = 0; //Wann hat die Messung gestartet?
volatile unsigned long MillisMessende = 0; //Wann soll Messung enden?
volatile unsigned long MillisDifferenz = 0; //Misst Messzeit
volatile unsigned long counts1 = 0; //Signal-Zähler
volatile unsigned long counts2 = 0;
volatile float cpm1 = 0; //Count pro Zeit
volatile float cpm2 = 0;


void setup() {
  Ethernet.begin(mac); //Startet die Netzwerkverbindung
  #ifdef DEBUG
    Serial.begin(9600); // only use serial when debugging
  #endif

VariablenZuruecksetzen();
pinMode(InterruptPin1, INPUT_PULLUP); //Setzt Pin als Input mit Eingangswiderstand
pinMode(InterruptPin2, INPUT_PULLUP);
InterruptPinsAktivieren(); //Setzt Interrupts für die Inputs
}


void loop() {

  if ( millis() >= MillisMessende && millis() >= MillisMessbeginn ) //prüft, ob die Messzeit abgelaufen ist
  {
  InterruptPinsDeaktivieren(); // noInterrupts();

  MillisDifferenz = millis() - MillisMessbeginn; //Tatsächliche Messzeit
  cpm1 = (float)counts1 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 1
  cpm2 = (float)counts2 * 1000 * 60 / MillisDifferenz; //Counts pro Minute für Sonde 2

  #ifdef DEBUG
    Serial.print(F("MillisDifferenz: "));
    Serial.println(MillisDifferenz);
    Serial.print(F("Sonde 1:\t"));
    Serial.print(counts1);
    Serial.print(F(" counts,\t"));
    Serial.print(cpm1);
    Serial.println(F(" cpm"));
    Serial.print(F("Sonde 2:\t"));
    Serial.print(counts2);
    Serial.print(F(" counts,\t"));
    Serial.print(cpm2);
    Serial.println(F(" cpm"));
  #endif

  DatenSenden();
  VariablenZuruecksetzen();

  InterruptPinsAktivieren(); // interrupts();
  };


  if ( millis() < MillisMessbeginn || MillisMessbeginn > MillisMessende) //prüft auf Laufzeitfehler
  {
  noInterrupts();
    VariablenZuruecksetzen();
  interrupts();
  }


Ethernet.maintain(); //Erneuert DHCP
}


void MesseImpulse1() {
  counts1++;
}

void MesseImpulse2() {
  counts2++;
}

void InterruptPinsAktivieren() {
  attachInterrupt( digitalPinToInterrupt(InterruptPin1), MesseImpulse1, RISING);
  attachInterrupt( digitalPinToInterrupt(InterruptPin2), MesseImpulse2, RISING);
}

void InterruptPinsDeaktivieren() {
  detachInterrupt( digitalPinToInterrupt(InterruptPin1));
  detachInterrupt( digitalPinToInterrupt(InterruptPin2));
}

void VariablenZuruecksetzen() {
  counts1 = 0; // setzt die Zähler zurück
  counts2 = 0; // setzt die Zähler zurück
  MillisMessbeginn = millis(); //Zeitpunkt zum Start der Messsung
  MillisMessende = MillisMessbeginn + IntervallMessung; //Zeitpunkt zum Beenden der Messung

  #ifdef DEBUG
    Serial.print(F("\nMillisMessbeginn: "));
    Serial.print(MillisMessbeginn);
    Serial.print(F(", MillisMessende: "));
    Serial.println(MillisMessende);
  #endif
}

void DatenSenden()
{//  Serial.println(F("\nconnecting...\n"));

  if (client.connect(server, 80)) {
  #ifdef DEBUG
    Serial.print(F("localIP:     "));
    Serial.println(Ethernet.localIP());
    Serial.print(F("subnetMask:  "));
    Serial.println(Ethernet.subnetMask());
    Serial.print(F("gatewayIP:   "));
    Serial.println(Ethernet.gatewayIP());
    Serial.print(F("dnsServerIP: "));
    Serial.println(Ethernet.dnsServerIP());
    Serial.println(F("connected...\n"));
  #endif

    client.print(F("GET /upload.php?zuluft="));
    client.print(cpm1);
    client.print(F("&&abluft="));
    client.print(cpm2);
    client.print(F(" HTTP/1.0\r\nHost: "));
    client.print(server);
    client.println(F("\r\nConnection: close\r\n\r\n"));
  } else {
    Serial.println(F("connection failed"));
  }


  if (!client.connected()) {
    Serial.println(F("\ndisconnecting."));
    client.stop();
  }
}

At least it’s running for 24h hours now :wink:

Thank’s a lot!