It's likely the problems are in your code somewhere; but not enough information is available to say for sure.
Your first step toward debugging the problem probably should be taking any ESP-12e issues out of the mix. At the beginning of getNtpTime()
temporarily add something like return 1477897101UL + millis()/1000;
to get a sync-time that advances at the correct rate and is repeatable for testing. If the display suddenly begins updating smoothly, look for problems in your time code, else in the display code.
The technique of duplicating a whole bunch of individualPixels[116]=1;
lines (with different pixel numbers) is crude, tedious, verbose, error-prone, inflexible, etc. You might instead create some arrays and use a loop to set pixel data. For example:
const byte L1[] = {160, 161, 146, 147, 116, 117, 102, 103, 72, 73, 58, 59, 28, 29, 148,
149, 112, 113, 0};
...
const byte R2[] = {34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 52, 53, 80, 81, 92, 93, 90,
91, 132, 133, 130, 131, 168, 169, 170, 171, 172, 173, 140, 141, 0};
void loadDigit(byte *pixelList) {
for (byte j=0; pixelList[j]; ++j)
individualPixels[pixelList[j]] = 1;
}
...
loadDigit(L1); // Write a left 1
...
loadDigit(R2); // Write a right 2
You could also create an array of addresses of number-data arrays, to get rid of the crude, tedious (etc.) switch/case statements in print_numbers()
. For example:
const byte *digitsL[] = {L0, L1, L2, L3, L4, L5, L6, L7, L8, L9};
const byte *digitsR[] = {R0, R1, R2, R3, R4, R5, R6, R7, R8, R9};
...
if (num>9)
loadDigit(digitsL[num/10]); // Write tens digit
loadDigit(digitsR[num%10]); // Write units digit
If your matrix is logically organized, all of the 1's in R0 are at constant offsets from the 1's in L0 (for example, 12 more), and similarly for other digits. If that's the case, you could modify loadDigit()
to take a second parameter, offset
, which indicates where to place the digit in the matrix, ie, tells loadDigit()
how much to add via a statement like individualPixels[offset+pixelList[j]] = 1;
. Then you could leave out the R0 ... R9
arrays (and digitsR[]
as well) and use code like the following:
...
if (num>9)
loadDigit(digitsL[num/10], 0); // Write tens digit at left
loadDigit(digitsL[num%10], 12); // Write units digit at right
A drawback to using const byte
arrays like L0 ... L9
and R0 ... R9
is that when your program starts they get copied from PROGMEM into RAM for access. It would make sense to declare them in PROGMEM, and use them directly from PROGMEM by appropriate changes. [Edit: See example program, below]
Note, a string of 224 WS2812B units takes about 6.7 ms to update: 224 units x 24 bits x 1.25 μs/bit. Each time you update your matrix of lights, the millis()
counter, timer0_millis
, will lose 5 or 6 ms because pixels.show()
runs with interrupts turned off. To compensate, you could add 5 to timer0_millis
after each update. To make the loss always be 5 ms instead of sometimes 5 and sometimes 6, add the following code just before pixels.show()
: unsigned long now=millis(); while (now==millis());
, which will stall until the end of the current millisecond. To see how to change timer0_millis
, see the "Better Alternative" section of my answer to "How to keep accurate millis() while using ADC_sleep mode?".
I'd remove the pixels.show()
call from turnOff()
because you will (I think) always be calling pixels.show()
shortly after that, after loading number images, to turn on a bunch of other pixels. That is, clear the array, fill the necessary 1's, then show, without a show between clearing and filling.
Following is an example program that illustrates storing a constant array of bytes in PROGMEM, and accessing its entries via pgm_read_byte()
calls.
// Sketch that accepts a number k via serial input, and responds with
// the k-th set of numbers from among some sets of numbers stored in
// PROGMEM. This avoids copying the array data into RAM. jiw 31 Oct 2016
#include <Streaming.h> // Ref: http://arduiniana.org/libraries/streaming/
// Set up datatext in PROGMEM
const byte L1[] PROGMEM = { 102, 103, 112, 113, 116, 117, 146, 147, 148,
149, 160, 161, 28, 29, 58, 59, 72, 73, 0};
const byte R1[] PROGMEM = { 124, 125, 128, 129, 134, 135, 136, 137, 172,
173, 40, 41, 46, 47, 84, 85, 90, 91, 0};
const byte L2[] PROGMEM = { 152, 153, 156, 157, 158, 159, 160, 161, 144,
145, 118, 119, 104, 105, 102, 103, 68, 69, 64,
65, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0};
const byte R2[] PROGMEM = { 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 52,
53, 80, 81, 92, 93, 90, 91, 132, 133, 130,
131, 168, 169, 170, 171, 172, 173, 140, 141, 0};
const void* Addrs[] = { L1, R1, L2, R2 };
enum { nAddrs = sizeof Addrs / sizeof Addrs[0] };
void prompt() {
Serial << endl << "Please enter item number from 1 to " << _DEC(nAddrs) << ": ";
}
void setup() {
Serial.begin(115200); // init serial port
prompt(); // Issue initial prompt
}
void loop() {
char c, d;
while (Serial.available()) { // Get characters
c = Serial.read();
if (c >= '0' && c <= '9') {
Serial << c << endl; // Echo the entered digit
d = c - '0' - 1;
if (d>=0 && d < nAddrs) {
byte k=0, t = pgm_read_byte(Addrs[d]);
Serial << "Set #" << _DEC(d+1) << ": ";
while (t) {
Serial << _HEX(t) << ' ';
t = pgm_read_byte(++k + Addrs[d]);
}
Serial << endl;
}
prompt(); // Issue prompt after any digit
}
}
}
- 8.9k
- 3
- 21
- 33