I'm using the ESP-12e with Arduino IDE. With that I'm trying to build a clock with a WS2812B LED strip matrix that I've build. When I try to display the seconds on my matrix there are strange timing problems. It shows me the numbers how I should, the LEDs work OK but ..it misses seconds spontaneously. sometime it jumps the numbers like 00 01 03 06, sometimes 00 02 03 05.. sometimes it hangs at one number for a short time.
- Is the problem in my code?
- Or is it due to hardware limitations of the ESP-12e?
- How can I do it better?
Here is my sketch (I removed some number definitions [...] for better overview):
#include <ESP8266WiFi.h> //WiFi
#include <Adafruit_NeoPixel.h> //LEDs
#include <TimeLib.h> //Time
#include <WiFiUdp.h> //Synchronize Time
const char* ssid = "XXXXX";
const char* password = "XXXXXXX";
WiFiClient wifiClient;
//NTP Servers
static const char ntpServerName[] = "us.pool.ntp.org";
const int timeZone = 1; // Central European Time
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
time_t getNtpTime();
void digitalClockDisplay();
void printDigits(int digits);
void sendNTPpacket(IPAddress &address);
// Setup Wifi
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
/*-------- NTP code ----------*/
// ====================================
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime()
{
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
// get a random server from the pool
WiFi.hostByName(ntpServerName, ntpServerIP);
Serial.print(ntpServerName);
Serial.print(": ");
Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
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 + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// 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();
}
// NEO PIXELS
// ====================================
// Setup
#define PIN 0
#define NUMPIXELS 224
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int individualPixels[NUMPIXELS];
// Time variables
int hs;
int m;
int s;
// For Loops
int x;
// RGB color variables
int red;
int green;
int blue;
void colorBlue(){
red = 0;
green = 0;
blue = 100;
}
/* IN LOOP Light pixels corresponding to current time */
void neoPixler(){
for (x=0; x<sizeof(individualPixels); x++){
if (individualPixels[x]==1){
pixels.setPixelColor(x, pixels.Color(red,green,blue)); //Set Neopixel color
}
else{
pixels.setPixelColor(x,pixels.Color(0,0,0));
}
}
pixels.show(); //Display Neopixel color
}
// ALL OFF
void turnOff(){
for(x=0; x<pixels.numPixels(); x++) {
individualPixels[x]=0;
pixels.show();
}
}
//Numbers
void dl_one(){
individualPixels[160]=1;
individualPixels[161]=1;
individualPixels[146]=1;
individualPixels[147]=1;
individualPixels[116]=1;
individualPixels[117]=1;
individualPixels[102]=1;
individualPixels[103]=1;
individualPixels[72]=1;
individualPixels[73]=1;
individualPixels[58]=1;
individualPixels[59]=1;
individualPixels[28]=1;
individualPixels[29]=1;
individualPixels[148]=1;
individualPixels[149]=1;
individualPixels[112]=1;
individualPixels[113]=1;
}
void dr_one(){
individualPixels[172]=1;
individualPixels[173]=1;
individualPixels[134]=1;
individualPixels[135]=1;
individualPixels[128]=1;
individualPixels[129]=1;
individualPixels[90]=1;
individualPixels[91]=1;
individualPixels[84]=1;
individualPixels[85]=1;
individualPixels[46]=1;
individualPixels[47]=1;
individualPixels[40]=1;
individualPixels[41]=1;
individualPixels[136]=1;
individualPixels[137]=1;
individualPixels[124]=1;
individualPixels[125]=1;
}
void dl_two(){
individualPixels[152]=1;
individualPixels[153]=1;
individualPixels[156]=1;
individualPixels[157]=1;
individualPixels[158]=1;
individualPixels[159]=1;
individualPixels[160]=1;
individualPixels[161]=1;
individualPixels[144]=1;
individualPixels[145]=1;
individualPixels[118]=1;
individualPixels[119]=1;
individualPixels[104]=1;
individualPixels[105]=1;
individualPixels[102]=1;
individualPixels[103]=1;
individualPixels[68]=1;
individualPixels[69]=1;
individualPixels[64]=1;
individualPixels[65]=1;
individualPixels[22]=1;
individualPixels[23]=1;
individualPixels[24]=1;
individualPixels[25]=1;
individualPixels[26]=1;
individualPixels[27]=1;
individualPixels[28]=1;
individualPixels[29]=1;
individualPixels[30]=1;
individualPixels[31]=1;
}
void dr_two(){
individualPixels[34]=1;
individualPixels[35]=1;
individualPixels[36]=1;
individualPixels[37]=1;
individualPixels[38]=1;
individualPixels[39]=1;
individualPixels[40]=1;
individualPixels[41]=1;
individualPixels[42]=1;
individualPixels[43]=1;
individualPixels[52]=1;
individualPixels[53]=1;
individualPixels[80]=1;
individualPixels[81]=1;
individualPixels[92]=1;
individualPixels[93]=1;
individualPixels[90]=1;
individualPixels[91]=1;
individualPixels[132]=1;
individualPixels[133]=1;
individualPixels[130]=1;
individualPixels[131]=1;
individualPixels[168]=1;
individualPixels[169]=1;
individualPixels[170]=1;
individualPixels[171]=1;
individualPixels[172]=1;
individualPixels[173]=1;
individualPixels[140]=1;
individualPixels[141]=1;
}
[......]
// Seconds
// ====================================
void print_numbers(byte num){
byte num10;
byte num1;
num1=num%10;
num10=(num-num1)/10;
switch (num10){ //10...
case 0:
dl_null();
break;
case 1:
dl_one();
break;
case 2:
dl_two();
break;
case 3:
dl_three();
break;
case 4:
dl_four();
break;
case 5:
dl_five();
break;
}
switch (num1){ //1...
case 0:
dr_null();
break;
case 1:
dr_one();
break;
case 2:
dr_two();
break;
case 3:
dr_three();
break;
case 4:
dr_four();
break;
case 5:
dr_five();
break;
case 6:
dr_six();
break;
case 7:
dr_seven();
break;
case 8:
dr_eight();
break;
case 9:
dr_nine();
break;
}
}
void seconds(){
/* Get current time */
s=second();
turnOff();
print_numbers(s);
neoPixler(); // Lights
}
void setup() {
// Debug info
Serial.begin(115200);
Serial.println(F("Booting"));
setup_wifi();
// Setup UDP Time + Sync Time
Serial.println("Starting UDP");
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(3000);
/* NEO PIXELS ------------------------------------------------------------------------------------------------------*/
colorBlue(); //Standard Color
pixels.begin(); //Begin Neopixel string
pixels.show(); // Initialize all pixels to 'off'
}
void loop() {
seconds();
}