Ethernet diagnosis help

The EtherTen combines an Uno-equivalent Arduino-compatible board and Wiznet-based Ethernet support, along with a microSD card slot and Power-over-Ethernet support. [Product page]
Joined:Sat Jul 14, 2012 1:53 am
Location:Dee Why NSW
Re: Ethernet diagnosis help

Post by ngp99 » Thu May 02, 2013 4:37 am

Amongst all that writing and pictures, I couldn't find a circuit, so I submit this for approval by those who would prefer to see one.
Hardware Reset.jpg

Joined:Thu Apr 25, 2013 10:07 pm

Re: Ethernet diagnosis help

Post by drewgarth » Thu May 02, 2013 10:10 am

Hi NGP99, thanks for that schematic. I haven't had a chance to review in any under the pump getting my day job done this time :)

I downloaded the Eagle files yesterday from that site and I just took a screen grab of the schematic and attached it below.
Schematics of 555 time hardware reset of RST pin

Joined:Sat Jul 14, 2012 1:53 am
Location:Dee Why NSW

Re: Ethernet diagnosis help

Post by ngp99 » Thu May 02, 2013 11:58 pm

Gawd... so THAT's where it was...

I thought Eagles were just PCB layouts.


Joined:Thu Apr 25, 2013 10:07 pm

Re: Ethernet diagnosis help

Post by drewgarth » Sat May 04, 2013 12:40 am

Yeah, its a bit strange to have not at least posted a schematic on that website.
But yes, if an Eagle PCB has been done properly it is based on the Schematic, so its a useful tool.

Just for the sake of completeness, i have just created a new pendrive linux. Ubuntu 13.04, did a clean install of the Arduino IDE from the Software Centre (which at the moment is at 1.03).

And tried a simple watchdog timer set for 8 seconds. I can confirm that the 8s watchdog does work.
Well at in so far as a soft reset goes

Likewise on windows with version 1.04 of the IDE the 8s watchdog also triggers.

My current plans are to build the 555 electronic reset timer into a ProtoShield, which will also tidy up some of my connections to my external sensors.

I will then reset once daily with the the 555 circuit and for good measure I will use the watchdog in its more usual form throughout my code to catch any code hangups. I've ordered the bits, so hopefully I will have another testing arduino up and running in a week or so....

Joined:Sat Jul 14, 2012 1:53 am
Location:Dee Why NSW

Re: Ethernet diagnosis help

Post by ngp99 » Wed May 08, 2013 2:15 pm

Stuff about millis roll-over here,122413.0.html

I am using the Jaycar water flow meter. It appears that the counting method leaves a bit to be desired.

Joined:Thu Apr 25, 2013 10:07 pm

Re: Ethernet diagnosis help

Post by drewgarth » Thu May 16, 2013 9:55 am

Hi guys,
well i've had some success with using an external 555 timer circuit as outlined earlier in this thread....Its taken me a few days longer, as I had to find time to re-code for the change from COSM to Xively...though, i do like the new API.

I've mounted the 555 timer circuit on a ProtoShield. I used a dremel to cut out part of the PCB to clear the ethernet socket on the etherten. So for this application the Freetronics shield works a treat. (the sparkfun one has other components in the way on the PCB)

Its the first time i've played with any protoshield...clearly with a bit more thought i could have tidied up the layout...but hey, it works :)
I've also included the 8s watchdog timer. Having said that the Xively client sometimes triggers the watchdog, purely because it takes more than 8s sometimes so at the moment I have to work around this by disabling the watchdog for the Xively datastream push...A work in progess.

The code below may be of use :)

Fingers crossed when i get back to my remote location in June, I will install the test device and it will work happily ever after :)

Code: Select all

This program reads the analogue inputs and computes voltage and current from sensors.

On boot, it connects to the internet, reads the NTP time.
If unavailable it sets the time to be an assumed time assumed to be the standard time for resetting, set by a variable to 9am. In this way it will
continue to function as designed on a 24 hour cycle.

This system uses a 555 reset timer connected to PIN 7 and triggering the reset.
As this is a hardware reset, it resets both the MCU and the W5100 Ethernet

This system also employs a Watchdog timer set for 8 seconds. 
If a bit of code locks up it will reset. The exception being the Xively Client.

Again if the time isnt available via NTP it sets it to be the reset time on the basis that will be close to when the reset triggered.
If the reset is triggered accidentally, then the "Reset-time" is as good as any other arbiarty time to bases further logic on 

The only "accumulated" data is the summed up amp hours and these reset once per day.
If the watchdog is triggering too regularly the system will function, but the accumulated hours will 
obviously reset each time.

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <Dns.h>
#include <avr/wdt.h> //Watchdog Timer Suitable for Uno only....2s max timer on Linux
#include <utility/w5100.h> // Allows tailoring of ethernet timeout. Important for watchdog
#include <HttpClient.h>
#include <Xively.h>

//location or user specifc settings
char xivelyKey[] = "   SET THIS YOURSELF";
#define FEEDID         SET THIS YOURSELF  // replace your feed ID
byte mac[] = {SET THIS YOURSELF};

int reset_hour=9;  //time used to reset Summed Amps
int resetPin = 7;
int day_reset=0; // Used to toggle whether or not the system has been throug the reset loop.
int current_hour; // used to store the hour using the hour() function so logic is based on a variable rather than a function
float Vref=5.07; // reference voltage
float sty_h=.010; //V / amp   sensitivity of 200a sensor
float sty_l=.040; //V / amp   sensitivity of 50a sensor
unsigned long elapsed_time_start=0;
unsigned long last_interval_calculated;
float summed_amps;
float amp_hours;
unsigned long elapsed_time;
unsigned long loop_timer;
unsigned long loop_counter_day;
float voltage; // voltage of battery
float power;
float current_best; // current based on most useful sensor
float current_l; // calculated current from 50amp sensor
float current_h; // caluculated current from 200amp sensor

// Definition of variables for averaging
const int numReadings = 10;
int readingsVolt[numReadings];
int readingsCurrent_l[numReadings];// the readings from the analog input
int readingsCurrent_h[numReadings];
int index = 0;                  // the index of the current reading
int totalVolt = 0;             // the running total
int totalCurrent_l=0;
int totalCurrent_h=0;
int averageVolt = 0;                // the average
int averageCurrent_l =0;
int averageCurrent_h =0;

//Xively strings for aggregating values for upload to the datastream
char sensorAmpHours[] = "AmpHours";
char sensorBestAmps[] = "Current";
char sensorVoltage[] = "Voltage";
char sensorTime[] = "Time";
char sensorPower[] = "Power";
XivelyDatastream datastreams[] = {
  XivelyDatastream(sensorAmpHours, strlen(sensorAmpHours), DATASTREAM_FLOAT),
  XivelyDatastream(sensorBestAmps, strlen(sensorBestAmps), DATASTREAM_FLOAT),
  XivelyDatastream(sensorVoltage, strlen(sensorVoltage), DATASTREAM_FLOAT),
  XivelyDatastream(sensorPower, strlen(sensorPower), DATASTREAM_FLOAT),
  XivelyDatastream(sensorTime, strlen(sensorTime), DATASTREAM_INT)
// Finally, wrap the datastreams into a feed
XivelyFeed feed(FEEDID, datastreams, 5 /* number of datastreams */);

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// initialize the library instance:
EthernetClient client;
XivelyClient xivelyclient(client);

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 15*1000; //delay between updates to

//TIME Related SETUP Info
unsigned int localPort = 8888;      // local port to listen for UDP packets
//IPAddress timeServer(192, 43, 244, 18); // NTP server
IPAddress timeServer;
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
time_t prevDisplay = 0; // when the digital clock was displayed
const  long timeZoneOffset = 36000L; // set this to the offset in seconds to your local time;

void setup() {
digitalWrite(resetPin, LOW);   // make sure the reset circuit doesn't get triggered
pinMode(resetPin, OUTPUT);
digitalWrite(resetPin, LOW);   // make sure the reset circuit doesn't get triggered

delay( 250 );   // allow some time (250 ms) after powerup and sketch start, for the Wiznet W5100 Reset IC to release and come out of reset.
  Serial.begin(9600); // start the serial port
 //Initialise averaging array to 0 
   for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readingsVolt[thisReading] = 0;     
    readingsCurrent_l[thisReading] = 0; 
    readingsCurrent_h[thisReading] = 0; 

 //Start Ethernet connection using Fixed IP
 Ethernet.begin(mac, ip);
 // lookup time server ip
   DNSClient dns;
  if(dns.getHostByName("",timeServer)) {
    Serial.print(F("NTP server ip :"));
  else Serial.print(F("dns lookup failed"));
//time set to be the reset_time for example 9am on an arbitary date
//this might help, if the system reboots using a watchdog at the reset time, then this 
//will ensure that an approximately useful time is provided in-case ntp fails.

sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
if ( Udp.parsePacket() ) {  
    // We've received a packet, read the data from it,NTP_PACKET_SIZE);  // read the packet into the buffer
    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    // combine the four bytes (two words) into a long integer
   // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;              
    // now convert NTP time into everyday time:
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;     
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears + timeZoneOffset;  
    time_t t = epoch;
    Serial.println("ran through time loop");
//these lines reduce the ethernet timeout from 30 seconds to about 3 seconds 
 //important for watchdog timer.
W5100.setRetransmissionTime(0x07D0); // Set the ethernet timeout
W5100.setRetransmissionCount(3);      //set the number of attempts
wdt_enable(WDTO_8S); // Enable watchdog timer Reset every 8 seconds

void loop() {
wdt_reset(); //Reset the watchdog timeout..
float a2_l; // used in current caluclation low
float a3_h; // used in current calculation high
int SensorValue_l;
int SensorValue_h;
int sensorValue;

unsigned long av_reset;
float temp_value;

/* Calculations based on millis()...reset is based on time */

if(millis() > loop_timer){
     loop_timer=millis()+200; //200 = 200 read sensors 5 times per per second

  // subtract the last reading:
  totalVolt = totalVolt - readingsVolt[index];   
  totalCurrent_l = totalCurrent_l - readingsCurrent_l[index]; 
  totalCurrent_h = totalCurrent_h - readingsCurrent_h[index]; 
  // read from the sensor:  
  readingsVolt[index] = analogRead(A0); 
  readingsCurrent_l[index] = analogRead(A2); //read 50a sensor
  readingsCurrent_h[index] = analogRead(A3); //read 200a sensor

  // add the reading to the total:
  totalVolt= totalVolt + readingsVolt[index];  
  totalCurrent_l= totalCurrent_l + readingsCurrent_l[index]; 
  totalCurrent_h= totalCurrent_h + readingsCurrent_h[index];   
  // advance to the next position in the array:  
  index = index + 1;       
    // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;  
  // calculate the average:
  averageVolt = totalVolt / numReadings;
  sensorValue = averageVolt;
 // Serial.println(averageVolt);
  averageCurrent_l = totalCurrent_l / numReadings;
 // Serial.println(SensorValue_l);
  averageCurrent_h = totalCurrent_h / numReadings; 
 // Serial.println(SensorValue_h);
     a2_l=Vref/1023; // reference volts per count
     a3_h=a2_l; // reference volts per count
     voltage=a2_l; // reference volts per count

     current_h=a3_h - current_h;
     current_l=current_l/sty_l; // current in amps
     current_h=current_h/sty_h; // current in amps

     voltage = voltage*sensorValue;
     voltage = voltage*  (19.93+2.98) / 2.98;

    //pick which sensor to use and base current_best on that
    //positive currents
      if(current_l > 40){
            if(current_l >= 0)
    //negative currents
      if(current_l < -40){
            if(current_l < 0)
     //Calculate the power based on the best current
     power = voltage * current_best;

    loop_counter_day = loop_counter_day +1;

    elapsed_time=elapsed_time/1000; //in seconds

If the current hour is the reset_hour  then if the system timer has been running for more than one hours
then perform a reset. In that way if the system has just booted at the reset hour...the system timer will not have run long enough to allow a reboot.
Otherwise it would reboot continuously during the reset hour. The downside is that if it is booted just prior to the reset hour, it wont reset until the following day...big deal :)

        if(current_hour == reset_hour){ 
          if(millis() > 3610000){   // 3610000 1 hour 10 seconds in milliseconds
                Serial.println("in reset loop");
                  digitalWrite(resetPin, HIGH); //Reset pin HIGH triggers 555 reset timer circuit

}   /////End IF for calculations

wdt_reset(); //Reset the watchdog timeout..

/////Now Create Xively datastream from variables

  // if you're not connected, and postingInterval seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    wdt_disable(); //disable watchdog to allow for DNS and network issues
  Serial.println("Uploading it to Xively");
  int ret = xivelyclient.put(feed, xivelyKey);
  Serial.print("xivelyclient.put returned ");
  lastConnectionTime = millis();
        wdt_enable(WDTO_8S); //re-enable watchdog timer

  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();


// send an NTP request to the time server at the given address 
unsigned long sendNTPpacket(IPAddress& address)
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp: 		   
  Udp.beginPacket(address, 123); //NTP requests are to port 123

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(" ");
  Serial.print(" ");
  Serial.print(" ");

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  if(digits < 10)

Freetronics Staff
Freetronics Staff
Joined:Tue Apr 09, 2013 11:19 pm
Location:Melbourne, Australia

Re: Ethernet diagnosis help

Post by angusgr » Fri May 17, 2013 6:23 am

Nice one!

Post Reply