I have one of the early Particle Neopixel rings with 24 pixels and the photon plugs into it.
I am using the 24 LEDs to display the battery SOC of another device. This is working well.
Right now I choose one LED to light up depending on the incoming SOC and the number of pixels (24)
socled = (PIXEL_COUNT * soc_int / 100);
I choose the color of the pixel in an if statement:
if(soc_int >= 0 && soc_int <= 30 ){ //if SOC is between 0% and 30% led is red
ring.clear();
ring.setPixelColor(socled, RED);
}
else if(soc_int > 30 && soc_int <= 70 ){ //if SOC is between 30% and 70% led is amber
ring.clear();
ring.setPixelColor(socled, AMBER);
}
else if(soc_int > 70 && soc_int <= 100 ){ //if SOC is between 70% and 100% led is green
ring.clear();
ring.setPixelColor(socled, GREEN);
}
else{
ring.clear(); //if SOC is not a value between 0 and 100, LED is off
}
What I would like is to show a gradient, for example if the SOC falls between two LED’s values, so if the result doesn’t exactly land on an LED position, Two leds would be partially lit, their relative values represent the weighting. ie… if the SOC chosen is 10.25, the led 10 would be fully lit, and led 11 would be 1/4 lit.
Can anyone give some clues how to accomplish that?
My full code below:
STARTUP(WiFi.selectAntenna(ANT_EXTERNAL)); //select u.FL antenna
#include <neopixel.h> // define neopixel ring
#define PIXEL_COUNT 24
#define PIXEL_PIN D6
#define PIXEL_TYPE WS2812B
Adafruit_NeoPixel ring(PIXEL_COUNT,PIXEL_PIN,PIXEL_TYPE);
#define RED ring.Color(255,0,0) //setup the main colors for the fuel gauge
#define GREEN ring.Color(0,255,0)
#define AMBER ring.Color(255,140,0)
double socled; //initialize variable for the position of the lit led
void setup() {
ring.begin(); //initialize led ring
ring.show(); //turn pixels off
ring.setBrightness(80); //set the ring brightness
Particle.subscribe("ps-soc", myHandler, MY_DEVICES); //subscribe to the state of charge published by our friend device
Particle.variable("soc-led", socled); //publish a variable to indicate which led position was chosen
}
void myHandler(const char *event, const char *data) //this handles the string from the particle.subscribe function
{
String SOC = String(data); //create a new string that will hold the SOC data
int soc_int = SOC.toInt(); //create an int and convert the string into an int
socled = (PIXEL_COUNT * soc_int / 100); //turn the SOC data from a percentage to an LED position based on how many leds in the ring
if(soc_int >= 0 && soc_int <= 30 ){ //if SOC is between 0% and 30% led is red
ring.clear();
ring.setPixelColor(socled, RED);
}
else if(soc_int > 30 && soc_int <= 70 ){ //if SOC is between 30% and 70% led is amber
ring.clear();
ring.setPixelColor(socled, AMBER);
}
else if(soc_int > 70 && soc_int <= 100 ){ //if SOC is between 70% and 100% led is green
ring.clear();
ring.setPixelColor(socled, GREEN);
}
else{
ring.clear(); //if SOC is not a value between 0 and 100, LED is off
}
}
void loop() {
ring.show();
delay(1000);
}