Fully functional version below. Will post some video when I can. Extremely pleased with the outcome...zero flicker as desired, and beautifully smooth updates.
//LightBox
//Sketch to control a lightbox consisting of 144 WS2812B LEDs
//arranged in a 12x12 grid
//external controls will allow full control of RGB output
//for the whole set of LEDs and for a selected individual LED.
//by Nigel Coxon 13/4/2018
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#define N_LEDS 144 //LEDS in grid
#define PIN 8 //output pin for LED data
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);
int RedPin = A0; // set the input pin for red potentiometer control
int GrnPin = A1; // set the input pin for green potentiometer control
int BluPin = A2; // set the input pin for blue potentiometer control
int RvalA = 0; // variable to store the analog values coming from the Red potentiometer
int GvalA = 0; // variable to store the analog values coming from the Green potentiometer
int BvalA = 0; // variable to store the analog values coming from the Blue potentiometer
byte Rval = 0; // Red value for sending to LEDs
byte Gval = 0; // Green
byte Bval = 0; // Blue
String RString = String(000);
String GString = String(000);
String BString = String(000);
const uint8_t addr = 0x70; // HT16K33 default address
uint16_t displayBuffer[9]; // Steve - if this is characters, I need to array to 9 as the loop runs 0 to 8.
uint16_t segmentcode[9]; // this holds the data in segment order for each character (ie segment a state for char 0-0, followed by segment b etc
String displayvals = String(000000000); // Data for LCD display
long lastread = millis();
const uint8_t NigelNumbers[10] = {
//binary hex dec displays
//segment
//.gfedcba
0b00111111, // 3F 63 0
0b00000110, // 06 6 1
0b01011011, // 58 91 2
0b01001111, // 4F 79 3
0b01100110, // 66 102 4
0b01101101, // 69 109 5
0b01111101, // 7D 125 6
0b00000111, // 07 7 7
0b01111111, // 7F 127 8
0b01101111, // 6F 111 9
};
byte pixelarray[12][12] = {
{ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,},
{ 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11,},
{ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,},
{ 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35,},
{ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,},
{ 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59,},
{ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,},
{ 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83,},
{ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,},
{ 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107,},
{ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,},
{ 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131,}
};
// The pixelarray is used in the form "pixelarray[x][y]" to return the sequential pixel number in the strip.
// The double zero at the start is intentional as I have one damaged pixel due to a soldering mistake.
int lightpitch = 1; //sometimes I use a grid of 30-pitch LEDS. Changing lightpitch to 2 simulates this (lights every other LED)
void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(addr);
Wire.write(0x20 | 1); // turn on oscillator
Wire.endTransmission();
setBrightness(15);
blink(0);
strip.setBrightness(255);
strip.begin();
//blank all registers
Wire.beginTransmission(0x70);
Wire.write(0x00);
for (int i = 0; i < 8; i++) {
Wire.write(0x00);
Wire.write(0x00);
}
Wire.endTransmission();
Serial.println("Blank step 1/3");
delay(500);
//fill all registers
Wire.beginTransmission(0x70);
Wire.write(0x00);
for (int i = 0; i < 8; i++) {
Wire.write(0xFF);
Wire.write(0xFF);
}
Wire.endTransmission();
Serial.println("Blank step 2/3");
delay(500);
//blank all registers again
Wire.beginTransmission(0x70);
Wire.write(0x00);
for (int i = 0; i < 8; i++) {
Wire.write(0x00);
Wire.write(0x00);
}
Wire.endTransmission();
Serial.println("Blank step 3/3");
delay(500);
}
void loop() {
Serial.println("New void loop");
int p = 0;
// intialise pixels with current values
for (p = 0; p < N_LEDS; p++) {
strip.setPixelColor(p, Rval, Gval, Bval);
}
strip.show();
// read the values from the sensors
analogReference(DEFAULT);
RvalA = analogRead(RedPin);
GvalA = analogRead(GrnPin);
BvalA = analogRead(BluPin);
//convert from 0-1023 (5v) to 0-255
Rval = RvalA * 0.25;
Gval = GvalA * 0.25;
Bval = BvalA * 0.25;
//update pixels with new value
for (p = 0; p < N_LEDS; p++) {
strip.setPixelColor(p, Rval, Gval, Bval);
}
strip.show();
//update the LCD display with the new value
RString = String(Rval);
GString = String(Gval);
BString = String(Bval);
while (RString.length() != 3) {
RString = "0" + RString;
}
while (GString.length() != 3) {
GString = "0" + GString;
}
while (BString.length() != 3) {
BString = "0" + BString;
}
displayvals = RString + GString + BString;
//transfer displayvals to displaybuffer
for (int i = 0; i < 9; i++) {
char c = displayvals.charAt(i);
int x = c - '0';
displayBuffer[i] = NigelNumbers[x];
}
//clear segmentcode
for (int i = 0; i < 9; i++) {
segmentcode[i] = 1;
}
//populate segmentcode from displayBuffer
for (int i = 0; i < 9; i++) {
for (int k = 9; k >= 0; k--) {
//delay(1000);
segmentcode[i] = (segmentcode[i] << 1) + ((displayBuffer[k] >> i) & 1);
//delay(1000);
}
segmentcode[i] = segmentcode[i] - 512;
}
//output segmentcode to LCDs
Wire.beginTransmission(0x70);
Wire.write (0x00); // initiation nybble
for (int segment = 0; segment < 8; segment++) { //loops segments to update
Wire.write(segmentcode[segment]);
Wire.write((segmentcode[segment] >> 8));
}
Wire.endTransmission();
Serial.print(Bval);
Serial.print ("\t");
Serial.print(Rval);
Serial.print ("\t");
Serial.println(Gval);
//Serial.print(Rval);
//Serial.print ("\t");
//Serial.print(Gval);
//Serial.print ("\t");
//Serial.println(Bval);
//Serial.println(displayvals);
}
void clear() {
for (int i = 0; i < 8; i++) {
displayBuffer[i] = 0;
}
}
void setBrightness(uint8_t b) {
if (b > 15) return;
Wire.beginTransmission(addr);
Wire.write(0xE0 | b); // Dimming command
Wire.endTransmission();
}
void blank() {
static boolean blankOn;
Wire.beginTransmission(addr);
Wire.write(0x80 | blankOn); // Blanking / blinking command
Wire.endTransmission();
blankOn = !blankOn;
}
void blink(uint8_t b) {
if (b > 3) return;
Wire.beginTransmission(addr);
Wire.write(0x80 | b << 1 | 1); // Blinking / blanking command
Wire.endTransmission();
}