Перезагрузка роутера при зависании UNO+ECN28J60+реле

geniusltd
Offline
Зарегистрирован: 30.06.2016

Есть скетч написан под shield W5100, подскажите не могу поправить под ethercard (ECN28J60) И Возможно ли это? 

#include <Arduino.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <stdint.h>

#define pinRelay 7                              // Сюда включим реле

#define timeIntervalToNextAttempt 60000        // Интервал обычной проверки NTP 1 минута
#define timeIntervalIfFirstAttemptFall  60000  // Интервал повторной проверки после перезагрузки 1 минута
#define timeIntervalIfSecondAttemptFall 120000 // Интервал если перезагрузка не помогла 2 минуты.


#define timeZone 2	                            // Временная зона, где мы живем

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x79, 0xF0 }; // MAC address для шилда.
//IPAddress ip = ( 192, 168, 1, 177 );

unsigned int localPort = 8888;                  // local port для прослушки UDP пакетов
IPAddress timeServer(132, 163, 4, 101);         // сервер NTP time-a.timefreq.bldrdoc.gov
IPAddress timeServer02(128, 138, 140, 44);      // сервер NTP utcnist.colorado.edu
IPAddress timeServer03(216, 228, 192, 69);      // сервер NTP nist-time-server.eoni.com
const int NTP_PACKET_SIZE= 48;                  // NTP time stamp - первые 48 байтов пакета
byte packetBuffer[ NTP_PACKET_SIZE];            // Буфер для входящих и исходящих пакетов
EthernetUDP Udp;                                // Создаем UDP
const unsigned long seventyYears = 2208988800UL;// Время Unix началось 1 января 1970 года. В секундах это 2208988800

unsigned long timeWhenCheckNTP ;                // Время, когда пора проверить NTP сервер.
// unsigned long timeWhenGotNTP;
String timeNowIs = "";                          // Здесь храним запись текущего времени;

uint8_t attemptCounter = 0;                     // Считаем попытки достучаться до вервера;
bool isNeedToReboot = false;                    // Надо ли перегружать роутер?
// Объявляем функции:
unsigned long sendNTPpacket(IPAddress& address);    // Функция отправки запроса NTP
void fUDPReadAndGotTime(void);                  // Функция разбора ответа NTP


void setup()
{
    pinMode(pinRelay, OUTPUT);
    digitalWrite(pinRelay, LOW);
    Serial.begin(9600);
    //while (!Serial) {; }
    Ethernet.begin(mac, ip);

    while (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0) {                                      // start Ethernet and UDP
        Serial.println("Failed to configure Ethernet using DHCP");
        delay(1000);
    }
    Udp.begin(localPort);
    delay(5000);
    sendNTPpacket(timeServer);
    fUDPReadAndGotTime();
    timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
}

void loop() {

/***************************** Проверяем NTP, три сервера **************************/
    if (millis()> timeWhenCheckNTP) {
        sendNTPpacket(timeServer);                          // Отправляем запрос
        delay (1000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;                             // Обнуляем счетчик перезагрузок
        }
        else {
            sendNTPpacket(timeServer02);
            delay(1000);
            if (Udp.parsePacket()) {
                fUDPReadAndGotTime();
                attemptCounter = 0;
            }
            else {
                sendNTPpacket(timeServer03);
                delay(1000);
                if (Udp.parsePacket()) {
                    fUDPReadAndGotTime();
                    attemptCounter = 0;
                }
                else {                                      // Если ни один из серверов не ответил
                    isNeedToReboot = true;                  // Установка флага перезагрузки
                    attemptCounter +=1;                     // Увеличение счетчика перезагрузок
                }
            }
        }
/***************************** Определяем время следующей перезагрузки **************************/
        if (attemptCounter == 0) {                          // Если все хорошо то следующая проверка через 10 минутЖ;
            timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
        }
        if (attemptCounter == 1) {                          // Если перегрузились - проверяем через пять минут
            timeWhenCheckNTP = millis() + timeIntervalIfFirstAttemptFall;
        }
        if (attemptCounter > 1) {                           // Если перегрузка не помогла - перегружаемся каждый час
            timeWhenCheckNTP = millis() + timeIntervalIfSecondAttemptFall;
        }

/******************************* Перегружаем, если надо ****************************************/
        if(attemptCounter < 50) {                           // Перегружаемся не более двух суток
            if (isNeedToReboot) {                           // Если флаг перезагрузки установлен
                isNeedToReboot = false;                     // Сбрасываем его
                Serial.println("Relay!! Relay!! Relay!!");  // Оповещаем в сериал-порт
                digitalWrite(pinRelay, HIGH);               // Включаем реле
                delay(30000);                               // Ждем 30 секунд
                digitalWrite(pinRelay, LOW);                // Отключаем реле
            }
        }
    }
}

/********************************** Отправка пактета на сервер NTP ***************************/
unsigned long sendNTPpacket(IPAddress& address) {
    memset(packetBuffer, 0, NTP_PACKET_SIZE);                               // set all bytes in the buffer to 0
                                                                            // 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
    Udp.write(packetBuffer,NTP_PACKET_SIZE);
    Udp.endPacket();
}
/******************************** Анализ пактета от NTP **************************************/
void fUDPReadAndGotTime(void) {
    Udp.read(packetBuffer,NTP_PACKET_SIZE);                             // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);  //the timestamp starts at byte 40 of the received packet and is four bytes,
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);   // or two words, long. First, esxtract the two words:
    unsigned long secsSince1900 = highWord << 16 | lowWord;             // combine the four bytes (two words) into a long integer
    Serial.print("Seconds since Jan 1 1900 = " );                       // this is NTP time (seconds since Jan 1 1900)
    Serial.println(secsSince1900);
    Serial.print("Unix time = ");                                       // now convert NTP time into everyday time:
    unsigned long epoch = secsSince1900 - seventyYears + (timeZone*3600); // subtract seventy years + Time Zone correction:
    Serial.println(epoch);                                              // print Unix time:
    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)
        timeNowIs = (String) ((epoch  % 86400L) / 3600);
    Serial.print(':');
        timeNowIs += ":";
    if ( ((epoch % 3600) / 60) < 10 ) {                                 // In the first 10 minutes of each hour, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.print((epoch  % 3600) / 60);                                 // print the minute (3600 equals secs per minute)
        timeNowIs += (String) ((epoch  % 3600) / 60);
    Serial.print(':');
        timeNowIs += ":";
    if ( (epoch % 60) < 10 ) {                                          // In the first 10 seconds of each minute, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.println(epoch %60);                                          // print the second
        timeNowIs += (String) (epoch %60);
        Serial.println(timeNowIs);
}

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Возможно, использовать библиотеку

https://github.com/ntruchsess/arduino_uip

geniusltd
Offline
Зарегистрирован: 30.06.2016

да возможно, но не знаю как переписать скетч под данную библиотеку :( 

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Ем, все просто. заменить в начале

#include <Arduino.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <stdint.h>

на 

#include <Arduino.h>
#include <SPI.h>
#include <UIPEthernet.h>
#include <UIPUdp.h>
#include <stdint.h>

И дожно поехать. 

geniusltd
Offline
Зарегистрирован: 30.06.2016

О спасибо. Думал весь скетч нужно пересобирать под другую библиотеку...

исправил начал компиляцию, вылетело с 3мя ошибками 

ошибка первая 

 
error: 'mymac' was not declared in this scope
 while (Ether.begin(sizeof Ethernet::buffer, mymac) == 0) {      // start Ethernet and UDP
 
подбробнее
ВНИМАНИЕ: Категория '' в библиотеке UIPEthernet не является действительной. Установка на 'Uncategorized'
C:\Users\admin\Desktop\arduino\router.ino: In function 'void setup()':
router:64: error: 'Ether' was not declared in this scope
     while (Ether.begin(sizeof Ethernet::buffer, mymac) == 0) {                                      // start Ethernet and UDP
            ^
In file included from C:\Program Files (x86)\Arduino\libraries\arduino_uip-master/UIPEthernet.h:28:0,
                 from C:\Users\admin\Desktop\arduino\router.ino:13:
C:\Program Files (x86)\Arduino\libraries\arduino_uip-master/ethernet_comp.h:4:18: error: 'UIPEthernet' is not a class, namespace, or enumeration
 #define Ethernet UIPEthernet
                  ^
C:\Users\admin\Desktop\arduino\router.ino:64:31: note: in expansion of macro 'Ethernet'
     while (Ether.begin(sizeof Ethernet::buffer, mymac) == 0) {                                      // start Ethernet and UDP
                               ^
router:64: error: 'mymac' was not declared in this scope
     while (Ether.begin(sizeof Ethernet::buffer, mymac) == 0) {                                      // start Ethernet and UDP
 
                                                 ^
 
вторая ошибка
 
Udp.begin(localPort);
     ^
router:69: error: expected constructor, destructor, or type conversion before '(' token
     delay(5000);
 
          ^
router:70: error: expected constructor, destructor, or type conversion before '(' token
 
     sendNTPpacket(timeServer);
                  ^
router:71: error: expected constructor, destructor, or type conversion before ';' token
     fUDPReadAndGotTime();
                         ^
router:72: error: 'timeWhenCheckNTP' does not name a type
 
     timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
 
     ^
 
router:73: error: expected declaration before '}' token
 
 }
 
 ^
 
exit status 1
'Udp' does not name a type
 
третья ошибка
 
ВНИМАНИЕ: Категория '' в библиотеке UIPEthernet не является действительной. Установка на 'Uncategorized'
router:69: error: expected constructor, destructor, or type conversion before '(' token
 
     delay(5000);
 
          ^
 
router:70: error: expected constructor, destructor, or type conversion before '(' token
 
     sendNTPpacket(timeServer);
 
                  ^
 
router:71: error: expected constructor, destructor, or type conversion before ';' token
 
     fUDPReadAndGotTime();
 
                         ^
 
router:72: error: 'timeWhenCheckNTP' does not name a type
 
     timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
 
     ^
 
router:73: error: expected declaration before '}' token
 
 }
 
 ^
 
exit status 1
expected constructor, destructor, or type conversion before '(' token
 
vitalikost
Offline
Зарегистрирован: 28.11.2014

Только что проверил, все компилится 

#include <Arduino.h>
#include <SPI.h>
//#include <Ethernet.h>
//#include <EthernetUdp.h>
#include <stdint.h>

#include <UIPEthernet.h>
#include <UIPUdp.h>

#define pinRelay 7                              // Сюда включим реле

#define timeIntervalToNextAttempt 60000        // Интервал обычной проверки NTP 1 минута
#define timeIntervalIfFirstAttemptFall  60000  // Интервал повторной проверки после перезагрузки 1 минута
#define timeIntervalIfSecondAttemptFall 120000 // Интервал если перезагрузка не помогла 2 минуты.


#define timeZone 2	                            // Временная зона, где мы живем

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x79, 0xF0 }; // MAC address для шилда.
IPAddress ip = ( 192, 168, 1, 177 );

unsigned int localPort = 8888;                  // local port для прослушки UDP пакетов
IPAddress timeServer(132, 163, 4, 101);         // сервер NTP time-a.timefreq.bldrdoc.gov
IPAddress timeServer02(128, 138, 140, 44);      // сервер NTP utcnist.colorado.edu
IPAddress timeServer03(216, 228, 192, 69);      // сервер NTP nist-time-server.eoni.com
const int NTP_PACKET_SIZE= 48;                  // NTP time stamp - первые 48 байтов пакета
byte packetBuffer[ NTP_PACKET_SIZE];            // Буфер для входящих и исходящих пакетов
EthernetUDP Udp;                                // Создаем UDP
const unsigned long seventyYears = 2208988800UL;// Время Unix началось 1 января 1970 года. В секундах это 2208988800

unsigned long timeWhenCheckNTP ;                // Время, когда пора проверить NTP сервер.
// unsigned long timeWhenGotNTP;
String timeNowIs = "";                          // Здесь храним запись текущего времени;

uint8_t attemptCounter = 0;                     // Считаем попытки достучаться до вервера;
bool isNeedToReboot = false;                    // Надо ли перегружать роутер?
// Объявляем функции:
unsigned long sendNTPpacket(IPAddress& address);    // Функция отправки запроса NTP
void fUDPReadAndGotTime(void);                  // Функция разбора ответа NTP


void setup()
{
    pinMode(pinRelay, OUTPUT);
    digitalWrite(pinRelay, LOW);
    Serial.begin(9600);
    //while (!Serial) {; }
    Ethernet.begin(mac, ip);

/*    while (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0) {                                      // start Ethernet and UDP
        Serial.println("Failed to configure Ethernet using DHCP");
        delay(1000);
    }*/
    Udp.begin(localPort);
    delay(5000);
    sendNTPpacket(timeServer);
    fUDPReadAndGotTime();
    timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
}

void loop() {

/***************************** Проверяем NTP, три сервера **************************/
    if (millis()> timeWhenCheckNTP) {
        sendNTPpacket(timeServer);                          // Отправляем запрос
        delay (1000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;                             // Обнуляем счетчик перезагрузок
        }
        else {
            sendNTPpacket(timeServer02);
            delay(1000);
            if (Udp.parsePacket()) {
                fUDPReadAndGotTime();
                attemptCounter = 0;
            }
            else {
                sendNTPpacket(timeServer03);
                delay(1000);
                if (Udp.parsePacket()) {
                    fUDPReadAndGotTime();
                    attemptCounter = 0;
                }
                else {                                      // Если ни один из серверов не ответил
                    isNeedToReboot = true;                  // Установка флага перезагрузки
                    attemptCounter +=1;                     // Увеличение счетчика перезагрузок
                }
            }
        }
/***************************** Определяем время следующей перезагрузки **************************/
        if (attemptCounter == 0) {                          // Если все хорошо то следующая проверка через 10 минутЖ;
            timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
        }
        if (attemptCounter == 1) {                          // Если перегрузились - проверяем через пять минут
            timeWhenCheckNTP = millis() + timeIntervalIfFirstAttemptFall;
        }
        if (attemptCounter > 1) {                           // Если перегрузка не помогла - перегружаемся каждый час
            timeWhenCheckNTP = millis() + timeIntervalIfSecondAttemptFall;
        }

/******************************* Перегружаем, если надо ****************************************/
        if(attemptCounter < 50) {                           // Перегружаемся не более двух суток
            if (isNeedToReboot) {                           // Если флаг перезагрузки установлен
                isNeedToReboot = false;                     // Сбрасываем его
                Serial.println("Relay!! Relay!! Relay!!");  // Оповещаем в сериал-порт
                digitalWrite(pinRelay, HIGH);               // Включаем реле
                delay(30000);                               // Ждем 30 секунд
                digitalWrite(pinRelay, LOW);                // Отключаем реле
            }
        }
    }
}

/********************************** Отправка пактета на сервер NTP ***************************/
unsigned long sendNTPpacket(IPAddress& address) {
    memset(packetBuffer, 0, NTP_PACKET_SIZE);                               // set all bytes in the buffer to 0
                                                                            // 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
    Udp.write(packetBuffer,NTP_PACKET_SIZE);
    Udp.endPacket();
}
/******************************** Анализ пактета от NTP **************************************/
void fUDPReadAndGotTime(void) {
    Udp.read(packetBuffer,NTP_PACKET_SIZE);                             // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);  //the timestamp starts at byte 40 of the received packet and is four bytes,
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);   // or two words, long. First, esxtract the two words:
    unsigned long secsSince1900 = highWord << 16 | lowWord;             // combine the four bytes (two words) into a long integer
    Serial.print("Seconds since Jan 1 1900 = " );                       // this is NTP time (seconds since Jan 1 1900)
    Serial.println(secsSince1900);
    Serial.print("Unix time = ");                                       // now convert NTP time into everyday time:
    unsigned long epoch = secsSince1900 - seventyYears + (timeZone*3600); // subtract seventy years + Time Zone correction:
    Serial.println(epoch);                                              // print Unix time:
    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)
        timeNowIs = (String) ((epoch  % 86400L) / 3600);
    Serial.print(':');
        timeNowIs += ":";
    if ( ((epoch % 3600) / 60) < 10 ) {                                 // In the first 10 minutes of each hour, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.print((epoch  % 3600) / 60);                                 // print the minute (3600 equals secs per minute)
        timeNowIs += (String) ((epoch  % 3600) / 60);
    Serial.print(':');
        timeNowIs += ":";
    if ( (epoch % 60) < 10 ) {                                          // In the first 10 seconds of each minute, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.println(epoch %60);                                          // print the second
        timeNowIs += (String) (epoch %60);
        Serial.println(timeNowIs);
}

Незабываем сюта указат свой адрес своей подсети

IPAddress ip = ( 192, 168, 1, 177 );

geniusltd
Offline
Зарегистрирован: 30.06.2016

залил скетч, интерфейс не пингуеться, не знаю может не должен проверяем работу включаем смотрю в монитор порта 

Seconds since Jan 1 1900 = 0
Unix time = 2085985696
The UTC time is 8:28:16
8:28:16
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!

постоянно дёргает релле, видимо сети не видит

у меня первая подсеть, по этому адрес оставил 192,168,1,177

может быть дело в 10 пине?

while (ether.begin(sizeof Ethernet::buffer, mymac,10)

как его в этом коде прописать? если не он то что может быть...

vitalikost
Offline
Зарегистрирован: 28.11.2014

строку 48 закоментировать после ее вставить


  Ethernet.begin(mac);
 
  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()); 

Так хоть увидим, что подключился

geniusltd
Offline
Зарегистрирован: 30.06.2016
localIP: 192.168.1.97
subnetMask: 255.255.255.0
gatewayIP: 192.168.1.2
dnsServerIP: 192.168.1.2
Seconds since Jan 1 1900 = 0
Unix time = 2085985696
The UTC time is 8:28:16
8:28:16
Relay!! Relay!! Relay!!
 
 
 
почему то адрес не 192,168,1,177 а 97 по дшсп получил вероятно 
пинги не ходят ведёт себя также ...
 
vitalikost
Offline
Зарегистрирован: 28.11.2014

модуль работает, адрес получает, уже хорошо.

пробегаем по серверах:

C:\Users\Пользователь>ping 132.163.4.101
 
Обмен пакетами с 132.163.4.101 по с 32 байтами данных:
Превышен интервал ожидания для запроса.
Превышен интервал ожидания для запроса.
Превышен интервал ожидания для запроса.
Превышен интервал ожидания для запроса.
 
Статистика Ping для 132.163.4.101:
    Пакетов: отправлено = 4, получено = 0, потеряно = 4
    (100% потерь)
 
C:\Users\Пользователь>ping 128.138.140.44
 
Обмен пакетами с 128.138.140.44 по с 32 байтами данных:
Ответ от 128.138.140.44: число байт=32 время=178мс TTL=42
Ответ от 128.138.140.44: число байт=32 время=175мс TTL=42
Ответ от 128.138.140.44: число байт=32 время=171мс TTL=42
Ответ от 128.138.140.44: число байт=32 время=176мс TTL=42
 
Статистика Ping для 128.138.140.44:
    Пакетов: отправлено = 4, получено = 4, потеряно = 0
    (0% потерь)
Приблизительное время приема-передачи в мс:
    Минимальное = 171мсек, Максимальное = 178 мсек, Среднее = 175 мсек
 
C:\Users\Пользователь>ping 216.228.192.69
 
Обмен пакетами с 216.228.192.69 по с 32 байтами данных:
Ответ от 216.228.192.69: число байт=32 время=251мс TTL=40
Ответ от 216.228.192.69: число байт=32 время=410мс TTL=40
Превышен интервал ожидания для запроса.
Ответ от 216.228.192.69: число байт=32 время=230мс TTL=40
 
Статистика Ping для 216.228.192.69:
    Пакетов: отправлено = 4, получено = 3, потеряно = 1
    (25% потерь)
Приблизительное время приема-передачи в мс:
    Минимальное = 230мсек, Максимальное = 410 мсек, Среднее = 297 мсек
 
Первый у нас молчит, пробуем заменмить:
строка 56
sendNTPpacket(timeServer);
заменить
sendNTPpacket(timeServer1);
 
смотрим что получилось.
по коду все идет на 86 строку, а дальше на реле
geniusltd
Offline
Зарегистрирован: 30.06.2016

да забыл сказать я изначально подменил не рабочий сервер на рабочий ничего не изменилось 

изменил 

sendNTPpacket(timeServer);

заменить
sendNTPpacket(timeServer01);   верно?
 
отображение в логе изменилась, но реакция таже постоянно дёргает релюху 
 
localIP: 192.168.1.97
subnetMask: 255.255.255.0
gatewayIP: 192.168.1.2
dnsServerIP: 192.168.1.2
Seconds since Jan 1 1900 = 0
Unix time = 2085985696
The UTC time is 8:28:16
8:28:16
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!
Relay!! Relay!! Relay!!
Seconds since Jan 1 1900 = 3676898524
Unix time = 1467916924
The UTC time is 18:42:04
18:42:04
Relay!! Relay!! Relay!!
Seconds since Jan 1 1900 = 3676898591
Unix time = 1467916991
The UTC time is 18:43:11
18:43:11
Seconds since Jan 1 1900 = 3676898624
Unix time = 1467917024
The UTC time is 18:43:44
18:43:44
Seconds since Jan 1 1900 = 3676898656
Unix time = 1467917056
The UTC time is 18:44:16
18:44:16
Seconds since Jan 1 1900 = 3676898665
Unix time = 1467917065
The UTC time is 18:44:25
 
vitalikost
Offline
Зарегистрирован: 28.11.2014

Так, надо исключить нерабочий сервер, у нас тут 3 сервера.

Нужно немного переписать код с 63-90 строки, на проверку 2 серверов, или 

IPAddress timeServer(132, 163, 4, 101); заменить на рабочий сервер. 

Пока идеи кончились.

 

geniusltd
Offline
Зарегистрирован: 30.06.2016

Проблема работы или сетевого интерфейса или библиотеки <UIPUdp.h>, как бы их проверить?

сеть адрес получает, но ходит ли трафик? почему пинги не ходят? библиотека не поддерживает?

vitalikost
Offline
Зарегистрирован: 28.11.2014

Сегодня бужет на руках модуль, постараюсь проверить. 

geniusltd
Offline
Зарегистрирован: 30.06.2016

оо было бы отлично. спасибо)

wifilan
Offline
Зарегистрирован: 01.12.2014

тоже давно хотел замутить подобное устройство. но программить я почти 0.

geniusltd
Offline
Зарегистрирован: 30.06.2016

тут ещё вопрос насколько стабильно будет работать модуль ECN28J60, ну это только с практики увидим.

vitalikost
Offline
Зарегистрирован: 28.11.2014

Немгого добавли задержки, а также в случаи проверки ждем 10 мин.

#include <Arduino.h>
#include <SPI.h>
//#include <Ethernet.h>
//#include <EthernetUdp.h>
#include <stdint.h>

#include <UIPEthernet.h>
#include <UIPUdp.h>

#define pinRelay 7                              // Сюда включим реле

#define timeIntervalToNextAttempt 60000        // Интервал обычной проверки NTP 1 минута
#define timeIntervalIfFirstAttemptFall  60000  // Интервал повторной проверки после перезагрузки 1 минута
#define timeIntervalIfSecondAttemptFall 120000 // Интервал если перезагрузка не помогла 2 минуты.


#define timeZone 2	                            // Временная зона, где мы живем

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x79, 0xF0 }; // MAC address для шилда.
//IPAddress ip = ( 192, 168, 5, 177 );

unsigned int localPort = 8888;                  // local port для прослушки UDP пакетов
IPAddress timeServer(132, 163, 4, 101);         // сервер NTP time-a.timefreq.bldrdoc.gov
IPAddress timeServer02(128, 138, 140, 44);      // сервер NTP utcnist.colorado.edu
IPAddress timeServer03(216, 228, 192, 69);      // сервер NTP nist-time-server.eoni.com
const int NTP_PACKET_SIZE= 48;                  // NTP time stamp - первые 48 байтов пакета
byte packetBuffer[ NTP_PACKET_SIZE];            // Буфер для входящих и исходящих пакетов
EthernetUDP Udp;                                // Создаем UDP
const unsigned long seventyYears = 2208988800UL;// Время Unix началось 1 января 1970 года. В секундах это 2208988800

unsigned long timeWhenCheckNTP ;                // Время, когда пора проверить NTP сервер.
// unsigned long timeWhenGotNTP;
String timeNowIs = "";                          // Здесь храним запись текущего времени;

uint8_t attemptCounter = 0;                     // Считаем попытки достучаться до вервера;
bool isNeedToReboot = false;                    // Надо ли перегружать роутер?
// Объявляем функции:
unsigned long sendNTPpacket(IPAddress& address);    // Функция отправки запроса NTP
void fUDPReadAndGotTime(void);                  // Функция разбора ответа NTP


void setup()
{
    pinMode(pinRelay, OUTPUT);
    digitalWrite(pinRelay, LOW);
    Serial.begin(9600);
    //while (!Serial) {; }
    Ethernet.begin(mac);
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());


/*    while (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0) {                                      // start Ethernet and UDP
        Serial.println("Failed to configure Ethernet using DHCP");
        delay(1000);
    }*/
    Udp.begin(localPort);
    delay(5000);
    sendNTPpacket(timeServer);
    delay(2000);
    fUDPReadAndGotTime();
    timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
}

void loop() {

/***************************** Проверяем NTP, три сервера **************************/
    if (millis()> timeWhenCheckNTP) {
        Serial.println("Test servers" );
        sendNTPpacket(timeServer);                          // Отправляем запрос
        delay (2000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;   
            // Обнуляем счетчик перезагрузок
           Serial.println("good server1" );     
      }
        else {
            sendNTPpacket(timeServer02);
            delay(2000);
            if (Udp.parsePacket()) {
                fUDPReadAndGotTime();
                attemptCounter = 0;
                Serial.println("good server2" ); 
            }
            else {
                sendNTPpacket(timeServer03);
                delay(2000);
                if (Udp.parsePacket()) {
                    fUDPReadAndGotTime();
                    attemptCounter = 0;
                    Serial.println("good server3" ); 
                }
                else {                      // Если ни один из серверов не ответил
                    isNeedToReboot = true;                  // Установка флага перезагрузки
                    attemptCounter +=1;                     // Увеличение счетчика перезагрузок
                    Serial.println("not good server" ); 
                }
            }
        }
/***************************** Определяем время следующей перезагрузки **************************/
        if (attemptCounter == 0) {                          // Если все хорошо то следующая проверка через 10 минутЖ;
            timeWhenCheckNTP = millis() + timeIntervalToNextAttempt*10;
        }
        if (attemptCounter == 1) {                          // Если перегрузились - проверяем через пять минут
            timeWhenCheckNTP = millis() + timeIntervalIfFirstAttemptFall;
        }
        if (attemptCounter > 1) {                           // Если перегрузка не помогла - перегружаемся каждый час
            timeWhenCheckNTP = millis() + timeIntervalIfSecondAttemptFall;
        }

/******************************* Перегружаем, если надо ****************************************/
        if(attemptCounter < 50) {                           // Перегружаемся не более двух суток
            if (isNeedToReboot) {                           // Если флаг перезагрузки установлен
                isNeedToReboot = false;                     // Сбрасываем его
                Serial.println("Relay!! Relay!! Relay!!");  // Оповещаем в сериал-порт
                digitalWrite(pinRelay, HIGH);               // Включаем реле
                delay(30000);                               // Ждем 30 секунд
                digitalWrite(pinRelay, LOW);                // Отключаем реле
            }
        }
    }
}

/********************************** Отправка пактета на сервер NTP ***************************/
unsigned long sendNTPpacket(IPAddress& address) {
    memset(packetBuffer, 0, NTP_PACKET_SIZE);                               // set all bytes in the buffer to 0
                                                                            // 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
    Udp.write(packetBuffer,NTP_PACKET_SIZE);
    Udp.endPacket();
}
/******************************** Анализ пактета от NTP **************************************/
void fUDPReadAndGotTime(void) {
    Udp.read(packetBuffer,NTP_PACKET_SIZE);                             // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);  //the timestamp starts at byte 40 of the received packet and is four bytes,
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);   // or two words, long. First, esxtract the two words:
    unsigned long secsSince1900 = highWord << 16 | lowWord;             // combine the four bytes (two words) into a long integer
    Serial.print("Seconds since Jan 1 1900 = " );                       // this is NTP time (seconds since Jan 1 1900)
    Serial.println(secsSince1900);
    Serial.print("Unix time = ");                                       // now convert NTP time into everyday time:
    unsigned long epoch = secsSince1900 - seventyYears + (timeZone*3600); // subtract seventy years + Time Zone correction:
    Serial.println(epoch);                                              // print Unix time:
    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)
        timeNowIs = (String) ((epoch  % 86400L) / 3600);
    Serial.print(':');
        timeNowIs += ":";
    if ( ((epoch % 3600) / 60) < 10 ) {                                 // In the first 10 minutes of each hour, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.print((epoch  % 3600) / 60);                                 // print the minute (3600 equals secs per minute)
        timeNowIs += (String) ((epoch  % 3600) / 60);
    Serial.print(':');
        timeNowIs += ":";
    if ( (epoch % 60) < 10 ) {                                          // In the first 10 seconds of each minute, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.println(epoch %60);                                          // print the second
        timeNowIs += (String) (epoch %60);
        Serial.println(timeNowIs);
}

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Полчилось как-то так:

Лог:

server is at 192.168.5.45
Seconds since Jan 1 1900 = 0
Unix time = 2085985696
The UTC time is 8:28:16
8:28:16
Test servers
not good server
Relay!! Relay!! Relay!!
Test servers
not good server
Relay!! Relay!! Relay!!
Test servers
not good server
Relay!! Relay!! Relay!!
Test servers
Seconds since Jan 1 1900 = 3677912607
Unix time = 1468931007
The UTC time is 12:23:27
12:23:27
good server1
Test servers
Seconds since Jan 1 1900 = 3677912675
Unix time = 1468931075
The UTC time is 12:24:35
12:24:35
good server3
 
geniusltd
Offline
Зарегистрирован: 30.06.2016

Даже при задержке в 10 минут, при повторной проверке, перегружает, при задержке в 1 минуту вообще ничего не проверяет сразу перегружает.

Я не понимаю почему он дёргает реле когда реально есть интернет, может проблема с питанием модуля, попробую запитать его отдельно, может поможет ... 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Там все просто, если не получаем от ответ 3 серверов  перегружаем. Ответы приходят через раз... вот и дергает реле. Завтра помозгую чтобы раз 10-15 дела проверку, в слчаи недудачи толькто тогда уходил на реле, а так было 3 сек, ответов нет реле, и так по кругу...

 

geniusltd
Offline
Зарегистрирован: 30.06.2016

ага я думал он проверят 1 нет ответа, проверяет 2 нет ответа, проверяет 3 есть ответ окей...

а он проверил 1й нет ответа дёргает реле ?

не может же 3 сервера не дать ответ?

может он не успевает дождаться ответа, и дёргает релюху, а в те времена когда успевает получить ответ тогда не перегружается наверное нужно ещё увеличить делей  завтра попробую ... 

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Там по очереди перебираем 3 сервера, если все 3 не дали ответ, тогда дёргаем релюшку. Зараз сделаю простою переборку, посмотрим как стабильно они отвечают

vitalikost
Offline
Зарегистрирован: 28.11.2014

Вот что получилось:

#include <Arduino.h>
#include <SPI.h>
//#include <Ethernet.h>
//#include <EthernetUdp.h>
#include <stdint.h>

#include <UIPEthernet.h>
#include <UIPUdp.h>

#define pinRelay 7                              // Сюда включим реле

#define timeIntervalToNextAttempt 60000        // Интервал обычной проверки NTP 1 минута
#define timeIntervalIfFirstAttemptFall  60000  // Интервал повторной проверки после перезагрузки 1 минута
#define timeIntervalIfSecondAttemptFall 120000 // Интервал если перезагрузка не помогла 2 минуты.


#define timeZone 2	                            // Временная зона, где мы живем

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x79, 0xF0 }; // MAC address для шилда.
//IPAddress ip = ( 192, 168, 5, 177 );

unsigned int localPort = 8888;                  // local port для прослушки UDP пакетов
IPAddress timeServer(132, 163, 4, 101);         // сервер NTP time-a.timefreq.bldrdoc.gov
IPAddress timeServer02(128, 138, 140, 44);      // сервер NTP utcnist.colorado.edu
IPAddress timeServer03(216, 228, 192, 69);      // сервер NTP nist-time-server.eoni.com
const int NTP_PACKET_SIZE= 48;                  // NTP time stamp - первые 48 байтов пакета
byte packetBuffer[ NTP_PACKET_SIZE];            // Буфер для входящих и исходящих пакетов
EthernetUDP Udp;                                // Создаем UDP
const unsigned long seventyYears = 2208988800UL;// Время Unix началось 1 января 1970 года. В секундах это 2208988800

unsigned long timeWhenCheckNTP ;                // Время, когда пора проверить NTP сервер.
// unsigned long timeWhenGotNTP;
String timeNowIs = "";                          // Здесь храним запись текущего времени;

uint8_t attemptCounter = 0;                     // Считаем попытки достучаться до вервера;
bool isNeedToReboot = false;                    // Надо ли перегружать роутер?
// Объявляем функции:
unsigned long sendNTPpacket(IPAddress& address);    // Функция отправки запроса NTP
void fUDPReadAndGotTime(void);                  // Функция разбора ответа NTP


void setup()
{
    pinMode(pinRelay, OUTPUT);
    digitalWrite(pinRelay, LOW);
    Serial.begin(9600);
    //while (!Serial) {; }
    Ethernet.begin(mac);
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());


/*    while (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0) {                                      // start Ethernet and UDP
        Serial.println("Failed to configure Ethernet using DHCP");
        delay(1000);
    }*/
    Udp.begin(localPort);
    delay(5000);
    sendNTPpacket(timeServer);
    delay(2000);
    fUDPReadAndGotTime();
    timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
  
  int test_all=0; 
int test_1=0; 
int test_2=0; 
int test_3=0;   
    //test
   for(int i =1;i<100;i++) 
   {
            Serial.print("Test servers #-" );
            Serial.println(i);
        sendNTPpacket(timeServer);                          // Отправляем запрос
        delay (2000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
           test_1++;
            // Обнуляем счетчик перезагрузок
           Serial.println("good server1" );     
      }
           
           
           
           sendNTPpacket(timeServer02);
            delay(2000);
            if (Udp.parsePacket()) {
                fUDPReadAndGotTime();
                test_2++;
                Serial.println("good server2" ); 
            }
            
            
                sendNTPpacket(timeServer03);
                delay(2000);
                if (Udp.parsePacket()) {
                    fUDPReadAndGotTime();
                    test_3++;
                    Serial.println("good server3" ); 
                }
               
                    
        delay(5000);   
   }     

Serial.println("++++++++++++++++" );  
Serial.print("server1 - " );
Serial.println(test_1 );

Serial.print("server2 - " );
Serial.println(test_2 );

Serial.print("server3 - " );
Serial.println(test_3 );

}


void loop() {

/***************************** Проверяем NTP, три сервера **************************/
 /*       Serial.println("Test servers" );
        sendNTPpacket(timeServer);                          // Отправляем запрос
        delay (2000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
           test_1++;
            // Обнуляем счетчик перезагрузок
           Serial.println("good server1" );     
      }
           
           
           
           sendNTPpacket(timeServer02);
            delay(2000);
            if (Udp.parsePacket()) {
                fUDPReadAndGotTime();
                test_2++;
                Serial.println("good server2" ); 
            }
            
            
                sendNTPpacket(timeServer03);
                delay(2000);
                if (Udp.parsePacket()) {
                    fUDPReadAndGotTime();
                    test_3++;
                    Serial.println("good server3" ); 
                }
               
                    
        delay(5000);       */    
     
}

/********************************** Отправка пактета на сервер NTP ***************************/
unsigned long sendNTPpacket(IPAddress& address) {
    memset(packetBuffer, 0, NTP_PACKET_SIZE);                               // set all bytes in the buffer to 0
                                                                            // 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
    Udp.write(packetBuffer,NTP_PACKET_SIZE);
    Udp.endPacket();
}
/******************************** Анализ пактета от NTP **************************************/
void fUDPReadAndGotTime(void) {
    Udp.read(packetBuffer,NTP_PACKET_SIZE);                             // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);  //the timestamp starts at byte 40 of the received packet and is four bytes,
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);   // or two words, long. First, esxtract the two words:
    unsigned long secsSince1900 = highWord << 16 | lowWord;             // combine the four bytes (two words) into a long integer
    Serial.print("Seconds since Jan 1 1900 = " );                       // this is NTP time (seconds since Jan 1 1900)
    Serial.println(secsSince1900);
    Serial.print("Unix time = ");                                       // now convert NTP time into everyday time:
    unsigned long epoch = secsSince1900 - seventyYears + (timeZone*3600); // subtract seventy years + Time Zone correction:
    Serial.println(epoch);                                              // print Unix time:
    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)
        timeNowIs = (String) ((epoch  % 86400L) / 3600);
    Serial.print(':');
        timeNowIs += ":";
    if ( ((epoch % 3600) / 60) < 10 ) {                                 // In the first 10 minutes of each hour, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.print((epoch  % 3600) / 60);                                 // print the minute (3600 equals secs per minute)
        timeNowIs += (String) ((epoch  % 3600) / 60);
    Serial.print(':');
        timeNowIs += ":";
    if ( (epoch % 60) < 10 ) {                                          // In the first 10 seconds of each minute, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.println(epoch %60);                                          // print the second
        timeNowIs += (String) (epoch %60);
        Serial.println(timeNowIs);
}

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Результат 100 проверок:

++++++++++++++++
server1 - 61
server2 - 63
server3 - 67
 
Так что не всегда онт отвечают
geniusltd
Offline
Зарегистрирован: 30.06.2016

круто через раз, так понимаю не особо надёжный метод через сервера времени :( 

или для надёжности по раз 5 проверять чтоб лишний раз не пегружать 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Ну так и думаю реализовать, немного позже допишу код, зараз тестовой комп с ардуиной пока не доступен. 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Так, модернизированый код, сильно не пинать:

#include <Arduino.h>
#include <SPI.h>
//#include <Ethernet.h>
//#include <EthernetUdp.h>
#include <stdint.h>

#include <UIPEthernet.h>
#include <UIPUdp.h>

#define pinRelay 7                              // Сюда включим реле

#define timeIntervalToNextAttempt 60000        // Интервал обычной проверки NTP 1 минута
#define timeIntervalIfFirstAttemptFall  60000  // Интервал повторной проверки после перезагрузки 1 минута
#define timeIntervalIfSecondAttemptFall 120000 // Интервал если перезагрузка не помогла 2 минуты.


#define timeZone 2	                            // Временная зона, где мы живем

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x79, 0xF0 }; // MAC address для шилда.
//IPAddress ip = ( 192, 168, 5, 177 );

unsigned int localPort = 8888;                  // local port для прослушки UDP пакетов
IPAddress timeServer(132, 163, 4, 101);         // сервер NTP time-a.timefreq.bldrdoc.gov
IPAddress timeServer02(128, 138, 140, 44);      // сервер NTP utcnist.colorado.edu
IPAddress timeServer03(216, 228, 192, 69);      // сервер NTP nist-time-server.eoni.com
const int NTP_PACKET_SIZE= 48;                  // NTP time stamp - первые 48 байтов пакета
byte packetBuffer[ NTP_PACKET_SIZE];            // Буфер для входящих и исходящих пакетов
EthernetUDP Udp;                                // Создаем UDP
const unsigned long seventyYears = 2208988800UL;// Время Unix началось 1 января 1970 года. В секундах это 2208988800

unsigned long timeWhenCheckNTP ;                // Время, когда пора проверить NTP сервер.
// unsigned long timeWhenGotNTP;
String timeNowIs = "";                          // Здесь храним запись текущего времени;

uint8_t attemptCounter = 0;                     // Считаем попытки достучаться до вервера;
bool isNeedToReboot = false;                    // Надо ли перегружать роутер?
// Объявляем функции:
unsigned long sendNTPpacket(IPAddress& address);    // Функция отправки запроса NTP
void fUDPReadAndGotTime(void);                  // Функция разбора ответа NTP


void setup()
{
    pinMode(pinRelay, OUTPUT);
    digitalWrite(pinRelay, LOW);
    Serial.begin(9600);
    //while (!Serial) {; }
    Ethernet.begin(mac);
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());


/*    while (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0) {                                      // start Ethernet and UDP
        Serial.println("Failed to configure Ethernet using DHCP");
        delay(1000);
    }*/
    Udp.begin(localPort);
    delay(5000);

    for(int i = 1;i<10;i++){
    sendNTPpacket(timeServer);
    delay(2000);
    if (Udp.parsePacket()) {
    fUDPReadAndGotTime();
    break;
    }
    }
    
    timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
}

void loop() {

/***************************** Проверяем NTP, три сервера **************************/
    if (millis()> timeWhenCheckNTP) {
        Serial.println("Test servers" );
        int goodflag=0;
        //Пройдем 10 раз 1 сервер
        for(int i = 1;i<10;i++){
        sendNTPpacket(timeServer);                          // Отправляем запрос
        delay (2000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;
            goodflag++;
            // Обнуляем счетчик перезагрузок
           Serial.println("good server1" );    
          break; 
        }
        delay(5000);
        }
        
        //Проверяем, сработал 1 сервер
        if(goodflag==0){
          
             //Пройдем 10 раз 2 сервер
        for(int i = 1;i<10;i++){
        sendNTPpacket(timeServer02);                          // Отправляем запрос
        delay (2000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;
            goodflag++;
            // Обнуляем счетчик перезагрузок
           Serial.println("good server3" );    
          break; 
        }
        delay(5000);
        }      
        }
     
             //Проверяем, сработал 2 сервер
   
       if(goodflag==0){
          
             //Пройдем 10 раз 2 сервер
        for(int i = 1;i<10;i++){
        sendNTPpacket(timeServer03);                          // Отправляем запрос
        delay (2000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;
            goodflag++;
            // Обнуляем счетчик перезагрузок
           Serial.println("good server3" );    
          break; 
        }
        delay(5000);
        }      
        }
        
        //Все молчат
               if(goodflag==0){
                 
                  // Если ни один из серверов не ответил
                    isNeedToReboot = true;                  // Установка флага перезагрузки
                    attemptCounter +=1;                     // Увеличение счетчика перезагрузок
                    Serial.println("not good server" );
               }

        
/***************************** Определяем время следующей перезагрузки **************************/
        if (attemptCounter == 0) {                          // Если все хорошо то следующая проверка через 10 минутЖ;
            timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
        }
        if (attemptCounter == 1) {                          // Если перегрузились - проверяем через пять минут
            timeWhenCheckNTP = millis() + timeIntervalIfFirstAttemptFall;
        }
        if (attemptCounter > 1) {                           // Если перегрузка не помогла - перегружаемся каждый час
            timeWhenCheckNTP = millis() + timeIntervalIfSecondAttemptFall;
        }

/******************************* Перегружаем, если надо ****************************************/
        if(attemptCounter < 50) {                           // Перегружаемся не более двух суток
            if (isNeedToReboot) {                           // Если флаг перезагрузки установлен
                isNeedToReboot = false;                     // Сбрасываем его
                Serial.println("Relay!! Relay!! Relay!!");  // Оповещаем в сериал-порт
                digitalWrite(pinRelay, HIGH);               // Включаем реле
                delay(30000);                               // Ждем 30 секунд
                digitalWrite(pinRelay, LOW);                // Отключаем реле
            }
        }
    }
}

/********************************** Отправка пактета на сервер NTP ***************************/
unsigned long sendNTPpacket(IPAddress& address) {
    memset(packetBuffer, 0, NTP_PACKET_SIZE);                               // set all bytes in the buffer to 0
                                                                            // 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
    Udp.write(packetBuffer,NTP_PACKET_SIZE);
    Udp.endPacket();
}
/******************************** Анализ пактета от NTP **************************************/
void fUDPReadAndGotTime(void) {
    Udp.read(packetBuffer,NTP_PACKET_SIZE);                             // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);  //the timestamp starts at byte 40 of the received packet and is four bytes,
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);   // or two words, long. First, esxtract the two words:
    unsigned long secsSince1900 = highWord << 16 | lowWord;             // combine the four bytes (two words) into a long integer
    Serial.print("Seconds since Jan 1 1900 = " );                       // this is NTP time (seconds since Jan 1 1900)
    Serial.println(secsSince1900);
    Serial.print("Unix time = ");                                       // now convert NTP time into everyday time:
    unsigned long epoch = secsSince1900 - seventyYears + (timeZone*3600); // subtract seventy years + Time Zone correction:
    Serial.println(epoch);                                              // print Unix time:
    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)
        timeNowIs = (String) ((epoch  % 86400L) / 3600);
    Serial.print(':');
        timeNowIs += ":";
    if ( ((epoch % 3600) / 60) < 10 ) {                                 // In the first 10 minutes of each hour, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.print((epoch  % 3600) / 60);                                 // print the minute (3600 equals secs per minute)
        timeNowIs += (String) ((epoch  % 3600) / 60);
    Serial.print(':');
        timeNowIs += ":";
    if ( (epoch % 60) < 10 ) {                                          // In the first 10 seconds of each minute, we'll want a leading '0'
        Serial.print('0');
        timeNowIs += "0";
    }
    Serial.println(epoch %60);                                          // print the second
        timeNowIs += (String) (epoch %60);
        Serial.println(timeNowIs);
}

 

Результат роботы

 

server is at 192.168.5.47
Seconds since Jan 1 1900 = 3678001616
Unix time = 1469020016
The UTC time is 13:06:56
13:06:56
Test servers
Seconds since Jan 1 1900 = 3678001618
Unix time = 1469020018
The UTC time is 13:06:58
13:06:58
good server1
Test servers
Seconds since Jan 1 1900 = 3678001680
Unix time = 1469020080
The UTC time is 13:08:00
13:08:00
good server1
Test servers
Seconds since Jan 1 1900 = 3678001742
Unix time = 1469020142
The UTC time is 13:09:02
13:09:02
good server1
Test servers
Seconds since Jan 1 1900 = 3678001804
Unix time = 1469020204
The UTC time is 13:10:04
13:10:04
good server1
Test servers
Seconds since Jan 1 1900 = 3678001811
Unix time = 1469020211
The UTC time is 13:10:11
13:10:11
good server1
Test servers
Seconds since Jan 1 1900 = 3678001887
Unix time = 1469020287
The UTC time is 13:11:27
13:11:27
good server1
Test servers
Seconds since Jan 1 1900 = 3678002018
Unix time = 1469020418
The UTC time is 13:13:38
13:13:38
good server1
Test servers
Seconds since Jan 1 1900 = 3678002032
Unix time = 1469020432
The UTC time is 13:13:52
13:13:52
good server1
Test servers
Seconds since Jan 1 1900 = 3678002046
Unix time = 1469020446
The UTC time is 13:14:06
13:14:06
good server1
Test servers
Seconds since Jan 1 1900 = 3678002053
Unix time = 1469020453
The UTC time is 13:14:13
13:14:13
good server1
Test servers
Seconds since Jan 1 1900 = 3678002254
Unix time = 1469020654
The UTC time is 13:17:34
13:17:34
good server1
Test servers
Seconds since Jan 1 1900 = 3678002316
Unix time = 1469020716
The UTC time is 13:18:36
13:18:36
good server1
Test servers
Seconds since Jan 1 1900 = 3678002392
Unix time = 1469020792
The UTC time is 13:19:52
13:19:52
good server1
Test servers
Seconds since Jan 1 1900 = 3678002399
Unix time = 1469020799
The UTC time is 13:19:59
13:19:59
good server1
Test servers
Seconds since Jan 1 1900 = 3678002427
Unix time = 1469020827
The UTC time is 13:20:27
13:20:27
good server1
Test servers
Seconds since Jan 1 1900 = 3678002551
Unix time = 1469020951
The UTC time is 13:22:31
13:22:31
good server1
Test servers
Seconds since Jan 1 1900 = 3678002558
Unix time = 1469020958
The UTC time is 13:22:38
13:22:38
good server1
Test servers
Seconds since Jan 1 1900 = 3678002579
Unix time = 1469020979
The UTC time is 13:22:59
13:22:59
good server1
Test servers
Seconds since Jan 1 1900 = 3678003043
Unix time = 1469021443
The UTC time is 13:30:43
13:30:43
good server3
 
Вытягуем шнур из WAN порта в роутере
 
Test servers
not good server
Relay!! Relay!! Relay!!
Test servers
 
Втавляем шнур в WAN порт в роутере
 
Seconds since Jan 1 1900 = 3678003536
Unix time = 1469021936
The UTC time is 13:38:56
13:38:56
good server3
Test servers
Seconds since Jan 1 1900 = 3678003543
Unix time = 1469021943
The UTC time is 13:39:03
13:39:03
good server1
Test servers
Seconds since Jan 1 1900 = 3678003780
Unix time = 1469022180
The UTC time is 13:43:00
13:43:00
good server3
 
 
Как-то так... задержки можно и по меньше, ну это уже тестировать нужно. 
geniusltd
Offline
Зарегистрирован: 30.06.2016

ООО шикарно по логу уже вижу что работает :))) Спасибо Виталий))) 

Завтра погоняю ...

geniusltd
Offline
Зарегистрирован: 30.06.2016

а у меня что то этот код не пашет :((( раз праверил потом всё релей релей (((

server is at 192.168.1.97
Seconds since Jan 1 1900 = 3678084891
Unix time = 1469103291
The UTC time is 12:14:51
12:14:51
Test servers
Seconds since Jan 1 1900 = 3678084893
Unix time = 1469103293
The UTC time is 12:14:53
12:14:53
good server1
Test servers
not good server
Relay!! Relay!! Relay!!
Test servers
not good server
Relay!! Relay!! Relay!!
 
vitalikost
Offline
Зарегистрирован: 28.11.2014

хм. странно, зараз еще протестирую. А вы загрузите код из 23 поста  http://arduino.ru/forum/proekty/perezagruzka-routera-pri-zavisanii-unoecn28j60rele#comment-207642  

Интересно посмотреть на статистику

geniusltd
Offline
Зарегистрирован: 30.06.2016

нет грузил последний из 27го поста

из 23-го также себя ведёт кстати, 1 раз находит, дальше релюху клацает 

geniusltd
Offline
Зарегистрирован: 30.06.2016

Виталий а Вы отдельно езернет модуль запитали, или от ардуино ?

vitalikost
Offline
Зарегистрирован: 28.11.2014

Все, вместе, уже больше часа работет...

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Немного модернизировал код:



void loop() {

/***************************** Проверяем NTP, три сервера **************************/
    if (millis()> timeWhenCheckNTP) {
        Serial.println("Test servers" );
        int goodflag=0;
        //Пройдем 10 раз 1 сервер
        for(int i = 1;i<10;i++){
        sendNTPpacket(timeServer);                          // Отправляем запрос
        delay (1000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;
            goodflag++;
            // Обнуляем счетчик перезагрузок
           Serial.print("good server1" );  
           Serial.print(" #-");
           Serial.println(i);  
          break; 
        }
        delay(1000);
        }
        
        //Проверяем, сработал 1 сервер
        if(goodflag==0){
          
             //Пройдем 10 раз 2 сервер
        for(int i = 1;i<10;i++){
        sendNTPpacket(timeServer02);                          // Отправляем запрос
        delay (1000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;
            goodflag++;
            // Обнуляем счетчик перезагрузок
           Serial.print("good server2" );  
           Serial.print(" #-");
           Serial.println(i);  
          break; 
        }
        delay(1000);
        }      
        }
     
             //Проверяем, сработал 2 сервер
   
       if(goodflag==0){
          
             //Пройдем 10 раз 2 сервер
        for(int i = 1;i<10;i++){
        sendNTPpacket(timeServer03);                          // Отправляем запрос
        delay (1000);
        if (Udp.parsePacket()) {                            // Если есть ответ
            fUDPReadAndGotTime();                           // Читаем время
            attemptCounter = 0;
            goodflag++;
            // Обнуляем счетчик перезагрузок
           Serial.print("good server3" );   
           Serial.print(" #-");
           Serial.println(i);
          break; 
        }
        delay(1000);
        }      
        }
        
        //Все молчат
               if(goodflag==0){
                 
                  // Если ни один из серверов не ответил
                    isNeedToReboot = true;                  // Установка флага перезагрузки
                    attemptCounter +=1;                     // Увеличение счетчика перезагрузок
                    Serial.println("not good server" );
               }

        
/***************************** Определяем время следующей перезагрузки **************************/
        if (attemptCounter == 0) {                          // Если все хорошо то следующая проверка через 10 минутЖ;
            timeWhenCheckNTP = millis() + timeIntervalToNextAttempt;
        }
        if (attemptCounter == 1) {                          // Если перегрузились - проверяем через пять минут
            timeWhenCheckNTP = millis() + timeIntervalIfFirstAttemptFall;
        }
        if (attemptCounter > 1) {                           // Если перегрузка не помогла - перегружаемся каждый час
            timeWhenCheckNTP = millis() + timeIntervalIfSecondAttemptFall;
        }

/******************************* Перегружаем, если надо ****************************************/
        if(attemptCounter < 50) {                           // Перегружаемся не более двух суток
            if (isNeedToReboot) {                           // Если флаг перезагрузки установлен
                isNeedToReboot = false;                     // Сбрасываем его
                Serial.println("Relay!! Relay!! Relay!!");  // Оповещаем в сериал-порт
                digitalWrite(pinRelay, HIGH);               // Включаем реле
                delay(30000);                               // Ждем 30 секунд
                digitalWrite(pinRelay, LOW);                // Отключаем реле
            }
        }
    }
}

остальное все тоже. 

работает стабильно.

Test servers
Seconds since Jan 1 1900 = 3678091600
Unix time = 1469110000
The UTC time is 14:06:40
14:06:40
good server1 #-1
Test servers
Seconds since Jan 1 1900 = 3678091604
Unix time = 1469110004
The UTC time is 14:06:44
14:06:44
good server1 #-1
Test servers
Seconds since Jan 1 1900 = 3678091606
Unix time = 1469110006
The UTC time is 14:06:46
14:06:46
good server1 #-1
Test servers
Seconds since Jan 1 1900 = 3678091667
Unix time = 1469110067
The UTC time is 14:07:47
14:07:47
good server1 #-1
 
geniusltd
Offline
Зарегистрирован: 30.06.2016

Запитал от юсб, включаю монитор слышу что сразу реле клацнуло постояло 1.5 минуты опять релей релей клац клац ещё 1.5 клац клац

Думаю а ну дай запитаю от БП не подключая юсб, 9в 1а, думаю в полне подойдёт, включаю светодиоды загорелись, реле не клацнуло значит вообще аруино не завелась, в чём может быть  проблема?

vitalikost
Offline
Зарегистрирован: 28.11.2014

на роутере постотреть, іp ардуина получает?. У немя все от юсб от ноутубка, работает без сбоев. 

только что проверил, ЮСБ + БП-12 в. Все работает

vitalikost
Offline
Зарегистрирован: 28.11.2014

Кстати как затитан модуль 5в или 3,3?

у ментя вот такой:

http://ru.aliexpress.com/store/product/ENC28J60-LAN-Ethernet-Network-Mod...

Запитан +5в.

geniusltd
Offline
Зарегистрирован: 30.06.2016

у меня вот такой запитан на 3,3в от ардуино, что впихнуть ему 5 не сгорит ?

http://ru.aliexpress.com/item/ENC28J60-LAN-Ethernet-Network-Board-Module-for-arduino-25MHZ-Crystal-AVR-51-LPC-STM32-3-3V/32615635511.html?spm=2114.13010608.0.57.8X4M6w

ведёт себя одинаково только от юсб, или юсб+бп, без юсб не могу понять почему но вообще не работает релюха при старте не клацает

да на роутере адрес получает, тот же что и в мониторе отображаеться значит всё ок.

сейчас подам ему 5в вместо 3.3 думаю не должён сгореть)

 

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

5 не желательно, нучше купить копеечный ams1117 3,3. Сам модуль прожарлив. Или что-то такого

http://ru.aliexpress.com/item/MB102-Breadboard-Power-Supply-Module-3-3V-...

geniusltd
Offline
Зарегистрирован: 30.06.2016

ага не заметил разницы у вас уже стоит амс на модуле по этому на него можно подавать 5 в, да на мой нельзя было дым пошёл :(

и походу уно потянул, сама уно работает, но от бп уже не запускается ....

geniusltd
Offline
Зарегистрирован: 30.06.2016

значит по идее скетч работает, если у вас запустился значит и у меня должен заработать, Большое спасибо за помощь.

закажу такой же модуль как у вас чтоб не питать его отдельно и проверю. 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Лучше купите на W5100, он постабильней будет:

http://ru.aliexpress.com/store/product/Free-Shipping-1pcs-UNO-Shield-Eth...

Если смущают габариты, то можно такой:

http://ru.aliexpress.com/store/product/Free-shipping-1PCS-LOT-TOP-Mini-W...

 

majahed
Offline
Зарегистрирован: 10.01.2019

А можно этот код переделать, что бы он пинговал не NTP серверы, а например, обычный компьютер в локальной сети?

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Он не пингует, а делает NTP-запрос.