INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Neopixel Uhr mit Nextion und MQTT
05.08.2019, 12:21 (Dieser Beitrag wurde zuletzt bearbeitet: 05.08.2019 20:18 von MeisterQ.)
Beitrag #1
Neopixel Uhr mit Nextion und MQTT
Moin zusammen,

ich habe seit langem mal wieder ein neues Projekt angefangen, und auch soziemlich abgeschlossen.

Hierbei handelt es sich um eine smarte Uhr, die die Zeit via NTP von meiner Fritzbox bekommt, und diese auf dem Neopixel Ring und einem 2.4" Nextion HMI anzeigt.

Zusätzlich zeigt sie auch den Wochentag und die Innen, sowie Außentemperatur an.

   

Zur Hardware:

- Adafruit Neopixel SK6812RGBW Nature White 1/4 60 Ring
- Nextion HMI 2.4"
- Wemos D1 mini
- TP4056 mit DCDC-Wandler
- 18650 Li-Ion Zelle

   

Zur Software / Ansteuerung

Der ESP ist mit meinem MQTT-Broker verbunden, und bezieht die Temperatur-Daten von meinen ESP32-Platinen mit BME280 die auf Batterie laufen, und überall im und ums Haus verteilt sind.

Die Daten laufen alle in Node-Red auf meinem Raspberry zusammen und werden dort verarbeitet und Visualisiert.

Über Node-Red kann ich die Verknüpfungen, von denen ich Daten auf dem Display sehen will, variabel ziehen.

Der Wemos hat abboniert 2 Topics für die Temperaturen, und 2 Topics für den Anzeigetext davor.

So kann ich über Node-Red einfach die Verknüpfungen ziehen, und die Daten, die ich haben will, anzeigen lassen.

   

Die Helligkeit der Stunde (Blau), der Minute (Grün), der Sekunde (Weiss) und der 12 Stunden (Rot) kann ich über das Dasboard von Node-Red ganz einfach per Schieberegler ändern. Diese Daten bleiben erhalten, und die Uhr stellt sich nach einem Reset wieder auf die Helligkeit ein.

Die Farben der o.g. Daten kann ich ebenfalls (bisher nur als RGBW) ändern. Ebenfalls "remanent".

   


Den Code habe ich weitestgehend selbst geschrieben. Natürlich nutze ich Bibliotheken wie Pubsubclient, Adafruit_Neopixel, NTPClient und so.

Die Uhr besitzt einen Nachtmodus, welcher die LEDs komplett deaktiviert, und das Display auf 1% runter dimmt.

Dieser Modus wird vom Node-Red um 0:00 Uhr aufgerufen und um 8Uhr morgens wieder deaktiviert.

Gegen abend wird ebenfalls von Node-Red die Helligkeit der LEDs gedimmt, damit man nicht so geblendet wird. Morgens bei aktivierung der Uhr wird wieder "Standardhelligkeit" aufgerufen.

Zusätzlich hat die Uhr einen Dauerlicht-Modus, welcher alle 60 LEDs auf maximaler Helligkeit aktiviert. Dieser ist mit meinen selbstegebauten Neopixel Bewegungsmeldern gekoppelt (ESP, PIR, 24er NeoPixel-Ring, MQTT, etc).

Das ganze ist mit OTA flashbar und die 18650er Li-Ionen Zelle dient nur als Puffer wenn ich mal an der Uhr rumbasteln will, damit sie nicht ständig Stromlos ist und weil ich einfach lust darauf hatte.

Auf Akku läuft die Uhr ca. 10 Stunden.

       

Zum Gehäuse:

Das Gehäuse habe ich mir in 3D mit Catia erstellt, habe es mit Slic3r PE gesliced, und auf meinem Hypercube Evolution mit PETG ausgedruckt.

Anschließend habe ich das Gehäuse Geschliffen, Gespachtelt, Grundiert und Lackiert.

Den Spachtel und Grundierungsvorgang habe ich mehrfach wiederholt, und alles mit Schleifpapier von 120 - 2000 Nass und Trocken bearbeitet.

Dafür, dass es meine erste bearbeitung von einem gedruckten Objekt war, bin ich recht zufrieden damit... könnte allerdings besser sein.

       


Der Code ist sehr unübersichtlich und in viele Tabs aufgeteilt... Habe alles mal hier angehängt.

Code:
#define SoftSerial mySerial
#define CO2_TX D1
#define CO2_RX D3

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Adafruit_NeoPixel.h>      // Neopixel Library
#include <PubSubClient.h>           // MQTT Library
#include <ArduinoOTA.h>             // OTA Library
#include <SoftwareSerial.h>

#define DEBUG
SoftwareSerial SoftSerial(CO2_RX, CO2_TX); // RX, TX

/*
********************************************************************************​********************
***************************************** Nextion **************************************************
********************************************************************************​********************
*/

float sliderVal;
float sliderVal2;
byte incomingByte[6];
byte pID;   // PageID
byte cID;   // ComponentID
byte tEv;   // TouchEvent
byte bVal;  // ButtonValue
byte NexT[3] = {255, 255, 255};

// Nextion Defines

// Nextion touch events

#define touchEventRelease 0
#define touchEventPress 1


/*
  ---------------------- WLan Einstellungen ------------------
*/

const char* ssid = "";                    // WLan Name
const char* password = "";            // WLan Passwort

IPAddress ip(192, 168, 2, 140);                   // IP mit der sich der ESP in das Netzwerk verbinden soll
IPAddress gateway(192, 168, 2, 169);                // Gateway des Netzwerks
IPAddress subnet(255, 255, 255, 0);               // Subnetmask
IPAddress dns(192, 168, 2, 169);


/*
  ---------------------- NTP Einstellungen ------------------
*/

const long utcOffsetInSeconds = 7200;

char daysOfTheWeek[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "fritz.box", utcOffsetInSeconds); //pool.ntp.org


/*
  ------------------------ Mosquitto --------------------------
*/

const char* mqtt_server = "192.168.2.173";                        // MQTT Server IP

WiFiClient espClient;                                             // WiFi client
PubSubClient client(espClient);                                   // Client für MQTT

/* topics */
#define HELLIGKEIT_STUNDE     "smarthome/Neopixel/helligkeitStunde"
#define FARBE_STUNDE          "smarthome/Neopixel/farbeStunde"

#define HELLIGKEIT_MINUTE     "smarthome/Neopixel/helligkeitMinute"
#define FARBE_MINUTE          "smarthome/Neopixel/farbeMinute"

#define HELLIGKEIT_SEKUNDE    "smarthome/Neopixel/helligkeitSekunde"
#define FARBE_SEKUNDE         "smarthome/Neopixel/farbeSekunde"

#define HELLIGKEIT_HINTERGRUND    "smarthome/Neopixel/helligkeitHintergrund"
#define FARBE_HINTERGRUND         "smarthome/Neopixel/farbeHintergrund"

#define INITIAL_HINTERGRUND       "smarthome/Neopixel/initial/hintergrund/farbe"
#define INITIAL_STUNDE            "smarthome/Neopixel/initial/stunde/farbe"
#define INITIAL_MINUTE            "smarthome/Neopixel/initial/minute/farbe"
#define INITIAL_SEKUNDE           "smarthome/Neopixel/initial/sekunde/farbe"

#define INITIAL_HINTERGRUND_HELLIGKEIT       "smarthome/Neopixel/initial/hintergrund/helligkeit"
#define INITIAL_STUNDE_HELLIGKEIT           "smarthome/Neopixel/initial/stunde/helligkeit"
#define INITIAL_MINUTE_HELLIGKEIT            "smarthome/Neopixel/initial/minute/helligkeit"
#define INITIAL_SEKUNDE_HELLIGKEIT           "smarthome/Neopixel/initial/sekunde/helligkeit"

#define TEMP1_TOPIC   "smarthome/Uhr/temp1"
#define TEMP2_TOPIC   "smarthome/Uhr/temp2"

#define UHR_TOPIC     "smarthome/Neopixel/clock/ena"

#define DAUER_TOPIC         "smarthome/bewegungsmelder/dauer_an"

#define TEXT_FELD1  "smarthome/Uhr/textfeld1"
#define TEXT_FELD2  "smarthome/Uhr/textfeld2"

#define NEX_DIM  "smarthome/Uhr/dim"
/*
  ------------------------ Neopixel --------------------------
*/

#define PIN D2          // Pin der Neopixels
#define NUMPIXELS 60   // Anzahl der Neopixels  

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);   // Einstellung für Neopixel

bool clockEna = true;
bool dauerLicht = false;
bool dauerLichtIstAn = false;

byte brightnessHour = 30;
byte brightnessMinute = 30;
byte brightnessSecond = 10;
byte brightnessBack = 20;
byte farbe = 1;
byte backColor = 1;
byte hourColor = 3;
byte minuteColor = 2;
byte secondColor = 4;
byte nexDim = 100;

int second;
int minute;
int hour;
int hourNex;
int connects;
int ergebnisSekunde = 0;
int ergebnisMinute = 0;
int ergebnisStunde = 0;
int ergebnisHintergrund = 0;
int ergebnisTempInnen = 0;
int ergebnisTempAussen = 0;
int ergebnisNexDim = 0;


int tempInnen;
int tempAussen;

char farbeHintergrund[1];
char farbeStunde[1];
char farbeMinute[1];
char farbeSekunde[1];

char helligkeitHintergrund[6];
char helligkeitStunde[6];
char helligkeitMinute[6];
char helligkeitSekunde[6];

char hourDigit[3];
char minuteDigit[3];
char secondDigit[3];

unsigned long previousMillis = 0;
const long interval = 1000;
unsigned long previousMillis2 = 0;
const long interval2 = 1000;
unsigned long previousMillis3 = 0;
const long interval3 = 1000;
unsigned long previousMillis4 = 0;
const long interval4 = 1000;
unsigned long previousMillis5 = 0;
const long interval5 = 1000;



void setup()
{
  Serial.begin(115200);
  SoftSerial.begin(9600);
  pixels.begin();                 // Neopixel initialisieren

  wifiSettings();
  mqttSettings();
  OTAsettings();
  mqttconnect();


  timeClient.begin();

  mqttPublish();
}

void loop()
{
  ArduinoOTA.handle();            // OTA Handle
  mqttHandle();                   // Sende Daten an MQTT Server
  getClockTime();
  serialSend();
  if (dauerLicht == false)
  {
    if (clockEna == true)
    {
      clockDraw();
    }
    if (clockEna == false)
    {
      clockOff();
    }
    dauerLichtIstAn = false;
  }
  if ((dauerLicht == true) && (dauerLichtIstAn == false))
  {
    dauerlicht();
    dauerLichtIstAn = true;
  }
//  SoftSerial.print("page page1");
//  SoftSerial.write(0xff);
//  SoftSerial.write(0xff);
//  SoftSerial.write(0xff);
}

void getClockTime()
{
  timeClient.update();
  hour = timeClient.getHours();
  hourNex = timeClient.getHours();
  minute = timeClient.getMinutes();
  second = timeClient.getSeconds();
}

void clockDraw()
{
  if (hour >= 12)
  {
    hour = (hour - 12) * 5;
  }
  else
  {
    hour = hour * 5;
  }
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    /*
        Serial.print(daysOfTheWeek[timeClient.getDay()]);
        Serial.print(", ");
        Serial.print(timeClient.getHours());
        Serial.print(":");
        Serial.print(timeClient.getMinutes());
        Serial.print(":");
        Serial.println(timeClient.getSeconds());

        Serial.println(hour);
    */
    pixels.clear();



    backgroundColors();
    hourColors();
    minuteColors();

    secondColors();


    SoftSerial.print("dim=100");
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);

    pixels.show();
  }

}


void clockOff()
{
  for (int i = 0; i < NUMPIXELS; i++)
  {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0, 0));
    pixels.show();
  }
  unsigned long currentMillis4 = millis();
  if (currentMillis4 - previousMillis4 >= interval4)
  {
    previousMillis4 = currentMillis4;
    SoftSerial.print("dim=1");
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
  }
}

void backgroundColors()
{
  if (backColor == 1) // Rot
  {
    pixels.setPixelColor(0, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(5, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(10, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(15, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(20, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(25, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(30, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(35, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(40, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(45, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(50, pixels.Color(brightnessBack, 0, 0, 0));
    pixels.setPixelColor(55, pixels.Color(brightnessBack, 0, 0, 0));
  }
  if (backColor == 2) // Grün
  {
    pixels.setPixelColor(0, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(5, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(10, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(15, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(20, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(25, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(30, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(35, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(40, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(45, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(50, pixels.Color(0, brightnessBack, 0, 0));
    pixels.setPixelColor(55, pixels.Color(0, brightnessBack, 0, 0));
  }
  if (backColor == 3) // Blau
  {
    pixels.setPixelColor(0, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(5, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(10, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(15, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(20, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(25, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(30, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(35, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(40, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(45, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(50, pixels.Color(0, 0, brightnessBack, 0));
    pixels.setPixelColor(55, pixels.Color(0, 0, brightnessBack, 0));
  }
  if (backColor == 4) // Weiss
  {
    pixels.setPixelColor(0, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(5, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(10, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(15, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(20, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(25, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(30, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(35, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(40, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(45, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(50, pixels.Color(0, 0, 0, brightnessBack));
    pixels.setPixelColor(55, pixels.Color(0, 0, 0, brightnessBack));
  }
}

void hourColors()
{
  if (hourColor == 1) // Rot
  {
    pixels.setPixelColor(hour - 1, pixels.Color(brightnessHour, 0, 0, 0));
    pixels.setPixelColor(hour, pixels.Color(brightnessHour, 0, 0, 0));
    pixels.setPixelColor(hour + 1, pixels.Color(brightnessHour, 0, 0, 0));

    if (hour == 59)
    {
      pixels.setPixelColor(0, pixels.Color(brightnessHour, 0, 0, 0));
    }
    if (hour == 0)
    {
      pixels.setPixelColor(59, pixels.Color(brightnessHour, 0, 0, 0));
    }
  }
  if (hourColor == 2) // Grün
  {
    pixels.setPixelColor(hour - 1, pixels.Color(0, brightnessHour, 0, 0));
    pixels.setPixelColor(hour, pixels.Color(0, brightnessHour, 0, 0));
    pixels.setPixelColor(hour + 1, pixels.Color(0, brightnessHour, 0, 0));

    if (hour == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, brightnessHour, 0, 0));
    }
    if (hour == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, brightnessHour, 0, 0));
    }
  }
  if (hourColor == 3) // Blau
  {
    pixels.setPixelColor(hour - 1, pixels.Color(0, 0, brightnessHour, 0));
    pixels.setPixelColor(hour, pixels.Color(0, 0, brightnessHour, 0));
    pixels.setPixelColor(hour + 1, pixels.Color(0, 0, brightnessHour, 0));

    if (hour == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, 0, brightnessHour, 0));
    }
    if (hour == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, 0, brightnessHour, 0));
    }
  }
  if (hourColor == 4) // Weiss
  {
    pixels.setPixelColor(hour - 1, pixels.Color(0, 0, 0, brightnessHour));
    pixels.setPixelColor(hour, pixels.Color(0, 0, 0, brightnessHour));
    pixels.setPixelColor(hour + 1, pixels.Color(0, 0, 0, brightnessHour));

    if (hour == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, 0, 0, brightnessHour));
    }
    if (hour == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, 0, 0, brightnessHour));
    }
  }
}


void minuteColors()
{
  if (minuteColor == 1) // Rot
  {
    pixels.setPixelColor(minute - 1, pixels.Color(brightnessMinute, 0, 0, 0));
    pixels.setPixelColor(minute, pixels.Color(brightnessMinute, 0, 0, 0));
    pixels.setPixelColor(minute + 1, pixels.Color(brightnessMinute, 0, 0, 0));

    if (minute == 59)
    {
      pixels.setPixelColor(0, pixels.Color(brightnessMinute, 0, 0, 0));
    }
    if (minute == 0)
    {
      pixels.setPixelColor(59, pixels.Color(brightnessMinute, 0, 0, 0));
    }
  }

  if (minuteColor == 2) // Grün
  {
    pixels.setPixelColor(minute - 1, pixels.Color(0, brightnessMinute, 0, 0));
    pixels.setPixelColor(minute, pixels.Color(0, brightnessMinute, 0, 0));
    pixels.setPixelColor(minute + 1, pixels.Color(0, brightnessMinute, 0, 0));

    if (minute == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, brightnessMinute, 0, 0));
    }
    if (minute == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, brightnessMinute, 0, 0));
    }
  }

  if (minuteColor == 3) // Blau
  {
    pixels.setPixelColor(minute - 1, pixels.Color(0, 0, brightnessMinute, 0));
    pixels.setPixelColor(minute, pixels.Color(0, 0, brightnessMinute, 0));
    pixels.setPixelColor(minute + 1, pixels.Color(0, 0, brightnessMinute, 0));

    if (minute == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, 0, brightnessMinute, 0));
    }
    if (minute == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, 0, brightnessMinute, 0));
    }
  }

  if (minuteColor == 4) // Weiss
  {
    pixels.setPixelColor(minute - 1, pixels.Color(0, 0, 0, brightnessMinute));
    pixels.setPixelColor(minute, pixels.Color(0, 0, 0, brightnessMinute));
    pixels.setPixelColor(minute + 1, pixels.Color(0, 0, 0, brightnessMinute));

    if (minute == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, 0, 0, brightnessMinute));
    }
    if (minute == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, 0, 0, brightnessMinute));
    }
  }
}



void secondColors()
{
  if (secondColor == 1) // Rot
  {
    pixels.setPixelColor(second - 1, pixels.Color(brightnessSecond, 0, 0, 0));
    pixels.setPixelColor(second, pixels.Color(brightnessSecond, 0, 0, 0));
    pixels.setPixelColor(second + 1, pixels.Color(brightnessSecond, 0, 0, 0));

    if (second == 59)
    {
      pixels.setPixelColor(0, pixels.Color(brightnessSecond, 0, 0, 0));
    }
    if (second == 0)
    {
      pixels.setPixelColor(59, pixels.Color(brightnessSecond, 0, 0, 0));
    }
  }

  if (secondColor == 2) // Grün
  {
    pixels.setPixelColor(second - 1, pixels.Color(0, brightnessSecond, 0, 0));
    pixels.setPixelColor(second, pixels.Color(0, brightnessSecond, 0, 0));
    pixels.setPixelColor(second + 1, pixels.Color(0, brightnessSecond, 0, 0));

    if (second == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, brightnessSecond, 0, 0));
    }
    if (second == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, brightnessSecond, 0, 0));
    }
  }

  if (secondColor == 3) // Blau
  {
    pixels.setPixelColor(second - 1, pixels.Color(0, 0, brightnessSecond, 0));
    pixels.setPixelColor(second, pixels.Color(0, 0, brightnessSecond, 0));
    pixels.setPixelColor(second + 1, pixels.Color(0, 0, brightnessSecond, 0));

    if (second == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, 0, brightnessSecond, 0));
    }
    if (second == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, 0, brightnessSecond, 0));
    }
  }

  if (secondColor == 4) // Weiss
  {
    pixels.setPixelColor(second - 1, pixels.Color(0, 0, 0, brightnessSecond));
    pixels.setPixelColor(second, pixels.Color(0, 0, 0, brightnessSecond));
    pixels.setPixelColor(second + 1, pixels.Color(0, 0, 0, brightnessSecond));

    if (second == 59)
    {
      pixels.setPixelColor(0, pixels.Color(0, 0, 0, brightnessSecond));
    }
    if (second == 0)
    {
      pixels.setPixelColor(59, pixels.Color(0, 0, 0, brightnessSecond));
    }
  }
}

void dauerlicht()
{
  for (int i = 0; i < NUMPIXELS; i++)
  {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0, 255));
    pixels.show();
  }
}

void mqttconnect()
{
  while (!client.connected())
  {
#ifdef DEBUG
    Serial.print("MQTT connecting ...");
#endif


    String clientId = "ESP8266_Clock";


#ifdef DEBUG
    Serial.println(connects);
#endif


    if (client.connect(clientId.c_str()))
    {

#ifdef DEBUG
      Serial.println("connected");
#endif

      client.subscribe(HELLIGKEIT_STUNDE);
      client.subscribe(HELLIGKEIT_MINUTE);
      client.subscribe(HELLIGKEIT_SEKUNDE);
      client.subscribe(HELLIGKEIT_HINTERGRUND);
      client.subscribe(FARBE_HINTERGRUND);
      client.subscribe(FARBE_STUNDE);
      client.subscribe(FARBE_MINUTE);
      client.subscribe(FARBE_SEKUNDE);
      client.subscribe(UHR_TOPIC);
      client.subscribe(DAUER_TOPIC);
      client.subscribe(TEMP1_TOPIC);
      client.subscribe(TEMP2_TOPIC);
      client.subscribe(TEXT_FELD1);
      client.subscribe(TEXT_FELD2);
      client.subscribe(NEX_DIM);
    }
  }
}

void mqttPublish()
{
  unsigned long currentMillis2 = millis();
  if (currentMillis2 - previousMillis2 >= interval2)
  {
    previousMillis2 = currentMillis2;
/*
    snprintf(farbeHintergrund, 5, "%ld", backColor);
    client.publish(INITIAL_HINTERGRUND, farbeHintergrund);


    snprintf(farbeStunde, 5, "%ld", hourColor);
    client.publish(INITIAL_STUNDE, farbeStunde);


    snprintf(farbeMinute, 5, "%ld", minuteColor);
    client.publish(INITIAL_MINUTE, farbeMinute);

    snprintf(farbeSekunde, 5, "%ld", secondColor);
    client.publish(INITIAL_SEKUNDE, farbeSekunde);




    snprintf(helligkeitHintergrund, 5, "%ld", brightnessBack);
    client.publish(INITIAL_HINTERGRUND_HELLIGKEIT, helligkeitHintergrund);


    snprintf(helligkeitStunde, 5, "%ld", brightnessHour);
    client.publish(INITIAL_STUNDE_HELLIGKEIT, helligkeitStunde);


    snprintf(helligkeitMinute, 5, "%ld", brightnessMinute);
    client.publish(INITIAL_MINUTE_HELLIGKEIT, helligkeitMinute);

    snprintf(helligkeitSekunde, 5, "%ld", brightnessSecond);
    client.publish(INITIAL_SEKUNDE_HELLIGKEIT, helligkeitSekunde);
    */
  }
}

void mqttHandle()
{
  if ((!client.connected()))
  {
    mqttconnect();
  }
  client.loop();




}

void receivedCallback(char* topic, byte * payload, unsigned int length) {
  std::string text((const char*)payload, length);
#ifdef DEBUG
  Serial.print("Message received: ");
  Serial.println(topic);

  Serial.print("payload: ");
#endif
  for (int i = 0; i < length; i++) {
#ifdef DEBUG
    Serial.print((char)payload[i]);
#endif
  }
#ifdef DEBUG
  Serial.println();
#endif

  // Helligkeit Sekunde

  if (strcmp((char*)topic, HELLIGKEIT_SEKUNDE) == 0)
  {
    ergebnisSekunde = 0;
    for (int i = 0; i < length; i++) ergebnisSekunde = (ergebnisSekunde * 10) + (payload[i] - '0');
    brightnessSecond = ergebnisSekunde;

#ifdef DEBUG
    Serial.println(ergebnisSekunde);
    Serial.println();
#endif
  }

  // Helligkeit Minute

  if (strcmp((char*)topic, HELLIGKEIT_MINUTE) == 0)
  {
    ergebnisMinute = 0;
    for (int i = 0; i < length; i++) ergebnisMinute = (ergebnisMinute * 10) + (payload[i] - '0');
    brightnessMinute = ergebnisMinute;

#ifdef DEBUG
    Serial.println(ergebnisMinute);
    Serial.println();
#endif
  }



  // Helligkeit Stunde

  if (strcmp((char*)topic, HELLIGKEIT_STUNDE) == 0)
  {
    ergebnisStunde = 0;
    for (int i = 0; i < length; i++) ergebnisStunde = (ergebnisStunde * 10) + (payload[i] - '0');
    brightnessHour = ergebnisStunde;

#ifdef DEBUG
    Serial.println(ergebnisStunde);
    Serial.println();
#endif
  }


  // Helligkeit Hintergrund

  if (strcmp((char*)topic, HELLIGKEIT_HINTERGRUND) == 0)
  {
    ergebnisHintergrund = 0;
    for (int i = 0; i < length; i++) ergebnisHintergrund = (ergebnisHintergrund * 10) + (payload[i] - '0');
    brightnessBack = ergebnisHintergrund;

#ifdef DEBUG
    Serial.println(ergebnisHintergrund);
    Serial.println();
#endif
  }


  // Farbe Hintergrund

  if (strcmp((char*)topic, FARBE_HINTERGRUND) == 0)
  {
    if (strncmp((char*)payload, "1", length) == 0)
    {
      backColor = 1;
#ifdef DEBUG
      Serial.println("Rot");
#endif
    }
    if (strncmp((char*)payload, "2", length) == 0)
    {
      backColor = 2;
#ifdef DEBUG
      Serial.println("Grün");
#endif
    }
    if (strncmp((char*)payload, "3", length) == 0)
    {
      backColor = 3;
#ifdef DEBUG
      Serial.println("Blau");
#endif
    }
    if (strncmp((char*)payload, "4", length) == 0)
    {
      backColor = 4;
#ifdef DEBUG
      Serial.println("Weiss");
#endif
    }
  }

  // Farbe Stunde

  if (strcmp((char*)topic, FARBE_STUNDE) == 0)
  {
    if (strncmp((char*)payload, "1", length) == 0)
    {
      hourColor = 1;
#ifdef DEBUG
      Serial.println("Rot");
#endif
    }
    if (strncmp((char*)payload, "2", length) == 0)
    {
      hourColor = 2;
#ifdef DEBUG
      Serial.println("Grün");
#endif
    }
    if (strncmp((char*)payload, "3", length) == 0)
    {
      hourColor = 3;
#ifdef DEBUG
      Serial.println("Blau");
#endif
    }
    if (strncmp((char*)payload, "4", length) == 0)
    {
      hourColor = 4;
#ifdef DEBUG
      Serial.println("Weiss");
#endif
    }
  }

  // Farbe Minute

  if (strcmp((char*)topic, FARBE_MINUTE) == 0)
  {
    if (strncmp((char*)payload, "1", length) == 0)
    {
      minuteColor = 1;
#ifdef DEBUG
      Serial.println("Rot");
#endif
    }
    if (strncmp((char*)payload, "2", length) == 0)
    {
      minuteColor = 2;
#ifdef DEBUG
      Serial.println("Grün");
#endif
    }
    if (strncmp((char*)payload, "3", length) == 0)
    {
      minuteColor = 3;
#ifdef DEBUG
      Serial.println("Blau");
#endif
    }
    if (strncmp((char*)payload, "4", length) == 0)
    {
      minuteColor = 4;
#ifdef DEBUG
      Serial.println("Weiss");
#endif
    }
  }


  // Farbe Minute

  if (strcmp((char*)topic, FARBE_SEKUNDE) == 0)
  {
    if (strncmp((char*)payload, "1", length) == 0)
    {
      secondColor = 1;
#ifdef DEBUG
      Serial.println("Rot");
#endif
    }
    if (strncmp((char*)payload, "2", length) == 0)
    {
      secondColor = 2;
#ifdef DEBUG
      Serial.println("Grün");
#endif
    }
    if (strncmp((char*)payload, "3", length) == 0)
    {
      secondColor = 3;
#ifdef DEBUG
      Serial.println("Blau");
#endif
    }
    if (strncmp((char*)payload, "4", length) == 0)
    {
      secondColor = 4;
#ifdef DEBUG
      Serial.println("Weiss");
#endif
    }
  }



  // Licht

  if (strcmp((char*)topic,  UHR_TOPIC) == 0)
  {
    if (strncmp((char*)payload, "true", length) == 0)
    {
      clockEna = true;
    }
    else
    {
      clockEna = false;
    }
  }

  // Dauerlicht

  if (strcmp((char*)topic,  DAUER_TOPIC) == 0)
  {
    if (strncmp((char*)payload, "true", length) == 0)
    {
      dauerLicht = true;
    }
    else
    {
      dauerLicht = false;
    }
  }

  // Temp Innen

  if (strcmp((char*)topic, TEMP2_TOPIC) == 0)
  {
    ergebnisTempInnen = 0;
    for (int i = 0; i < length; i++) ergebnisTempInnen = (ergebnisTempInnen * 10) + (payload[i] - '0');
    tempInnen = ergebnisTempInnen;

#ifdef DEBUG
    Serial.println(ergebnisTempInnen);
    Serial.println();
#endif
  }


  // Temp Aussen

  if (strcmp((char*)topic, TEMP1_TOPIC) == 0)
  {
    ergebnisTempAussen = 0;
    for (int i = 0; i < length; i++) ergebnisTempAussen = (ergebnisTempAussen * 10) + (payload[i] - '0');
    tempAussen = ergebnisTempAussen;

#ifdef DEBUG
    Serial.println(ergebnisTempAussen);
    Serial.println();
#endif
  }

  // Textfeld 1

  if (strcmp((char*)topic, TEXT_FELD1) == 0)
  {
    Serial.print(text.c_str());
    SoftSerial.print("page0.text1.txt=\"");
    SoftSerial.print(text.c_str());
    SoftSerial.write('"');
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
  }

  // Textfeld 2

  if (strcmp((char*)topic, TEXT_FELD2) == 0)
  {
    Serial.print(text.c_str());
    SoftSerial.print("page0.text2.txt=\"");
    SoftSerial.print(text.c_str());
    SoftSerial.write('"');
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
  }

  // Nextion Dim

  if (strcmp((char*)topic, NEX_DIM) == 0)
  {
    ergebnisNexDim = 0;
    for (int i = 0; i < length; i++) ergebnisNexDim = (ergebnisNexDim * 10) + (payload[i] - '0');
    nexDim = ergebnisNexDim;

#ifdef DEBUG
    Serial.println(ergebnisNexDim);
    Serial.println();
#endif
    SoftSerial.print("dim=\"");
    SoftSerial.print(nexDim);
    SoftSerial.write('"');
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
    SoftSerial.write(0xff);
  }
}

void mqttSettings()
{
  client.setServer(mqtt_server, 1883);
  client.setCallback(receivedCallback);
}


void nextionButtons()
{
/*
  if (cID == 1 && pID == 0)
  {
    client.publish(BUTTON1_TOPIC, "button1");
  }

  if (cID == 2 && pID == 0)
  {
    client.publish(BUTTON2_TOPIC, "button2");
  }

  if (cID == 3 && pID == 0)
  {
    client.publish(BUTTON3_TOPIC, "button3");
  }

  if (cID == 4 && pID == 0)
  {
    client.publish(BUTTON4_TOPIC, "button4");
  }

  if (cID == 1 && pID == 1)
  {
    client.publish(BUTTON5_TOPIC, "button5");
  }

  if (cID == 2 && pID == 1)
  {
    client.publish(BUTTON6_TOPIC, "button6");
  }

  if (cID == 2 && pID == 1)
  {
    client.publish(BUTTON7_TOPIC, "button7");
  }

    if (cID == 2 && pID == 1)
  {
    client.publish(BUTTON8_TOPIC, "button8");
  }

    if (cID == 9 && pID == 0)
  {
    client.publish(BUTTON9_TOPIC, "button9");
  }

    if (cID == 10 && pID == 0)
  {
    client.publish(BUTTON10_TOPIC, "button10");
  }

    if (cID == LEDNexoff && pID == control1)
    {
      LEDonOff(LOW);
    }

    if (cID == BeepNexon && pID == control2)
    {
      beepOnOff(HIGH);
    }

    if (cID == BeepNexoff && pID == control2)
    {
      beepOnOff(LOW);
    }*/
}

void nextion_event()
{
  if (tEv == touchEventRelease)
  {
    Serial.print("Touch Event: ");
    Serial.println("Release");

  }
  if (tEv == touchEventPress)
  {
    Serial.print("Touch Event: ");
    Serial.println("Press");
  }
}

void serialRead()
{
  if (SoftSerial.available() > 0)
  {
    for (int i = 0; i <= 6; i++)
    {
      incomingByte[i] = SoftSerial.read();
      Serial.println(incomingByte[i]);
      delay(5);
    }
    Serial.println("--------------------------------------------------------------------");

    if (incomingByte[0] == 101)
    {
      pID = incomingByte[1];
      cID = incomingByte[2];
      tEv = incomingByte[3];
      nextion_event();
      nextionButtons();
      //      nextionSlider();
//     nextionButtonVal();

      if (incomingByte[0] != 101)
      {
        pID = incomingByte[0];
        cID = incomingByte[1];
        tEv = incomingByte[2];
        nextion_event();
        nextionButtons();
        //        nextionSlider();
//        nextionButtonVal();
      }
    }
  }
}

void serialSend()
{
  unsigned long currentMillis3 = millis();
  if (currentMillis3 - previousMillis3 >= interval3)
  {
    previousMillis3 = currentMillis3;
    sprintf(hourDigit, "%02d", hourNex);
    sprintf(minuteDigit, "%02d", minute);
    sprintf(secondDigit, "%02d", second);
    serialSendChar("page0.hour.txt=\"", hourDigit);
    serialSendChar("page0.min.txt=\"", minuteDigit);
    serialSendChar("page0.sec.txt=\"", secondDigit);
    serialSendNum("page0.temp1.txt=\"", tempAussen / 100);
    serialSendNum("page0.temp2.txt=\"", tempInnen / 100);
    serialSendChar("page1.hour.txt=\"", hourDigit);
    serialSendChar("page1.min.txt=\"", minuteDigit);
    serialSendChar("page1.sec.txt=\"", secondDigit);
    serialSendChar("page0.tag.txt=\"", (char*)daysOfTheWeek[timeClient.getDay()]);
  }
}


void serialSendChar(char where[], char what[])
{
  SoftSerial.print(where);
  SoftSerial.print(what);
  SoftSerial.write('"');
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
}

void serialSendNum(char where[], int what)
{
  SoftSerial.print(where);
  SoftSerial.print(what);
  SoftSerial.write('"');
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
  SoftSerial.write(0xff);
}

void wifiSettings()
{
  //  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  WiFi.config(ip, gateway, subnet, dns);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("WiFi != WL_CONNECTED");
    unsigned long currentMillis5 = millis();
    if (currentMillis5 - previousMillis5 >= interval5)
    {
      previousMillis5 = currentMillis5;
      connects++;
    }

    for (int i = 0; i < NUMPIXELS; i++)
    {
      pixels.clear();
      pixels.setPixelColor(i % NUMPIXELS, pixels.Color(0, 255, 0, 0));
      pixels.setPixelColor((i - 1) % NUMPIXELS, pixels.Color(0, 100, 0, 0));
      pixels.setPixelColor((i - 2) % NUMPIXELS, pixels.Color(0, 20, 0, 0));
      pixels.setPixelColor((i - 3) % NUMPIXELS, pixels.Color(0, 0, 0, 0));
      pixels.show();
      delay(20);
    }
  }

  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("WiFi == WL_CONNECTED");
    for (int i = 0; i < NUMPIXELS; i++)
    {
      pixels.setPixelColor(i, pixels.Color(0, 0, 20, 0));
      pixels.show();
    }
    delay(200);
    for (int i = 0; i < NUMPIXELS; i++)
    {
      pixels.setPixelColor(i, pixels.Color(0, 0, 0, 0));
      pixels.show();
    }
    delay(200);
  }
}

Ich freue mich auf euer Feedback!

Nachtrag:

https://www.youtube.com/watch?v=spqpPsyG...e=youtu.be

Noch ein kurzes Video von der Uhr.

Am anfang lade ich gerade einen Code hoch. Dann sucht die Uhr nach Wlan, verbindet sich und legt los.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.08.2019, 12:58
Beitrag #2
RE: Neopixel Uhr mit Nextion und MQTT
Sieht optisch gut aus.

Welchen NTP-Client benutzt Du (bitte Link, es gibt mehrere)?
So, wie es aussieht, machst Du die Sommer-/Winterzeit-Umschaltung hart codiert im Programm mit utcOffsetInSeconds?

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.08.2019, 13:04
Beitrag #3
RE: Neopixel Uhr mit Nextion und MQTT
(05.08.2019 12:58)Tommy56 schrieb:  Sieht optisch gut aus.

Welchen NTP-Client benutzt Du (bitte Link, es gibt mehrere)?
So, wie es aussieht, machst Du die Sommer-/Winterzeit-Umschaltung hart codiert im Programm mit utcOffsetInSeconds?

Gruß Tommy

Moin,

dankeschön.

Ich nutze momentan diesen hier: https://github.com/arduino-libraries/NTPClient

Als NTP-Server nutze ich meine Fritzbox.

Genau.. Momentan ist Sommer-/Winterzeit noch hart codiert. Evtl bringt die Zukunft (Sofern ich das Datum noch einfüge), eine automatische umschaltung.

Vielleicht lasse ich die Umschaltung aber auch über Node-Red laufen, da müsste es in der Palette schon flows geben, die mir Sommer/Winterzeit zurückmelden.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.08.2019, 13:33
Beitrag #4
RE: Neopixel Uhr mit Nextion und MQTT
Die Lib benutzt den Offset nur zur Anzeige und arbeitet intern mit utc.
Wenn Du willst, kannst Du mal folgendes ausprobieren (Änderung in der NTPClient.cpp):
Code:
// Neue Funktion
// nach European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// Param: UTC-Unixtime
// Return Offset
time_t NTPClient::calcOffset(unsigned long utc) {
const uint8_t tz_utc = 0;
uint16_t y = year(utc);
uint8_t m,h,d;
  m = month(utc);
  h = hour(utc);
  d = day(utc);
  if (m < 3 || m > 10) return utc + 3600; // +1h
  if (m > 3 && m < 10) return utc + 7200; // +2h
  if ((((m == 3) && ((h +24 * d) >= (1+ tz_utc + 24 * (31 - (5 * y / 4 +4) % 7))))
    || ((m == 10) && ((h +24 * d) >= (1+ tz_utc + 24 * (31 - (5 * y / 4 +4) % 7)))))) return utc + 7200;
  else return utc + 3600;  
}

// Die ist schon drin - Änderung vorletzte Zeile
bool NTPClient::forceUpdate() {
  #ifdef DEBUG_NTPClient
    Serial.println("Update from NTP Server");
  #endif

  this->sendNTPPacket();

  // Wait till data is there or timeout...
  byte timeout = 0;
  int cb = 0;
  do {
    delay ( 10 );
    cb = this->_udp->parsePacket();
    if (timeout > 100) return false; // timeout after 1000 ms
    timeout++;
  } while (cb == 0);

  this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time

  this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE);

  unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
  unsigned long lowWord = word(this->_packetBuffer[42], this->_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;

  this->_currentEpoc = secsSince1900 - SEVENZYYEARS;

  this->_timeOffset = calcOffset(_currentEpoc); // <--- Offset bestimmen
  
  return true;
}

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.08.2019, 13:43
Beitrag #5
RE: Neopixel Uhr mit Nextion und MQTT
Hey,

das ersetzt aber nicht komplett ALLES in der .cpp, oder?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.08.2019, 13:47
Beitrag #6
RE: Neopixel Uhr mit Nextion und MQTT
(05.08.2019 13:43)MeisterQ schrieb:  Hey,

das ersetzt aber nicht komplett ALLES in der .cpp, oder?
Nö, nur die eine neue Methode rein und in der danach stehenden die vorletzte Zeile (<---) einfügen.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.08.2019, 14:37
Beitrag #7
RE: Neopixel Uhr mit Nextion und MQTT
(05.08.2019 13:47)Tommy56 schrieb:  
(05.08.2019 13:43)MeisterQ schrieb:  Hey,

das ersetzt aber nicht komplett ALLES in der .cpp, oder?
Nö, nur die eine neue Methode rein und in der danach stehenden die vorletzte Zeile (<---) einfügen.

Gruß Tommy

Verstehe ich nicht.
Hab noch nie die .cpps bearbeitet und mit dem Editor ist das auch ein kramp was die Formatierung angeht.

Für mich logisch wäre es jetzt einfach den von dir geposteten Code GANZ am ende einzufügen.

Aber wo wird diese dann aufgerufen?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
05.08.2019, 15:38
Beitrag #8
RE: Neopixel Uhr mit Nextion und MQTT
Ich frage mich immer wieder, wie Du mit derart mangelhaften Grundkenntnissen Sachen zum Laufen bringst.
Hier die geänderte NTPClient.cpp:
Code:
/**
* The MIT License (MIT)
* Copyright (c) 2015 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include "NTPClient.h"

NTPClient::NTPClient(UDP& udp) {
  this->_udp            = &udp;
}

NTPClient::NTPClient(UDP& udp, long timeOffset) {
  this->_udp            = &udp;
  this->_timeOffset     = timeOffset;
}

NTPClient::NTPClient(UDP& udp, const char* poolServerName) {
  this->_udp            = &udp;
  this->_poolServerName = poolServerName;
}

NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset) {
  this->_udp            = &udp;
  this->_timeOffset     = timeOffset;
  this->_poolServerName = poolServerName;
}

NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval) {
  this->_udp            = &udp;
  this->_timeOffset     = timeOffset;
  this->_poolServerName = poolServerName;
  this->_updateInterval = updateInterval;
}

void NTPClient::begin() {
  this->begin(NTP_DEFAULT_LOCAL_PORT);
}

void NTPClient::begin(int port) {
  this->_port = port;

  this->_udp->begin(this->_port);

  this->_udpSetup = true;
}

// nach European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// Param: UTC-Unixtime
// Return Offset

long NTPClient::calcOffset(unsigned long utc) {
const uint8_t tz_utc = 0;
uint16_t y = year(utc);
uint8_t m,h,d;
  m = month(utc);
  h = hour(utc);
  d = day(utc);
  if (m < 3 || m > 10) return utc + 3600; // +1h
  if (m > 3 && m < 10) return utc + 7200; // +2h
  if ((((m == 3) && ((h +24 * d) >= (1+ tz_utc + 24 * (31 - (5 * y / 4 +4) % 7))))
    || ((m == 10) && ((h +24 * d) >= (1+ tz_utc + 24 * (31 - (5 * y / 4 +4) % 7)))))) return utc + 7200;
  else return utc + 3600;  
}

bool NTPClient::forceUpdate() {
  #ifdef DEBUG_NTPClient
    Serial.println("Update from NTP Server");
  #endif

  this->sendNTPPacket();

  // Wait till data is there or timeout...
  byte timeout = 0;
  int cb = 0;
  do {
    delay ( 10 );
    cb = this->_udp->parsePacket();
    if (timeout > 100) return false; // timeout after 1000 ms
    timeout++;
  } while (cb == 0);

  this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time

  this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE);

  unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
  unsigned long lowWord = word(this->_packetBuffer[42], this->_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;

  this->_currentEpoc = secsSince1900 - SEVENZYYEARS;

  this->_timeOffset = calcOffset(_currentEpoc); // <--- Offset bestimmen

  return true;
}

bool NTPClient::update() {
  if ((millis() - this->_lastUpdate >= this->_updateInterval)     // Update after _updateInterval
    || this->_lastUpdate == 0) {                                // Update if there was no update yet.
    if (!this->_udpSetup) this->begin();                         // setup the UDP client if needed
    return this->forceUpdate();
  }
  return true;
}

unsigned long NTPClient::getEpochTime() const {
  return this->_timeOffset + // User offset
         this->_currentEpoc + // Epoc returned by the NTP server
         ((millis() - this->_lastUpdate) / 1000); // Time since last update
}

int NTPClient::getDay() const {
  return (((this->getEpochTime()  / 86400L) + 4 ) % 7); //0 is Sunday
}
int NTPClient::getHours() const {
  return ((this->getEpochTime()  % 86400L) / 3600);
}
int NTPClient::getMinutes() const {
  return ((this->getEpochTime() % 3600) / 60);
}
int NTPClient::getSeconds() const {
  return (this->getEpochTime() % 60);
}

String NTPClient::getFormattedTime() const {
  unsigned long rawTime = this->getEpochTime();
  unsigned long hours = (rawTime % 86400L) / 3600;
  String hoursStr = hours < 10 ? "0" + String(hours) : String(hours);

  unsigned long minutes = (rawTime % 3600) / 60;
  String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes);

  unsigned long seconds = rawTime % 60;
  String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds);

  return hoursStr + ":" + minuteStr + ":" + secondStr;
}

void NTPClient::end() {
  this->_udp->stop();

  this->_udpSetup = false;
}

void NTPClient::setTimeOffset(int timeOffset) {
  this->_timeOffset     = timeOffset;
}

void NTPClient::setUpdateInterval(unsigned long updateInterval) {
  this->_updateInterval = updateInterval;
}

void NTPClient::setPoolServerName(const char* poolServerName) {
    this->_poolServerName = poolServerName;
}

void NTPClient::sendNTPPacket() {
  // set all bytes in the buffer to 0
  memset(this->_packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  this->_packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  this->_packetBuffer[1] = 0;     // Stratum, or type of clock
  this->_packetBuffer[2] = 6;     // Polling Interval
  this->_packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  this->_packetBuffer[12]  = 49;
  this->_packetBuffer[13]  = 0x4E;
  this->_packetBuffer[14]  = 49;
  this->_packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  this->_udp->beginPacket(this->_poolServerName, 123); //NTP requests are to port 123
  this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE);
  this->_udp->endPacket();
}

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Arduino Nano, Sensoren und Nextion MotD 24 8.039 30.08.2018 10:42
Letzter Beitrag: hotsystems
  Arduino mit Nextion komunizieren lassen Steve1604 4 6.627 01.08.2016 21:56
Letzter Beitrag: hotsystems

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste