Pages: [1]   Go Down
Author Topic: Ntp-Server - Problem  (Read 610 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Sr. Member
****
Karma: 2
Posts: 285
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo alle zusammen,
ich habe da mal wieder ein Problem. Und zwar würde ich gerne die Uhrzeit und das Datum aus dem Internet aktualisieren. Dazu verbindet sich das Arduino mit einem Ntp-Server.
Das erste Mal, wenn der Arduino die Zeit aus dem Internet "besorgt", funktioniert auch alles einwandfrei. Aber dann beim zweiten mal bleibt der irgendwo hängen und kommt nicht weiter. Und da finde ich den Fehler einfach nicht, liegt wahrscheinlich daran, dass ich mir den Sketch hauptsächlich aus dem Internet zusammen gesucht habe -_- 
Ja ich weiß, man lernt dabei viel mehr wenn man das selber versucht, aber das funktioniert bei mir noch nicht so ganz gut. Müsste mich dann da Monatelang wahrscheinlich einlesen/arbeiten, bis ich da irgendetwas verstehe, wobei am Ende auch nichts gutes bei rauskommt. Und dazu habe ich leider zur Zeit nicht so die Geduld.

Hoffe irgendjemand kann den Fehler aufdecken ! Oder sollte ich besser eine andere Vorgehensweise verwenden ?!

Hier der Sketch:
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>

byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0D, 0x44, 0x70 };
byte ip[] = {
  192, 168, 2, 111 };

IPAddress timeServer(130,149,17,21);
const long timeZoneOffset = +3600L;
unsigned int ntpSyncTime = 15;
unsigned int localPort = 8888;
const int NTP_PACKET_SIZE= 48;
byte packetBuffer[NTP_PACKET_SIZE];
EthernetUDP Udp;
unsigned long ntpLastUpdate = 0;
time_t prevDisplay = 0;

int getTimeAndDate() {
  int flag=0;
  Udp.begin(localPort);
  sendNTPpacket(timeServer);
  delay(1000);
  if (Udp.parsePacket()){
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
    unsigned long highWord, lowWord, epoch;
    highWord = word(packetBuffer[40], packetBuffer[41]);
    lowWord = word(packetBuffer[42], packetBuffer[43]); 
    epoch = highWord << 16 | lowWord;
    epoch = epoch - 2208988800 + timeZoneOffset;
    flag=1;
    setTime(epoch);
    ntpLastUpdate = now();
  }
  return flag;
}

unsigned long sendNTPpacket(IPAddress& address)
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;
  packetBuffer[1] = 0;
  packetBuffer[2] = 6;
  packetBuffer[3] = 0xEC;
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;                 
  Udp.beginPacket(address, 123);
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}

void printDigits(int digits){
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void clockDisplay(){
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void timeserver()
{

  int i = 0;
  int DHCP = 0;
  DHCP = Ethernet.begin(mac);
  while( DHCP == 0 && i < 30){
    delay(1000);
    DHCP = Ethernet.begin(mac);
    i++;
  }
  if(!DHCP){
    Serial.println("DHCP FAILED");
    for(;;); //Infinite loop because DHCP Failed
  }
  Serial.println("DHCP Success");

  //Try to get the date and time
  int trys=0;
  while(!getTimeAndDate() && trys<10) {
    trys++;
  }

  if(now()-ntpLastUpdate > ntpSyncTime) {
    int trys=0;
    while(!getTimeAndDate() && trys<10){
      trys++;
    }
    if(trys<10){
      Serial.println("ntp server update success");
    }
    else{
      Serial.println("ntp server update failed");
    }
  } 
  clockDisplay();

}

void setup()
{
  Serial.begin(9600);
}

void loop()
{
   timeserver(); 
   delay(10000); //nicht die beste Variante, aber in dem Fall auch egal.
}

Grüße
Lorenz
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du hast das Initialisieren der Ethernet-Hardware (DHCP = Ethernet.begin(mac)) in der Funktion "timeserver()". Dort ist das aber unangebracht, da es bei jedem Aufruf der Funktion ausgeführt wird. Dein Ardino will also alle 10 Sekunden eine neue IP.

Code:
  int i = 0;
  int DHCP = 0;
  DHCP = Ethernet.begin(mac);
  while( DHCP == 0 && i < 30){
    delay(1000);
    DHCP = Ethernet.begin(mac);
    i++;
  }

Falls das nicht klappt, greift vermutlich der folgende Code:
Code:
  if(!DHCP){
    Serial.println("DHCP FAILED");
    for(;;); //Infinite loop because DHCP Failed
  }
Und der Ardino geht in eine Endlosschleife.

Verlager den Code mal ins setup(), dort gehört er nämlich hin. Eine IP-Adresse holst Du Dir einmal am Anfang und dann behält der Arduino die auch, egal wie oft er NTP-Anfragen macht.
Logged

Germany
Offline Offline
Sr. Member
****
Karma: 2
Posts: 285
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie einfach es doch ist, wenn man den Fehler weiß  smiley-mr-green
Super, vielen Dank !
Funktioniert jetzt alles einwandfrei.

Ich habe das deswegen in eine Funktion geschrieben, weil ich diesen Sketch noch in einen adneren mit einfüge wollte.
Dort müsste ich dann zwei Verbindungen gleichzeitig aufrecht erhalten. Einmal die Verbindung zu dem NTP-Server und zu TouchOSC (iOS app). Ich habe das einfach mal gerade zusammengefügt und es funktioniert sogar. Hätte ich gar nicht gedacht.
Aber ich denke mal, dass das nicht der beste Weg ist, dass so zu betreiben ! Oder irre ich mich da ?

Hier der zusammengebastelte Sketch:
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <Z_OSC.h>
#include <EthernetUdp.h>
#include <Time.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x44, 0x70 };
byte ip[] = { 192, 168, 2, 111 }; // Arduino
int  serverPort  = 8000;
byte gateway[] = { 192, 168, 2, 1 };    // Router
byte subnet[] = { 255, 255, 255, 0 };    // Subnet

/*byte destIp[] = { 192, 168, 2, 100 }; //Lokale Ip vom ipod touch
int destPort = 9000; //Eingangsport ipod touch*/
uint16_t i;
float floatValue;
Z_OSCServer server;
Z_OSCMessage *rcvMes;
/*Z_OSCClient client; //Client um Text an Label zu senden TouchOSC*/

IPAddress timeServer(130,149,17,21);
const long timeZoneOffset = +3600L;
unsigned int ntpSyncTime = 15;
unsigned int localPort = 8888;
const int NTP_PACKET_SIZE= 48;
byte packetBuffer[NTP_PACKET_SIZE];
EthernetUDP Udp;
unsigned long ntpLastUpdate = 0;
time_t prevDisplay = 0;

int getTimeAndDate() {
  int flag=0;
  Udp.begin(localPort);
  sendNTPpacket(timeServer);
  delay(1000);
  if (Udp.parsePacket()){
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
    unsigned long highWord, lowWord, epoch;
    highWord = word(packetBuffer[40], packetBuffer[41]);
    lowWord = word(packetBuffer[42], packetBuffer[43]); 
    epoch = highWord << 16 | lowWord;
    epoch = epoch - 2208988800 + timeZoneOffset;
    flag=1;
    setTime(epoch);
    ntpLastUpdate = now();
  }
  return flag;
}

unsigned long sendNTPpacket(IPAddress& address)
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;
  packetBuffer[1] = 0;
  packetBuffer[2] = 6;
  packetBuffer[3] = 0xEC;
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;                 
  Udp.beginPacket(address, 123);
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}

void printDigits(int digits){
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void clockDisplay(){
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void timeserver()
{

 

  //Try to get the date and time
  int trys=0;
  while(!getTimeAndDate() && trys<10) {
    trys++;
  }

  if(now()-ntpLastUpdate > ntpSyncTime) {
    int trys=0;
    while(!getTimeAndDate() && trys<10){
      trys++;
    }
    if(trys<10){
      Serial.println("ntp server update success");
    }
    else{
      Serial.println("ntp server update failed");
    }
  } 
  clockDisplay();

}

void setup()
{
 Serial.begin(9600);
 
  int i = 0;
  int DHCP = 0;
  DHCP = Ethernet.begin(mac);
  while( DHCP == 0 && i < 30){
    delay(1000);
    DHCP = Ethernet.begin(mac);
    i++;
  }
  if(!DHCP){
    Serial.println("DHCP FAILED");
    for(;;); //Infinite loop because DHCP Failed
  }
  Serial.println("DHCP Success");
   Ethernet.begin(mac, ip);
  server.sockOpen(serverPort); //TouchOSC Port öffnen
 
}

void loop()
{
 if(server.available()){
   
    rcvMes=server.getMessage();

    for(i=0 ; i<rcvMes->getArgsNum(); i++){
      switch( rcvMes->getTypeTag(i) ){
       
      case 'f':     
        Z_OSCMessage Message;

       
        floatValue = rcvMes->getFloat(i);       
       
        if(strcmp("/1/1", rcvMes->getZ_OSCAddress()) == 0){ timeserver(); }         

        break;
      }
    }

  }
}

Grüße Lorenz
Logged

Pages: [1]   Go Up
Jump to: