Problems getting arduino with ENC28J60 online

Hi there,

I have a simple Arduino Nano V3 connected to a ENC28J60 board (using the jeelabs EtherCard library). My target is to send some sensor data values (temperature, relais settings, ...) via a HTTP-GET-request to my local web-server (Ubuntu 12.04) and to receive some small commands in the answer.

Hardware-wiring seems OK, because the Arduino gets an IP-Address from the server and there's some traffic visible in tcpdump on the server. But in the serial monitor there seems somthing wrong :frowning: First some code:

default.h:

#ifndef DEFAULT_H
#define DEFAULT_H

#if ARDUINO >= 100
#include "Arduino.h"       // for delayMicroseconds, digitalPinToBitMask, etc
#else
#include "WProgram.h"      // for delayMicroseconds
#include "pins_arduino.h"  // for digitalPinToBitMask, etc
#endif

typedef struct {
  byte           anl_no;               // own device identifier
  byte           heatercount;          // number of heaters if more than one, use a PID algorithm
  DeviceAddress  Sensors[4];           // onewire addresses of the 4 possible temperature sensors
  uint8_t        src_ip[4];            // own IP address of the sender
  uint8_t        dst_ip[4];            // IP address of the server
  char           dst_path[200];        // Destination path for the API
} SettingsData;

//#######################
// Pin Definitions
//#######################
#define ONEWIREPIN  3           // Pin für den Datenkanal des One-Wire-Bus
#define SENSORPIN   3           // Pin für den OneWire-Bus mit den Temp.-Sensoren
#define ETHERPIN   10           // Pin für den Ethernet-Anschluss
//#######################
#endif

webclient.ino:

#include <EtherCard.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <PID_v1.h>
#include"Default.h"

// global variables
static byte      relaisstate = 0;         // act. State of the relais-output
static float     akttempsC[4] = { -50.0, -50.0, -50.0, -50.0 };
static byte      aktorder;                // actual order from the server 
static uint32_t  lastConnectionTime;           // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 5*1000;  // delay between updates, in milliseconds

/*-----( Declare objects )-----*/
OneWire oneWire(SENSORPIN);                             // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);                    // Pass our oneWire reference to Dallas Temperature. 

// Local settings
SettingsData    settings = {
    1,
    3,
    { 
      { 0x28, 0x04, 0xD5, 0x4D, 0x04, 0x00, 0x00, 0xAD }, 
      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
    },
    { 192, 168, 100, 200 },
    { 192, 168, 100, 1 },
    "/Temperatures/connect.php"
  };

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x07,0x02,0x07,0xAE };
byte Ethernet::buffer[500];
char website[] PROGMEM = "rover";

void setup(void) {
  uint8_t epromtest;

  Serial.begin(9600);
  Serial.println("starting setup");
  
  // have the settings ever been written ? read the first byte of the settings to check 
  // that. otherwise take the default values
  /*
  epromtest = EEPROM.read(0);
  if (epromtest != 0 && epromtest != 255) {
    EEPROM_readAnything(0, settings);
    Serial.println("Read settings from EEPROM...");
  }
  */
  
  if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) 
    Serial.println( "Failed to access Ethernet controller");

  if (!ether.dhcpSetup()) {
    Serial.println("DHCP failed, using static configuration");
    if (!ether.staticSetup(settings.src_ip))
      Serial.println("Failed to set IP address");
  }

  if (!ether.dnsLookup(website)) {
    Serial.println("DNS failed, setting fixed srvIP ");
    ether.copyIp(ether.hisip, settings.dst_ip);
  }
  
  // print actual settings
  Serial.println("Setup");
  Serial.println("-------------------------------------------");
  Serial.print("Anlage :");
  Serial.println(settings.anl_no);
  Serial.print("Heizer :");
  Serial.println(settings.heatercount);
  Serial.print("Wasser :");
  Serial.println(settings.max_water);
  ether.printIp("SrcIP  :", settings.src_ip);   
  ether.printIp("DstIP s :", settings.dst_ip);
  ether.printIp("DstIP i :", ether.hisip);
  Serial.print("Pfad   :");
  Serial.println(settings.dst_path);
  Serial.println("-------------------------------------------");

  if (settings.Sensors[0][0] != 0) sensors.setResolution(settings.Sensors[0], 9); 
  if (settings.Sensors[1][0] != 0) sensors.setResolution(settings.Sensors[1], 9); 
  if (settings.Sensors[2][0] != 0) sensors.setResolution(settings.Sensors[2], 9); 
  if (settings.Sensors[3][0] != 0) sensors.setResolution(settings.Sensors[3], 9); 
  
  lastConnectionTime = millis();
}



void loop(void) {
  delay(30);
  ether.packetLoop(ether.packetReceive());
    
  Serial.println("Loop");
  Serial.println("-------------------------------------------");
  ether.printIp("IP       : ", ether.myip);
  ether.printIp("GW       : ", ether.gwip);  
  ether.printIp("DNS      : ", ether.dnsip);  
  ether.printIp("SRV soll : ", settings.dst_ip);
  ether.printIp("SRV ist  : ", ether.hisip);
  Serial.println("-------------------------------------------");
  
  Serial.print("Millis :");
  Serial.println(millis());
  Serial.print("Last   :");
  Serial.println(lastConnectionTime);
  
  if(millis() > lastConnectionTime) {
    Serial.println("Should send a request...");
    httpRequest();
    lastConnectionTime = millis() + postingInterval;    // note the time that the connection was made:
  } else {
    Serial.println("waiting");
  }

  delay(800);
}

/* ===========================================================
   Callback-function for browseUrl
   =========================================================== */
static void response_callback(byte status, word off, word len) { 
  Serial.print((const char*) Ethernet::buffer + off);
}

/* ===========================================================
   httpRequest
   =========================================================== */
void httpRequest() {
  char srequest[128] = {0};        // zusammengebastelter Request
  char string_temp[4][8] = {"0.0","0.0","0.0","0.0"};

  Serial.print("sending request :");
  
  ether.printIp("SRV: ", ether.hisip);
  
  dtostrf(akttempsC[0], 4, 1, string_temp[0]);
  if (akttempsC[1] != -50.0) dtostrf(akttempsC[1], 4, 1, string_temp[1]);
  if (akttempsC[2] != -50.0) dtostrf(akttempsC[2], 4, 1, string_temp[2]);
  if (akttempsC[2] != -50.0) dtostrf(akttempsC[3], 4, 1, string_temp[3]);

  // Normalen Request an den Server senden
  sprintf(srequest, "?a=%d&t1=%s&t2=%s&t3=%s&t4=%s&r=%d", 
          settings.anl_no, &string_temp[0], &string_temp[1], 
          &string_temp[2], &string_temp[3], relaisstate);
  Serial.print("params          :");
  Serial.println(srequest);

  ether.browseUrl(PSTR("/Temperatures/connect.php"), srequest, website, response_callback);
}

(After some errors on my side) the code compiles OK and is sent to the Arduino (with about 20K of available 30K)

The strange behaviour starts in the Serial monitor. Sometimes it seems to be stuck in the setup() routine and prints out only the half of all the debug messages. Sometimes (just at this moment) all seems ok, but nothing appears in the webserver-logs.

First the tcpdump snippet:

01:45:07.828715 IP 192.168.100.36.3064 > rover.hoover.home.http: Flags [S], seq 19456, win 768, options [mss 550], length 0
01:45:07.828834 ARP, Request who-has 192.168.100.36 tell rover.hoover.home, length 28
01:45:08.826995 ARP, Request who-has 192.168.100.36 tell rover.hoover.home, length 28
01:45:09.826996 ARP, Request who-has 192.168.100.36 tell rover.hoover.home, length 28

But there's nothing in the apache logs. And where's the cause to the repeated ARP - requests ? Is there any chance to

  • get the traffic more detailed?
  • get more debug output ?
  • get a bit more "process stability"

thank you all in advance,

Harry

I suspect that you are running out of memory.

Keep the string literals out of SRAM:
Serial.println(F("starting setup"));

Thanks. I tried the F() - macro and deleted some of the debug message lines. Code size increased slightly.

I added

char webpath[] PROGMEM = "/Temperatures/connect.php";

and changed the function httprequest to :

  char srequest[128] = {0};        // zusammengebastelter Request
  char string_temp[4][8] = {"0.0","0.0","0.0","0.0"};

  Serial.print("sending request :");
  
  dtostrf(akttempsC[0], 4, 1, string_temp[0]);
  if (akttempsC[1] != -50.0) dtostrf(akttempsC[1], 4, 1, string_temp[1]);
  if (akttempsC[2] != -50.0) dtostrf(akttempsC[2], 4, 1, string_temp[2]);
  if (akttempsC[2] != -50.0) dtostrf(akttempsC[3], 4, 1, string_temp[3]);

  // Normalen Request an den Server senden
  sprintf(srequest, "?a=%d&t1=%s&t2=%s&t3=%s&t4=%s&r=%d", 
          settings.anl_no, &string_temp[0], &string_temp[1], 
          &string_temp[2], &string_temp[3], relaisstate);
  Serial.print(F("params          :"));
  Serial.println(srequest);

  ether.browseUrl(webpath,srequest, website, response_callback);

Now I see debug lines on every request that should be sent to the webserver.

...
sending request :params          :?a=1&t1=-50.0&t2=0.0&t3=0.0&t4=0.0&r=0
...

But the data does not seem to pass its way to the webserver. No lines in the apache log and the tcpdump lines state a length of 0 :frowning:

20:46:01.174719 IP (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 44)
    192.168.100.36.2896 > rover.hoover.home.http: Flags [S], cksum 0xef9d (correct), seq 21504, win 768, options [mss 550], length 0

Any ideas, what I'm doing wrong here? Thanks in advance.

Harry