Is Ethernet shield for Nano usable in any way?



  • Hi all!

    It's not really a technical problem but i wanted to ask you.
    I have a Deek-Robot W5100 Ethernet Shield for Nano. My question is, for what it is usable? 🙂
    I've created a very simple sketch with MySensors (W5100 Ethernet + MQTT + DHCP + MY DEBUG messages, quite typcial setup) + 2 relay messages.
    Debug build even won't fit into 30kB of flash 🙂
    Adding optimization, turning off My debug drops usage to 24kB (78% of flash).
    Room for application is so small, that i don't know for what this shield is used for 🙂

    By the way, do you know any small boards compatible (like nano) with ethernet, with more flash ?



  • @NeoX

    I use a Nano, Ethernet, LCD display, and GPS for an NTP server on my isolated network to provide the time for [suspect] cameras.

    #define VER 12.2
    bool debug = false;  // must be true to have debug statements go to serial
    /*
      NTP Time Server:
      Modified by Gregg Ferry
      using softwareserial instead of Serial1
    
      using GY-GPS6MV2
     
     This code is in the public domain.
    
     ver 12
       time server gets time from Arduino clock instead of from gps
     */
    #define enableEthernet false
    #define enableGPS true
    #define enableDisplay true
    #define minimizeSerialTraffic true
    
    #if enableEthernet
    // ethernet
    
    #include <SPI.h>           // needed for Arduino versions later than 0018
    #include <Ethernet.h>
    #include <EthernetUdp.h>   // UDP library from: bjoern@cs.stanford.edu 12/30/2008
    // Time Server MAC address
    byte mac[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
    // NTP Server public IP Address
    IPAddress ip(192, 168, 2, 130);
    // Time Server Port
    #define NTP_PORT 123
    unsigned int localPort = 123;
    static const int NTP_PACKET_SIZE = 48;
    // buffers for receiving and sending data
    byte packetBuffer[NTP_PACKET_SIZE]; 
    // An Ethernet UDP instance 
    EthernetUDP Udp;
    int packetSize;
    
    // NTP since 1900/01/01
    //#include <PGMWrap.h>
    //const uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //const or compiler complains
    const uint8_t daysInMonth [] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //const or compiler complains
    const unsigned long seventyYears = 2208988800UL; // to convert unix time to epoch
    #endif
    
    #if enableGPS
    // GPS
    
    #include <TinyGPS++.h>
    //GPS instance
    TinyGPSPlus tinyGPS;
    
    #include <NeoSWSerial.h>
    //#include <SoftwareSerial.h>
    #define rxPin 5
    #define txPin 4
    NeoSWSerial GPSSerial(rxPin, txPin); // CONNECT BT RX PIN TO ARDUINO txPin | CONNECT BT TX PIN TO ARDUINO rxPin
    char incharBefore=255;
    char inchar=255;
    #endif
    
    #if enableDisplay
    // Display
    
    #include "SSD1306Ascii.h"
    #include "SSD1306AsciiAvrI2c.h"
    #define I2C_ADDRESS 0x3C
    SSD1306AsciiAvrI2c oled;
    #endif
    bool TimeHasBeenSet = false;
    bool firstPass = true;
    
    
    //Time
    
    #include <Timezone.h>
    //#include "Time.h"
    TimeChangeRule myDST = {"PDT", Second, Sun, Mar, 2, -420};    // Daylight time = UTC - 7 hours
    TimeChangeRule mySTD = {"PST", First, Sun, Nov, 2, -480};     // Standard time = UTC - 8 hours
    Timezone myTZ(myDST, mySTD);
    TimeChangeRule *tcr;        // pointer to the time change rule, use to get TZ abbrev
    time_t local;
    
    String timeString = "hh:mm:ss";
    String dateString = "yyyy MMM dd";
    const String localDaysOfWeek[] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" };
    const String localMonthsOfYear[] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
    uint8_t localDayOfWeek;
    uint8_t previousHour = 0;
    uint8_t previousMinute = 0;
    uint8_t previousSecond = 0;
    unsigned long timestamp1970;
    
    //-----------------------------------------------------------------------------------printTimes
    void printTimes(){
        Serial.print(F("GPS   "));
        Serial.print(tinyGPS.date.year());Serial.print(F("/"));
        Serial.print(tinyGPS.date.month());Serial.print(F("/"));
        Serial.print(tinyGPS.date.day());Serial.print(F(" "));
        Serial.print(tinyGPS.time.hour());Serial.print(F(":"));
        Serial.print(tinyGPS.time.minute());Serial.print(F(":"));
        Serial.println(tinyGPS.time.second());
    
        Serial.print(F("UTC   "));
        Serial.print(year());Serial.print(F("/"));
        Serial.print(month());Serial.print(F("/"));
        Serial.print(day());Serial.print(F(" "));
        Serial.print(hour());Serial.print(F(":"));
        Serial.print(minute());Serial.print(F(":"));
        Serial.println(second());
    
        Serial.print(F("local "));
        Serial.print(year(local));Serial.print(F("/"));
        Serial.print(month(local));Serial.print(F("/"));
        Serial.print(day(local));Serial.print(F(" "));
        Serial.print(hour(local));Serial.print(F(":"));
        Serial.print(minute(local));Serial.print(F(":"));
        Serial.println(second(local));
    
        Serial.print(F("      "));
        Serial.print(dateString);Serial.print(F(" "));
        Serial.println(timeString);
    
    }
    //-----------------------------------------------------------------------------------setTimeAndDateStrings
    void setTimeAndDateStrings(){
    
      local = myTZ.toLocal(now(), &tcr); // two days ago -172800
      char buf[32];
      
      sprintf(buf, "%.2d:%.2d:%.2d",hour(local), minute(local), second(local));
      timeString = String(buf);
      
    //  char m[4];    // temporary storage for month string (DateStrings.cpp uses shared buffer)
    //  strcpy(m, monthShortStr(month(local)));
    //  sprintf(buf, "%.2d %s %d",day(local), m, year(local));
    //  dateString = String(buf);
      
      sprintf(buf, "%.2d ",day(local));
      dateString = String(buf);
      dateString += localMonthsOfYear[month(local)-1];
      sprintf(buf," %d",year(local));
      dateString += String(buf);
      
      localDayOfWeek = weekday(local)-1;
    }
    
    #if enableGPS
    //-----------------------------------------------------------------------------------getgps
    static bool getgps()
    { // and update arduino time
      if (GPSSerial.available()==0) return false;
    //  while (GPSSerial.available()) {
        incharBefore = inchar;
        inchar = GPSSerial.read();
        tinyGPS.encode(inchar);
        if (!TimeHasBeenSet) Serial.print(inchar);
    //  }
      if ((inchar != 10) || (incharBefore != 13)) return false; // make sure to full NMEA statement was received
        inchar = 0; incharBefore = 0; // NMEA statement received, reset terminators
    
      if(tinyGPS.time.isValid()){
      /*  
       *   setTime(
          tinyGPS.time.hour(),
          tinyGPS.time.minute(),
          tinyGPS.time.second(),
          tinyGPS.date.day(),
          tinyGPS.date.month(),
          tinyGPS.date.year()
        );
        */
          int hh=tinyGPS.time.hour();
          int mm=tinyGPS.time.minute();
          int ss=tinyGPS.time.second();
          int DD=tinyGPS.date.day();
          int MM=tinyGPS.date.month();
          int YY=tinyGPS.date.year();
          setTime(hh,mm,ss,DD,MM,YY);
        
        local = myTZ.toLocal(now(), &tcr); //get the local time
        setTimeAndDateStrings();
    
        if (!TimeHasBeenSet) printTimes();
        TimeHasBeenSet = true;
        
        return true;
      }
      else {
        return false;
      }
    }
    #endif
    
    #if enableDisplay
    //-----------------------------------------------------------------------------------displayGPStimeSetTheTime
    void displayGPStimeSetTheTime(bool TimeSetByGPS){
      oled.setCursor(0,0);             // Start at top-left corner
      if (TimeSetByGPS) oled.print(F(" ")); else oled.print(F("!")); 
    }
    //-----------------------------------------------------------------------------------displayAwaitingGPS
    void displayAwaitingGPS() {
      oled.clear();
      oled.setCursor(0,0);             // Start at top-left corner
      oled.println(F("NTP Server"));
      oled.println(F(" Awating"));
      oled.println(F("  GPS Lock "));
      Serial.println(F(" Awating GPS Lock "));
    }
    
    //-----------------------------------------------------------------------------------displayNewDay
    void displayNewDay(){
      previousHour = hour(local);
      previousMinute= minute(local);
      previousSecond = second(local);
    
      oled.clear();
      oled.setCursor(12,0);             // center time string
      oled.print(timeString);
    
      uint8_t s = (10-localDaysOfWeek[localDayOfWeek].length())*6;
      oled.setCursor(s,3);
      oled.print(localDaysOfWeek[localDayOfWeek]);
    
      oled.setCursor(0,6);
      oled.print(dateString);
    }
    //-----------------------------------------------------------------------------------displayTime
    void displayTime(){
      // digital clock display of the time
      if ((second(local)==0 && minute(local)==0 && hour(local)==0) || firstPass){ // new day
        firstPass = false;
        displayNewDay();
      }
      else {
        if (hour(local) != previousHour){
          previousHour = hour(local);
          oled.setCursor(12,0);
          oled.print(timeString);
        }
        else {
          if (minute(local) != previousMinute){
            previousMinute= minute(local);
            oled.setCursor(48,0);
            oled.print(timeString.substring(3));
          }
          else {
            if (second(local) != previousSecond){
              previousSecond = second(local);
              oled.setCursor(84,0);
              oled.print(timeString.substring(6));
            }
          }
        }
      }
    }
    // send to serial monitor
    #else
    void displayGPStimeSetTheTime(bool TimeSetByGPS){
    }
    void displayAwaitingGPS() {
      Serial.println(F(" Awating GPS Lock "));
    }
    void displayTime(){
    #if !minimizeSerialTraffic
      Serial.println();
      printTimes();
    #endif
    }
    #endif
    
    //-----------------------------------------------------------------------------------setup
    #if enableEthernet
    void setupEthernet(){
      // start the Ethernet and UDP:
      Ethernet.begin(mac,ip);
      Udp.begin(localPort);
      Serial.print(Ethernet.localIP()); Serial.print(F(" "));Serial.println(NTP_PORT);
    }
    #endif
    
    #if enableGPS
    void setupGPS(){
      GPSSerial.begin(9600); // start GPS module UART
      // Disable everything but $GPRMC
      // Note the following sentences are for UBLOX NEO6MV2 GPS 
      GPSSerial.write("$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n");
      GPSSerial.write("$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n");
      GPSSerial.write("$PUBX,40,GSV,0,0,0,0,0,0*59\r\n");
      GPSSerial.write("$PUBX,40,GGA,0,0,0,0,0,0*5A\r\n"); 
      GPSSerial.write("$PUBX,40,GSA,0,0,0,0,0,0*4E\r\n");
    }
    #endif
    
    #if enableDisplay
    void setupDisplay(){
      oled.begin(&Adafruit128x64, I2C_ADDRESS);
      oled.setFont(System5x7);
      oled.set2X();
    }
    #endif
    
    void setup() {
      Serial.begin(115200);
      Serial.print("NTP Server with display version ");Serial.println(VER);
    
    #if enableDisplay
      setupDisplay();
    #endif
      displayAwaitingGPS();
    
    #if enableEthernet
      setupEthernet();
    #endif
    
    #if enableGPS
      setupGPS();
    #endif
    
    }
    //-----------------------------------------------------------------------------------loop
    void loop() {
      /*
      while (Serial.available()){
        char inChar = Serial.read();
        if (inChar == 'd' || inChar == 'D') {
          debug = !debug;
          if (debug) Serial.println(F("debug is ON"));else Serial.println(F("debug is off"));
        }
      }
      */
    
    #if enableGPS
      if (getgps()){
        if(TimeHasBeenSet) displayTime();
      }
    #endif
        
    #if enableEthernet
      // if there's data available, read a packet
      packetSize = Udp.parsePacket();
      if(packetSize) processNTP();
    #endif
    
    
    }
    
    #if enableEthernet
    
    //-----------------------------------------------------------------------------------numberOfSecondsSince1900Epoch
    unsigned long int numberOfSecondsSince1900Epoch(uint16_t y, uint8_t m, uint8_t d, uint8_t h, uint8_t mm, uint8_t s) {
      if (y >= 1970)
        y -= 1970;
      uint16_t daysLocal = d;
      for (uint8_t i = 1; i < m; ++i)  daysLocal += daysInMonth[i - 1];
    //  for (uint8_t i = 1; i < m; ++i)
    //    daysLocal += pgm_read_byte(daysInMonth + i - 1);
      if (m > 2 && y % 4 == 0)
        ++daysLocal;
      daysLocal += 365 * y + (y + 3) / 4 - 1;
      return daysLocal*24L*3600L + h*3600L + mm*60L + s + seventyYears;
    }
    //-----------------------------------------------------------------------------------processNTP
    void processNTP() {
    
      Udp.read(packetBuffer,NTP_PACKET_SIZE);
      IPAddress Remote = Udp.remoteIP();
      int PortNum = Udp.remotePort();
    
    /*
    if (debug) {
      Serial.println();
      Serial.print("Received UDP packet size ");
      Serial.println(packetSize);
      Serial.print("From ");
    
      for (int i =0; i < 4; i++)
      {
        Serial.print(Remote[i], DEC);
        if (i < 3)
        {
          Serial.print(".");
        }
      }
      Serial.print(", port ");
      Serial.print(PortNum);
    
      byte LIVNMODE = packetBuffer[0];
      Serial.print("  LI, Vers, Mode :");
      Serial.print(packetBuffer[0],HEX);
    
      byte STRATUM = packetBuffer[1];
      Serial.print("  Stratum :");
      Serial.print(packetBuffer[1],HEX);
    
      byte POLLING = packetBuffer[2];
      Serial.print("  Polling :");
      Serial.print(packetBuffer[2],HEX);
    
      byte PRECISION = packetBuffer[3];
      Serial.print("  Precision :");
      Serial.println(packetBuffer[3],HEX);
    
      for (int z = 0; z < NTP_PACKET_SIZE; z++) {
        Serial.print(packetBuffer[z],HEX);
        if (((z+1) % 4) == 0) {
          Serial.println();
        }
      }
      Serial.println();
    
    } // end of debug statements
    */
    
      packetBuffer[0] = 0b00100100;   // LI, Version, Mode
      packetBuffer[1] = 1 ;   // stratum
      packetBuffer[2] = 6 ;   // polling minimum
      packetBuffer[3] = 0xFA; // precision
    
      packetBuffer[7] = 0; // root delay
      packetBuffer[8] = 0;
      packetBuffer[9] = 8;
      packetBuffer[10] = 0;
    
      packetBuffer[11] = 0; // root dispersion
      packetBuffer[12] = 0;
      packetBuffer[13] = 0xC;
      packetBuffer[14] = 0;
    
    /*  
        uint16_t y=year();
        uint8_t m=month();
        uint8_t d=day();
        uint8_t h=hour();
        uint8_t mm=minute();
        uint8_t s=second();
      if (y >= 1970) y -= 1970;
      uint16_t daysLocal = d;
      for (uint8_t i = 1; i < m; ++i)  daysLocal += daysInMonth[i - 1];
      if (m > 2 && y % 4 == 0) ++daysLocal;
      daysLocal += 365 * y + (y + 3) / 4 - 1;
      timestamp1970 = daysLocal*24L*3600L + h*3600L + mm*60L + s + seventyYears;
    */
    
    //    uint16_t utcYY=year();
    //    uint8_t utcMM=month();
    //    uint8_t utcDD=day();
    //    uint8_t utchh=hour();
    //    uint8_t utcmm=minute();
    //    uint8_t utcss=second();
      
    //  timestamp1970 = numberOfSecondsSince1900Epoch(utcYY,utcMM,utcDD,utchh,utcmm,utcss);
    //  timestamp1970 = numberOfSecondsSince1900Epoch(2022,4,30,10,10,10);
    timestamp1970 = numberOfSecondsSince1900Epoch(year(),month(),day(),hour(),minute(),second());
    
     /*  
     *   
      timestamp1970 = numberOfSecondsSince1900Epoch(
        tinyGPS.date.year(),
        tinyGPS.date.month(),
        tinyGPS.date.day(),
        tinyGPS.time.hour(),
        tinyGPS.time.minute(),
        tinyGPS.time.second()
      );
       */
      unsigned long tempval = timestamp1970;
    
      packetBuffer[12] = 71; //"G";
      packetBuffer[13] = 80; //"P";
      packetBuffer[14] = 83; //"S";
      packetBuffer[15] = 0; //"0";
    
      // reference timestamp1970
      packetBuffer[16] = (tempval >> 24) & 0XFF;
      tempval = timestamp1970;
      packetBuffer[17] = (tempval >> 16) & 0xFF;
      tempval = timestamp1970;
      packetBuffer[18] = (tempval >> 8) & 0xFF;
      tempval = timestamp1970;
      packetBuffer[19] = (tempval) & 0xFF;
    
      packetBuffer[20] = 0;
      packetBuffer[21] = 0;
      packetBuffer[22] = 0;
      packetBuffer[23] = 0;
    
    
      //copy originate timestamp from incoming UDP transmit timestamp
      packetBuffer[24] = packetBuffer[40];
      packetBuffer[25] = packetBuffer[41];
      packetBuffer[26] = packetBuffer[42];
      packetBuffer[27] = packetBuffer[43];
      packetBuffer[28] = packetBuffer[44];
      packetBuffer[29] = packetBuffer[45];
      packetBuffer[30] = packetBuffer[46];
      packetBuffer[31] = packetBuffer[47];
    
      //receive timestamp
      packetBuffer[32] = (tempval >> 24) & 0XFF;
      tempval = timestamp1970;
      packetBuffer[33] = (tempval >> 16) & 0xFF;
      tempval = timestamp1970;
      packetBuffer[34] = (tempval >> 8) & 0xFF;
      tempval = timestamp1970;
      packetBuffer[35] = (tempval) & 0xFF;
    
      packetBuffer[36] = 0;
      packetBuffer[37] = 0;
      packetBuffer[38] = 0;
      packetBuffer[39] = 0;
    
      //transmitt timestamp
      packetBuffer[40] = (tempval >> 24) & 0XFF;
      tempval = timestamp1970;
      packetBuffer[41] = (tempval >> 16) & 0xFF;
      tempval = timestamp1970;
      packetBuffer[42] = (tempval >> 8) & 0xFF;
      tempval = timestamp1970;
      packetBuffer[43] = (tempval) & 0xFF;
    
      packetBuffer[44] = 0;
      packetBuffer[45] = 0;
      packetBuffer[46] = 0;
      packetBuffer[47] = 0;
    
    
      // Reply to the IP address and port that sent the NTP request
    
      Udp.beginPacket(Remote, PortNum);
      Udp.write(packetBuffer,NTP_PACKET_SIZE);
      Udp.endPacket();
    }
    #else
    void processNTP() {}
    #endif
    

Log in to reply
 

Suggested Topics

  • 87
  • 1
  • 10
  • 2
  • 7
  • 8

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts