[SOLUCIONADO] Modulo ENC28J60 consulta de hora con protocolo ntp

Hola.
Tengo un problema con la consulta de hora ,resulta que cuando esta por dhcp y realizo el dnsLookup todo funciona pero cuando realizo la configuración manual de ip no

la parte que no me funciona del todo bien es:

{
  Serial.println("\n[Get Static IP]");
  if (ether.begin(sizeof Ethernet::buffer, myMac,10) == 0) moduleStatus = 255;
  ether.staticSetup(myip, gwip, dnsip, mask);
  //ether.dnsLookup(ntpServer);  
}

Algo me debe estar faltando o estoy haciendo mal porque si habilito ether.dnsLookup(ntpServer); funciona pero la idea es que lo quiero poner en una red donde no hay servidor de DNS y el servidor de NTP es interno

el código del programa que estoy usando para probar es:

#include <EtherCard.h>  // https://github.com/njh/EtherCard

const byte myMac[] PROGMEM = { 0x00, 0x01, 0x02, 0x03, 0x06, 0x05 };

// ipparaconfiguracin manual
static  byte myip[] = { 192,168,1,29 };// { 192,168,1,203 };
static  byte mask[]= { 255,255,255,0 };
static  byte gwip[]= { 192,168,1,1 };
static  byte dnsip []= { 192,168,1,1 };

//IP de servidoresde hora
const char ntpServer[] PROGMEM = "ar.pool.ntp.org";  //Servidor NTP uy.pool.ntp.org    ntp.bit.nl 
static byte ntpServer1[]  = {162,159,200,1 }; // ar.pool.ntp.org
static byte ntpServer2[]  ={192,168,1,3}; // ntp_interno
//static byte ntpServer2[] = {213,136,12,53}; // ntp_interno


const long  gmtOffset_sec = -10800;// para definir el horario Urugauy -3 elvalor esta en segundos


const unsigned int NTP_REMOTEPORT = 123;             // NTP requests are to port 123
const unsigned int NTP_LOCALPORT = 8888;             // Local UDP port to use
const unsigned int NTP_PACKET_SIZE = 48;             // NTP time stamp is in the first 48 bytes of the message
byte Ethernet::buffer[350];                          // Buffer must be 350 for DHCP to work

byte moduleStatus;
unsigned long Tiempo;
uint8_t ntpIp[IP_LEN];


#define Boton1 3 // entrada de pulso para consulta de reloj
#define Boton2 4 // SW para selexcionar  ntp internoo externo
#define Boton3 5 // SW para selexcionar  dhcp o ip manual

boolean Ant_Boton1;
unsigned long BT1_Tiempo;

//#define reset()       __asm__ __volatile__ ("JMP  0x0000 \n")

void setup() {

pinMode(Boton2,INPUT_PULLUP);//ntpinternoo externo
pinMode(Boton3,INPUT_PULLUP);//dhcp o ip manual

Serial.begin(1200);
Serial.println(F("\n[EtherCard NTP Client]"));

if (digitalRead(Boton3) == HIGH) // en HIGH ip manual
{
  Serial.println("\n[Get Static IP]");
  if (ether.begin(sizeof Ethernet::buffer, myMac,10) == 0) moduleStatus = 255;
  ether.staticSetup(myip, gwip, dnsip, mask);
  //ether.dnsLookup(ntpServer);  
}
else // configuracion por dhcp
{
  Serial.println("\n[Get DHCP]");
  if   (ether.begin(sizeof Ethernet::buffer, myMac) == 0) moduleStatus = 254;
  ether.dhcpSetup() ;                    ut
  ether.dnsLookup(ntpServer) ;           
}

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);


  ether.udpServerListenOnPort(&udpReceiveNtpPacket, NTP_LOCALPORT);

  
if (digitalRead(Boton2) == LOW)ether.printIp("NTP1: ", ntpServer1);
else  ether.printIp("NTP2: ", ntpServer2);

if (digitalRead(Boton2) == LOW) sendNTPpacket(ntpServer1);  
else  sendNTPpacket(ntpServer2);   


}
void loop() {

//boton1
    if (digitalRead(Boton1) == LOW)            //Pregunta si el pulsador está presionado
     {
      if (Ant_Boton1 == LOW)                  //Pregunta si el pulsador está presionado
        {
          if ((millis()-BT1_Tiempo)>=800)     //Pregunta si el pulsador está presionado
            {
               BT1_Tiempo=millis();
                  Tiempo=millis(); 
              if (digitalRead(Boton2) == LOW) sendNTPpacket(ntpServer1);  
              else  sendNTPpacket(ntpServer2);  
            }
        else{
          Ant_Boton1= LOW; 
          BT1_Tiempo=millis();
            }
       Ant_Boton1= LOW; 
      }
    else{
       Ant_Boton1= HIGH;
        }
    }
  
ether.packetLoop(ether.packetReceive());


 //delay(50);
}
// send an NTP request to the time server at the given address
void sendNTPpacket(const uint8_t* remoteAddress) {
  // buffer to hold outgoing packet
  byte packetBuffer[ NTP_PACKET_SIZE];
  // 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:
  ether.sendUdp(packetBuffer, NTP_PACKET_SIZE, NTP_LOCALPORT, remoteAddress, NTP_REMOTEPORT );
   
  //Serial.println("NTP request sent.");
}
void udpReceiveNtpPacket(uint16_t dest_port, uint8_t src_ip[IP_LEN], uint16_t src_port, const char *packetBuffer, uint16_t len) {
 //Serial.print("NTP response received.");

  // the timestamp starts at byte 40 of the received packet and is four bytes,
  // or two words, long. First, extract 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;
  // 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;
  // print Unix time:
 // Serial.print("Unix UTC time = ");
 // Serial.println(epoch);
  epoch=epoch + gmtOffset_sec; //para pasar a horario local



  // Serial.print("The Local time is ");   // UTC es el tiempo universal o GMT
    Serial.print((epoch  % 86400L) / 3600);   // Horas (86400 segundos por dia)  - Se haya el modulo
   // Serial.print(':');
    if ( ((epoch % 3600) / 60) < 10 ) {
     // Añadir un 0 en los primeros 9 minutos
     Serial.print('0');
    }
    Serial.print((epoch  % 3600) / 60); // Minutos:
   // Serial.print(':');
    if ( (epoch % 60) < 10 ) {
     // Añadir un 0 en los primeros 9 minutos
     Serial.print('0');
    }
    Serial.println(epoch % 60);              // Segundos
    
Serial.println (millis()-Tiempo);
}

muchas gracias por cualquier sujerencia

Una pregunta tonta

Si el problema es cuando tienes IP fija ¿seguro que todos los parámetros son correctos? ya se que parece muy tonta pero mira, yo me instalé en el celular la app fing, que me busca las conexiones en mi red, y me había pasado un rato intentando configurar la smart tv de mi esposa para priorizarle el ancho de banda y no me dí cuenta que me empecinaba en una ip que era falsa, con esa app vi que no aparecía la tv hasta que me dí cuenta que le ponía 192.168.1 y resulta que mi server de dns está ofreciendo 192.168.0, algo tonto, pero me llevó un rato darme cuenta por empecinarme, o como decía Staling, ninguna fuerza es más poderosa que la inercia

Haz la prueba tonta. Copia los datos de la ip que te da por DCHP y asignalos manualmente. Tienen que funcionar. En caso de que no funcione, ahí puedes hallar el error

Saludos

TonyDiana ,bosoft
Muchas gracias por su tiempo si la red esta bien configurada lo parámetros de red que toma con el dhcp son los mismo que con la configuración manual con excepción de ip que esta unas ip mas arriba

Si le saco el comentario a la linea //ether.dnsLookup(ntpServer); funciona sin problema
y no tiene nada que ver la dirección ntpServer puede ser cualquier nombre de equipo de la red o de algún sitio de internet, y la dirección donde consulto la hora es ntpServer1 o ntpServer2 que la idea es cambiarla a un servidor interno cuando funcione como quiero

pienso que ether.dnsLookup algo mas esta habilitando para que funcione el resto y lamentable mente no me doy cuenta

saludos

Para comenzar esa MAC

const byte myMac[] PROGMEM = { 0x00, 0x01, 0x02, 0x03, 0x06, 0x05 };

no me gusta, se que viene por defecto en el ejemplo y te funciona con DHCP.
Prueba con otra. Mira lo que te cuento a continuación:
Recuerdo a Jopapa que le sugirió a otro forero usar la mac del Router cambiando alguna de los valores hexa que desees. Con solo cambiar 1 o 2 es suficiente.
Si eso no tiene que ver... continuemos con otras cosas.

Tené mucho cuidado con ar.pool.ntp.org a mi siempre me dio problemas y uso los otros

server 2.ar.pool.ntp.org
server 3.south-america.pool.ntp.org
server 2.south-america.pool.ntp.org

Incluso en la PC me da problemas.

Creo que tu problema es de otra índole

Surbyte
muchas gracias por tu comentario no se avía escrito contestando pero no se porque no se publico pero va denuedo

con respecto ala mac si te doy la razón sin duda hay que tener cuidado
lo de ntp ar fue un ejemplo ya que el de uy no funciona

Les cuento como son las pruebas para ver si me puedo explicar
si configuro las ip estáticas en una red que no tiene internet solo el servidor de NTP no me funciona pero si le habilito la linea ether.dnsLookup(ntpServer);y habilito un servidor de dns que responda con cualquier ip no importa la que sea ejemplo pregunto por google.com y en dns contesta con la ip 1.2.3.4 funciona y al consulta la hora al ntp funciona sin problema

Estuve tratando de mirar la librería sobre dnsLookup, pero no logro entender todo hay cosas que no las comprendo igualmente no logre encontrar ninguna pista

saludos

Vamos primero con códigos seguros y luego pruebas la modificación en el tuyo.
Que tal este Tutorial Módulo Ethernet ENC28J60 y Arduino donde usa tu módulo con ip fija.

Hola
llegue a la conclusión que la librería tiene algún problema o me falta declarar algo, con ip estática y consultas udp , realice capturas de trafico el paquete con la consulta lo manda per no esta empaquetando de forma correcta no coloca las Mac de la interfase local como la del destino
Por lo tanto el paquete no tiene un destino valido dela red adjunto la captura
Al habilitarle la lineal del ether.dnsLookup coloca las mac y llega a su destino
Me decidí a buscar otras librerías y encontré UIPEthernet que funciona de forma correcta para lo que estaria usando

#include <UIPEthernet.h>


IPAddress timeServer(192, 168, 1, 2); // 
IPAddress timeServer2(162,159,200,1); // 

static  byte myip[] = { 192,168,1,203 };//
static  byte mask[]= { 255,255,255,0 };
static  byte gwip[]= { 192,168,1,1 };
static  byte dnsip []= { 192,168,1,1 };


const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
const unsigned int NTP_REMOTEPORT = 123;  // puerto remoto del NTP
unsigned int localPort = 8888;            // local port to listen for UDP packets

uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05};

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 

void setup() 
{
 Serial.begin(1200);

 // start Ethernet and UDP

 
 Ethernet.begin(mac,  myip,  dnsip,  gwip,  mask);

 Serial.println(Ethernet.localIP());
 Serial.println(Ethernet.subnetMask());
 Serial.println(Ethernet.gatewayIP());
 Serial.println(Ethernet.dnsServerIP());

 Udp.begin(localPort);
}

void loop()
{
 sendNTPpacket(timeServer); // send an NTP packet to a time server


   // wait to see if a reply is available
 delay(1000);  
 if ( Udp.parsePacket() ) {  
   // We've received a packet, read the data from it
   Udp.read(packetBuffer,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;  
   Serial.print("Seconds since Jan 1 1900 = " );
   Serial.println(secsSince1900);               

   // now convert NTP time into everyday time:
   Serial.print("Unix 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;  
   // print Unix time:
   Serial.println(epoch);                               


   // print the hour, minute and second in UTC:
   Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
   Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
   Serial.print(':');  
   if ( ((epoch % 3600) / 60) < 10 ) {
     // In the first 10 minutes of each hour, we'll want a leading '0'
     Serial.print('0');
   }
   Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
   Serial.print(':'); 
   if ( (epoch % 60) < 10 ) {
     // In the first 10 seconds of each minute, we'll want a leading '0'
     Serial.print('0');
   }
   Serial.println(epoch %60); // print the second
   
       // print the hour, minute and second in PDT:
   Serial.print("The PDT time is ");       // UTC is the time at Greenwich Meridian (GMT)
   Serial.print(((epoch  % 86400L) / 3600)-7); // print the hour (86400 equals secs per day)
   Serial.print(':');  
   if ( ((epoch % 3600) / 60) < 10 ) {
     // In the first 10 minutes of each hour, we'll want a leading '0'
     Serial.print('0');
   }
   Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
   Serial.print(':'); 
   if ( (epoch % 60) < 10 ) {
     // In the first 10 seconds of each minute, we'll want a leading '0'
     Serial.print('0');
   }
   Serial.println(epoch %60); // print the second
 }
 // wait ten seconds before asking for the time again
 delay(1000); 
}

// 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, NTP_REMOTEPORT); //NTP requests are to port 123
 Udp.write(packetBuffer,NTP_PACKET_SIZE);
 Udp.endPacket(); 
}

Gracias por la info

Yo siempre comienzo con los ejemplos de una librería. Si los ejemplos no funcionan entonces no continúo con dicha librería y como has visto, a veces ocurren cosas raras.
Generalmente se deben a actualizaciones del IDE y de muchas cosas que desconocemos, en el proceso algunas cosas dejan de funcionar.
Acostumbrate a poner siempre en tu código la versión de la librería que estas usando y del IDE, sin olvidar de donde la descargaste, sea con el Administrador de librerías o de algun sitio.

Todo eso te ayudará no solo ahora sino dentro de 6 meses cuando la pruebes y no funcione. Hay muchos que vienen mas tarde y por no ser prolijos y detallistas se pasan dias y semanas buscando cosas que no funcionan y lo único que debe hacer es retrotraerse a lo que hizo tiempo atras.

Muchas gracias a todos por los comentarios y las sugerencias

No tiene nada que ver con el hilo pero como se edita el titulo para poder mencionar que quedo solucionad ?

Leyendo las normas se explica.

Vas a More, luego Modify, y puedes editar asi el post sobre el que te ubiques incialmente.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.