Eine etwas andere Uhr mit RGB Led-Ring und D1 Mini - AZ-Delivery

Heute wollen wir mit dem RGB-Led Ring der neu im Angebot von AZ-Delivery ist und einem D1-Mini eine Uhr bauen die über NTP synchronisiert wird. Die Zeiger werden durch verschiedene Farben symbolisiert. Sekundenzeiger = rot, Minutenzeiger = grün und Stundenzeiger = blau. Zur Anzeige wird diejenige der 12 Leds, die sich unter dem entsprechenden Zeiger befindet auf die Farbe des Zeigers geschaltet. Ist ein Zeiger zwischen zwei Leds, leuchten beide in der entsprechenden Farbe wobei jene, die näher am Zeiger ist, heller leuchtet.

Wenn ihr noch zusätzlich ein Trimmpotentiometer spendiert, könnt ihr auch die Helligkeit der Anzeige regeln. In dem Fall bitte die Auskommentierung der folgenden Zeile aufheben, indem ihr die beiden Schrägstriche "//"  am Zeilenanfang entfernt.

#define POTENTIOMETER //uncomment to use potentiometer for brightness

Ihr dürft auch nicht vergessen im Code eure Zugangsdaten bei "MYSSID" und "MYPWD" einzugeben.

 

Der Code:

 

#include <NeoPixelBus.h> //library for led strip
//libraries for WiFi and NTP
#include <ESP8266WiFi.h> 
#include <NtpClientLib.h>
#include <TimeLib.h>


//NTP Server setup
//if possible use local router for NTP server
//higher availability fast response
#define NTP_SERVER "fritz.box" // "pool.ntp.org" 
#define GMT_TIMEZONE 1
#define DAYLIGHT true
#define TIMEZONE_MINUTES 0


//here add your access information
#define MYSSID "************"
#define MYPWD "******************"
//#define POTENTIOMETER // uncomment to use potentiometer for brightness

const uint16_t PixelCount = 12; // this example assumes 12 pixels, making it smaller will cause a failure
const uint8_t PixelPin = 2;  // make sure to set this to the correct pin, ignored for Esp8266

//initialize LED strip driver
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);

//color definition for black to switch leds off
RgbColor black(0);

//some global vatriables
boolean connected = false;
bool wifiFirstConnected = false;
uint8_t colorSaturation = 64; //maximum brightness

//callback on WiFi connected
void onSTAConnected (WiFiEventStationModeConnected ipInfo) {
    Serial.printf ("Connected to %s\r\n", ipInfo.ssid.c_str ());
}

//callback on got IP address
// Start NTP only after IP network is connected
void onSTAGotIP (WiFiEventStationModeGotIP ipInfo) {
    Serial.printf ("Got IP: %s\r\n", ipInfo.ip.toString ().c_str ());
    Serial.printf ("Connected: %s\r\n", WiFi.status () == WL_CONNECTED ? "yes" : "no");
    wifiFirstConnected = true; //set flag to start NTP in main loop
    connected = true;
}

// Manage network disconnection
void onSTADisconnected (WiFiEventStationModeDisconnected event_info) {
    Serial.printf ("Disconnected from SSID: %s\n", event_info.ssid.c_str ());
    Serial.printf ("Reason: %d\n", event_info.reason);
    //NTP.stop(); // NTP sync can be disabled to avoid sync errors
}

//callback on NTP events
void processSyncEvent (NTPSyncEvent_t ntpEvent) {
    if (ntpEvent) {
        Serial.print ("Time Sync error: ");
        if (ntpEvent == noResponse)
            Serial.println ("NTP server not reachable");
        else if (ntpEvent == invalidAddress)
            Serial.println ("Invalid NTP server address");
    } else {
        //Serial.print ("Got NTP time: ");
        //Serial.println (NTP.getTimeDateString (NTP.getLastNTPSync ()));
    }
}

boolean syncEventTriggered = false; // True if a time event has been triggered
NTPSyncEvent_t ntpEvent; // Last triggered event

//this function gets the seconds of the day and calculate the led position and brightness
void setTime(uint32_t seconds) {
  //array to collect RGB values
  uint8_t red[12];
  uint8_t green[12];
  uint8_t blue[12];
  //one led every five seconds and twelfe leds at all
  uint8_t led_s1 = seconds / 5 % 12;
  //second led is the next led or 0 if we reached the end
  uint8_t led_s2 = (led_s1 < 11)?led_s1+1:0;
  //one led every 300 seconds and twelfe leds at all 
  uint8_t led_m1 = seconds / 300 % 12;
  uint8_t led_m2 = (led_m1 < 11)?led_m1+1:0;
  //one led every 3600 seconds and twelfe leds at all 
  uint8_t led_h1 = seconds / 3600 % 12;
  uint8_t led_h2 = (led_h1 < 11)?led_h1+1:0;
  //for the values for seconds we split it into 5 parts with 1 second
  uint8_t val_s = (seconds % 5) * colorSaturation /5;
  //for values for minutes we split it into 15 parts with 20 seconds
  uint8_t val_m = ((seconds / 20) % 15) * colorSaturation /15;
  //for values for hours we split it into 16 parts with 225 seconds
  uint8_t val_h = ((seconds / 225) % 16) * colorSaturation /16;
  //Serial.printf("Sek = %i %i:%i:%i values %i:%i:%i \n",seconds,led_s1,led_m1,led_h1,val_s,val_m,val_h);
  //now we fill the rgb arrays with 0 for black
  for (uint8_t i = 0; i<12; i++) {
    red[i]=0; green[i]=0; blue[i] =0; 
  }
  //next we set the values for the leds as calculated before
  red[led_s1] = colorSaturation - val_s;
  red[led_s2] = val_s;
  green[led_m1] = colorSaturation - val_m;
  green[led_m2] = val_m;
  blue[led_h1] = colorSaturation - val_h;
  blue[led_h2] = val_h;
  //at last we prepare the send buffer for sending to the strip
  for (uint8_t i = 0; i<12; i++) {
    RgbColor col(red[i],green[i],blue[i]);
    HslColor hcol(col);
    strip.SetPixelColor(i,hcol);
  }
}


void setup() {
    static WiFiEventHandler e1, e2, e3;

    Serial.begin(115200);
    while (!Serial); // wait for serial attach

    Serial.println();
    Serial.println("Initializing...");
    Serial.flush();

    // this resets all the neopixels to an off state
    strip.Begin();
    strip.Show();


    Serial.println();
    Serial.println("Connecting...");
    WiFi.mode(WIFI_STA);
    WiFi.begin(MYSSID, MYPWD);

    NTP.onNTPSyncEvent ([](NTPSyncEvent_t event) {
        ntpEvent = event;
        syncEventTriggered = true;
    });

    e1 = WiFi.onStationModeGotIP (onSTAGotIP);// As soon WiFi is connected, start NTP Client
    e2 = WiFi.onStationModeDisconnected (onSTADisconnected);
    e3 = WiFi.onStationModeConnected (onSTAConnected);
    
}


time_t t;
uint32_t s;
void loop() {
  yield(); //to allow background tasks
  static int last = 0;
  if (wifiFirstConnected) {
      //if we are connected we start NTP
      wifiFirstConnected = false;
      NTP.begin (NTP_SERVER, GMT_TIMEZONE, DAYLIGHT, TIMEZONE_MINUTES);
      NTP.setInterval (63);
  }

  if (syncEventTriggered) {
      //we got a NTP event
      processSyncEvent (ntpEvent);
      syncEventTriggered = false;
  }
  if (connected && ((millis () - last) > 1000)) {
#ifdef POTENTIOMETER
      //if we use a potentiometer for brightness we read the
      //value from pin A0
      colorSaturation = analogRead(A0) /16; //max = 64
#endif
     //every second we update led strip
      last = millis();
      t = NTP.getTime();
      if (t>0) {
        //if we got a time we calculate the seconds of the day
        s = hour(t)*3600+minute(t)*60+second(t);
      } else {
        //otherwise we increment the seconds
        s++;
      }
      //set the leds and send it to the strip
      setTime(s);
      strip.Show();
  }
}

 

 

Alle erforderlichen Bibliotheken können über die Arduino Bibliotheksverwaltung registriert werden:

 

Die Schaltung:

 

Die Schaltung ist ganz einfach. Der RX-Pin des ESP8266 wird wegen der DMA Möglichkeiten genutzt. Nicht wundern wenn während des Programm-Hochladens alle LEDs weiß leuchten. Die Controller der WS2812 können mit den Daten auf der Seriellen Schnittstelle nichts anfangen. Das Potentiometer wird zwischen 3.3 V und Masse geschaltet. Der Schleifer kommt an A0.

Viel Spass beim Basteln.

 

Esp-8266Projekte für anfänger

26 Kommentare

Kommentar hinterlassen

Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery