Arduino hängt bei ntpsync / NTP & SD Karte

Hallo,

ich habe mir das Beispielprogramm für den Zeit-Sync gesucht: Beispiel NTP und DHCP

Habe das mit dem DHCP rausgenommen und eine feste IP vergeben.

Jetzt möchte ich Temperaturen erfassen und auf eine SD-Karte schreiben. Mittels DS18B20 Sensoren.

Das funktioniert soweit auch alles.
Nur, wenn er den NTPsync machen will (wo ich die Variable festgelegt habe: const int ntpsync = 60; // *** NTP Sync alle 2 Stunden) hängt er sich auf.
also, wenn ich 60 eingestellt habe, hängt er sich nach einer Minute auf, wenn ich 2 h eingestellt habe nach 2 h.

  • Das ganze wenn die SD-Karte gesteckt ist.

Das seltsame ist nun, das er sich nicht aufhängt, wenn die SD-Karte nicht drinnen ist.

Ich hab keine Ahnung wo dran das liegt. Wäre schön , wenn Ihr da eine Idee zu habt. Code ist im Anhang

/* DS18B20 Sensor an Arduino Uno */
#include <OneWire.h>
#include <DallasTemperature.h>

// Datenleitung an Pin10
#define ONE_WIRE_BUS 9

// oneWire Instanz erzeugen
OneWire oneWire(ONE_WIRE_BUS);

// Referenz zu DallasTemperature
DallasTemperature sensors(&oneWire);

//Adresse desn Sensors
DeviceAddress insideThermometer = { 0x28, 0xFF, 0x55, 0xED, 0x61, 0x16, 0x04, 0xF2 };
DeviceAddress outsideThermometer = { 0x28, 0xFF, 0x2B, 0xCC, 0x61, 0x16, 0x04, 0xC2 };










// Includes
#include <TimeLib.h> // Zeitfunktionen
#include <Ethernet.h> // Ethernetfunktionen
#include <EthernetUdp.h> // UDP Funktionen auf Ethernet
#include <SPI.h> // SPI für Ethernetboard
// Variablen
// *** Ethernet MAC Adresse steht auf Ethernetshield oder manuell setzen
static byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x00, 0x9B, 0xC1 }; 
  IPAddress ip(192, 168, 2, 11);
// *** NTP Server anpassen - sollte eine Adresse aus de.ntp.pool.org sein
static IPAddress timeServer(132, 163, 4, 101);
const int NTP_PACKET_SIZE = 48; // NTP Paketgroeße
byte packetBuffer[NTP_PACKET_SIZE]; // NTP Datnpuffer
time_t prevDisplay = 0; // NTP Klasse - Zeit wurde noch nicht geändert
const int ntpsync = 60; // *** NTP Sync alle 2 Stunden


EthernetClient client; // EthernetClient - Instanz erstellen
EthernetUDP Udp; // UDP - Instanz erstellen



#include "SD.h"
const int CSpin = 53;
unsigned long millisb;





float tempin = 0;
float tempout = 0;



// einmalig 
void setup() 
{

 Serial.begin(9600); 


 // Bibliothek starten
 sensors.begin();
 // Resolution auf 10 bit setzen
  sensors.setResolution(insideThermometer, 100);
  sensors.setResolution(outsideThermometer, 100);




  Ethernet.begin(mac, ip); // EthernetClient starten, 1 Sekunde warten
  delay(1000);
  Udp.begin(8888);   // UDP starten Port 8888
  setSyncProvider(getNtpTime); // NTP Provider starten / erstmalig abfragen
  setSyncInterval(ntpsync); // NTP Sync alle 2 Stunden
  setTime(hour(),minute(),second(),day(),month(),year()); // Zeit auf Arduino setzen


  SD.begin(CSpin);
  


  
}









// Dauerschleife
void loop() 
{

  
 sensors.requestTemperatures();
 Serial.print("Insideerature is: ");
 tempin = sensors.getTempC(insideThermometer);
 Serial.print(tempin);
 Serial.println();
 Serial.print("Insidedgvfsadffgfdserature is: ");
 tempout = sensors.getTempC(outsideThermometer);
 Serial.print(tempout);
 Serial.println();



  ClockDisplay();




  if(millisb+1000 <= millis())
  {
    File dataFile = SD.open("TEMP.txt", FILE_WRITE);
    Serial.println("File open");
    if (dataFile) {
      dataFile.print(day());
      dataFile.print(".");
      dataFile.print(month());
      dataFile.print(".");
      dataFile.print(year());
      dataFile.print(",");
      dataFile.print(hour());
      dataFile.print(":");
      dataFile.print(minute());
      dataFile.print(":");
      dataFile.print(second());
      dataFile.print(",");
      dataFile.print(tempin);
      dataFile.print(",");
      dataFile.println(tempout);
      dataFile.close();
      Serial.println("File close");
    }
   else {
    Serial.println("error opening TEMP.txt");
    }
    millisb = millis();


 Serial.println();
 Serial.println();  
  }
}




// Anzeige Zeit/Datum und IP-Adresse auf Serial
void ClockDisplay(){
  Serial.print("Zeit / Datum: ");
  printDigits(hour());
  Serial.print(":");
  printDigits(minute());
  Serial.print(":");
  printDigits(second());
  Serial.print("  ");
  printDigits(day());
  Serial.print(".");
  printDigits(month());
  Serial.print(".");
  Serial.println(year());
  //Serial.println(Ethernet.localIP());
  //Serial.println(ipbuf);
}
// 0 vorsetzen wenn übergebener Wert < 10
void printDigits(int digits)
{
  if(digits < 10) Serial.print('0'); // vorher 0 wenn einstellig
  Serial.print(digits);
}







// NTP Provider - prüft ob NTP läuft und holt die Daten
time_t getNtpTime()
{
  while (Udp.parsePacket() > 0) ; // vorhergehende Pakete verwerfen
  sendNTPpacket(timeServer);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) // 1500 Millisekunden Wartezeit für NTP Antwort
  {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE)
    {
      Udp.read(packetBuffer, NTP_PACKET_SIZE); // Paket in Puffer einlesen
      unsigned long secsSince1900;
      // Byte 40,41,42,43 zusammen in long umwandeln
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + 2 * SECS_PER_HOUR;
    }
  }
  return 0; 
}

// NTP Request senden
void sendNTPpacket(IPAddress &address)
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE); // Puffer auf 0 setzen
  // notwendige Werte für NTP-Request
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum oder Uhrentyp
  packetBuffer[2] = 6;     // Pollingintervall
  packetBuffer[3] = 0xEC;  // Peer Clock Präzision
  /* 8 bytes 0 für Root Delay & Root Dispersion
   Es wird also immer eine Antwort entgegengenommen,
   egal welche Abweichung der Server vom Root hat */
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  // Werte für Request gesetzt, Request senden auf Port 123
  Udp.beginPacket(address, 123);
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

Mit freundlichen Grüßen

Code_WP.txt (5.53 KB)

Bite schreibe Deinen Code direkt ins Forum. Nutze dazu Codetags (</> oben links im Editor). Anhänge werden selten gelesen.

Funktioniert das NTP-Sync allein - ohne SD und DS18B20?

Funktioniert das Schreiben auf die SD allein?

Wenn nicht, das probieren. Wenn ja, vermute ich einen Konflikt zwischen Ethernet und SD.
Welche Komponenten sind verbaut? (Bitte Link dazu).

Gruß Tommy

Verbaut sind die DS18B20 Sensoren von eBay.

Und ein Ethernet Shield mit dem W5100

Ohne SD Karte hängt er sich nicht auf, ob der Sync direkt funktioniert weiß ich nicht genau, gibts da ne Möglichkeit das einfach rauszubekommen?

Das schreiben auf die SD funktioniert auch allein.

Gerade beim testen festgestellt: Wenn ich die SD Karte rausnehme, nachdem er sich aufgehängt hat, läuft er weiter, aber auch nicht richtig wie er soll. (Er öffnet das File, wartet und dann schließt er es wieder & macht weiter). Stecke ich die Karte dann wieder rein ändert sich nichts weiter.
Also erkennt er nicht das die SD-Karte weg ist, was er eigentlich machen müsste, oder?

Ich hoffe das das weiter hilft.

So, habe ChipSelect (CSpin) jetzt wieder auf 4 gelegt. Jetzt scheint es zu funktionieren.
Warum klappt es nicht mit 53, habe gelesen das ich den, wenn ich den Mega verwende auf 53 legen soll?

Wie soll Dein Ethernetshield an deinen CS-Pin (bei Dir 53) für die SD-Karte kommen? Da steckt das Shield nicht drauf. Ich verwende Pin 4.
Welches Shield das ist, ist nicht so genau zu sehen. Probier mal:

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8

Ein Beispiel für eine NTP-Abfrage ist in den Beispielen der IDE enthalten.

Für mehr Übersichtlichkeit solltest Du alle #include oben sammeln und nicht einfach dort lassen, wo sie beim Einfügen gelandet sind.

Gruß Tommy

Tommy56:
Wie soll Dein Ethernetshield an deinen CS-Pin (bei Dir 53) für die SD-Karte kommen? Da steckt das Shield nicht drauf. Ich verwende Pin 4.

Da hast du natürlich recht. Habs ja auch grad mit 4 probiert und es läuft.

Tommy56:
Für mehr Übersichtlichkeit solltest Du alle #include oben sammeln und nicht einfach dort lassen, wo sie beim Einfügen gelandet sind.

Ja, wollte ich später noch machen, hab das erstmal so, um zu wissen welche Variablen und Librarys zusammengehören.

Vielen Dank dieserseits schonmal.