Different from your approach, but here is my "color collider" code. It moves 2 different colors to the center of the string and changes a few middle LEDs to be color of the 2 "colliding" colors. It is set up as a stand alone access point, so if you want to use it in station mode you need to change the WiFi set up. The code you are probably interested in is in the handleRoot() routine.
#include <NetworkInfo.h>
#include <TransmissionResult.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
ESP8266WebServer server(80); // web server on standard port
ESP8266HTTPUpdateServer httpUpdater;
#include <DNSServer.h>
const byte DNS_PORT = 53; // name server on standard port
IPAddress apIP(192, 168, 6, 1); // IP address to use in non-routed range
DNSServer dnsServer;
#include <FS.h>
#include <user_interface.h>
#include <string.h>
#include <Streaming.h> // from "Streaming by Mikal Hart" in library manager
const char* ap_ssid = "Colors"; // Default AP ssid if board ID not found
const char* ap_password = "lightupleds"; // AP Password
const char* host = "www.leds.com"; // DNS host name
#include <NeoPixelBus.h>
const uint16_t pixelCount = 144;
#define colorSaturation 127
// three element pixels, in different order and speeds
// For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use.
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(pixelCount);
RgbColor red(colorSaturation, 0, 0);
RgbColor green(0, colorSaturation, 0);
RgbColor blue(0, 0, colorSaturation);
RgbColor white(colorSaturation);
RgbColor black(0);
RgbColor leftColor = red;
RgbColor rightColor = green;
bool firstTime = true;
void handleRoot(){
String htmlPage;
htmlPage.reserve(3800); // reserve space for HTML page
if (server.hasArg("lred")) {
// we have input data - assume they are all set
leftColor = RgbColor(server.arg("lred").toInt(),server.arg("lgreen").toInt(),server.arg("lblue").toInt());
rightColor = RgbColor(server.arg("rred").toInt(),server.arg("rgreen").toInt(),server.arg("rblue").toInt());
firstTime = true;
}
// Fill in static part of page
htmlPage =
" <!DOCTYPE HTML>\n\
<html lang='en'>\n\
<head>\n\
<meta name='viewport' content='width=device-width, initial-scale=1.0'>\n\
<title>Color Collider</title>\n\
</head>\n\
\n\
\n\
<body onload='changeRGB()'>\n\
<h1 style='text-align: center;'>Color Collider color selector</h1>\n\
<br>\n\
<h2 id='collide'>Pick colors to collide</h2>\n\
<form>\n\
<p id='lside'> Left Side </p>\n\
<div>\n\
<label for='lred' id='lrlab'>Red Value</label><br>\n\
<input type='range' id='lred' name='lred' min='0' max='127' onchange='changeRGB()'\n\
value=";
htmlPage += leftColor.R ;
htmlPage +=
" \n\
>\n\
</div>\n\
<div>\n\
<label for='lgreen' id='lglab'>Green Value</label><br>\n\
<input type='range' id='lgreen' name='lgreen' min='0' max='127' onchange='changeRGB()'\n\
value=";
htmlPage += leftColor.G ;
htmlPage +=
" > \n\
</div>\n\
<div>\n\
<label for='lblue' id='lblab'>Blue Value</label><br>\n\
<input type='range' id='lblue' name='lblue' min='0' max='127' onchange='changeRGB()' \n\
value= ";
htmlPage += leftColor.B ;
htmlPage +=
" \n\
</div>\n\
<p id='rside'> Right Side </p>\n\
<div>\n\
<label for='rred' id='rrlab'>Red Value</label><br>\n\
<input type='range' id='rred' name='rred' min='0' max='127' onchange='changeRGB()' \n\
value=";
htmlPage += rightColor.R ;
htmlPage +=
" >\n\
</div>\n\
<div>\n\
<label for='rgreen' id='rglab'>Green Value</label><br>\n\
<input type='range' id='rgreen' name='rgreen' min='0' max='127' onchange='changeRGB()'\n\
value = ";
htmlPage += rightColor.G ;
htmlPage +=
" > \n\
</div>\n\
<div>\n\
<label for='rblue' id='rblab'>Blue Value</label><br>\n\
<input type='range' id='rblue' name='rblue' min='0' max='127' onchange='changeRGB()'\n\
value=";
htmlPage += rightColor.B ;
htmlPage +=
" >\n\
</div>\n\
<div>\n\
<input type='submit' value='Set colors'>\n\
</div>\n\
</form> \n\
<script>\n\
\n\
function changeRGB() {\n\
var lcol, lr, lg, lb, rcolor,rr,rg,rb,collidecolor,cr,cg,cb,cscale,cmax;\n\
lr = document.getElementById('lred').value;\n\
lg = document.getElementById('lgreen').value;\n\
lb = document.getElementById('lblue').value; \n\
lcolor = 'rgb('+ (Number(lr)*2) + ','+ (Number(lg)*2)+ ','+ (Number(lb)*2)+')';\n\
rr = document.getElementById('rred').value;\n\
rg = document.getElementById('rgreen').value;\n\
rb = document.getElementById('rblue').value; \n\
rcolor = 'rgb('+ (Number(rr)*2) + ','+ (Number(rg)*2)+ ','+ (Number(rb)*2)+')';\n\
document.getElementById('lrlab').innerHTML = 'Red value '+ lr;\n\
document.getElementById('lglab').innerHTML = 'Green value '+lg;\n\
document.getElementById('lblab').innerHTML = 'Blue value '+lb;\n\
document.getElementById('lside').style.backgroundColor = lcolor;\n\
// document.getElementById('lside').innerHTML = lcolor;\n\
document.getElementById('rrlab').innerHTML = 'Red value '+ rr;\n\
document.getElementById('rglab').innerHTML = 'Green value '+rg;\n\
document.getElementById('rblab').innerHTML = 'Blue value '+rb;\n\
document.getElementById('rside').style.backgroundColor = rcolor;\n\
cr = Number(rr)+Number(lr);\n\
cg = Number(rg)+Number(lg);\n\
cb = Number(rb)+Number(lb);\n\
cmax = Math.max(cr,cg,cb);\n\
if (cmax == 0) {\n\
cscale = 0;\n\
}\n\
else {\n\
cscale = 254/cmax;\n\
}\n\
collidecolor = 'rgb(' + (cr*cscale) +',' +(cg*cscale) +',' +(cb*cscale) +')';\n\
document.getElementById('collide').style.backgroundColor = collidecolor;\n\
// document.getElementById('collide').innerHTML = collidecolor;\n\
}\n\
</script>\n\
</body>\n\
</html>\n";
server.send(200, "text/html",htmlPage);
}
bool PixelEqual( RgbColor color1,RgbColor color2){
if((color1.R == color2.R) &&
(color1.G == color2.G) &&
(color1.B == color2.B)){
return true;
}
else {
return false;
}
}
void setup()
{
Serial.begin(115200);
// Set up WiFi network
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP,IPAddress(255, 255, 255, 0));
if (!WiFi.softAP(ap_ssid, ap_password)) {
Serial.println("wifi connection fail");
// while (true) {}; // hang until wdt forces a reset to retry
}
Serial.println("wifi connected");
// DNS
// modify TTL associated with the domain name (in seconds)
// default is 60 seconds
dnsServer.setTTL(300);
// set which return code will be used for all other domains (e.g. sending
// ServerFailure instead of NonExistentDomain will reduce number of queries
// sent by clients)
// default is DNSReplyCode::NonExistentDomain
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure);
// start DNS server for a specific domain name
dnsServer.start(DNS_PORT,host, apIP);
// set web page handlers
server.on("/", handleRoot);
// Start the server
httpUpdater.setup(&server);
server.begin();
// this resets all the neopixels to an off state
strip.Begin();
strip.Show();
}
void loop()
{
RgbColor merge; // combined color value
dnsServer.processNextRequest(); // check for DNS request
server.handleClient(); // check for connection request
if (firstTime){
// set the colors
strip.ClearTo(black);
for (int i =0; i<(pixelCount)/2;i+=6) {
for(int j=0;j<4;j++){
strip.SetPixelColor(i+j, leftColor );
strip.SetPixelColor(pixelCount-(i+j+1), rightColor);
}
}
strip.Show();
firstTime = false;
}
delay(50);
// shift colors toward middle
strip.RotateLeft(1,pixelCount/2,pixelCount-1);
strip.RotateRight(1,0,(pixelCount/2)-1);
// combine colors four away from middle and set them in pattern - the color may be black
merge = RgbColor::LinearBlend(strip.GetPixelColor(68), strip.GetPixelColor(75), 0.50f);
strip.SetPixelColor(68, merge);
strip.SetPixelColor(75, merge);
// if the end colors are not black correct for merged color after rotate
if(!PixelEqual(strip.GetPixelColor(0), black)){
strip.SetPixelColor(0,leftColor);
strip.SetPixelColor(pixelCount-1,rightColor);
}
strip.Show();
}