esp-pixelprojektor/pixelprojektor/pixelprojektor.ino

163 lines
3.5 KiB
C++

#include <Homie.h>
// homie lib from: https://github.com/marvinroger/homie-esp8266/
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 2 //data pin for ws2812
Adafruit_NeoPixel strip = Adafruit_NeoPixel(64, PIN, NEO_GRB + NEO_KHZ800);
HomieNode homieNode("pixel", "commands");
int xyToPos(int x, int y){ //convert x y pixel position to matrix position
if (y%2==0){
return (y*8+x);
}else{
return (y*8+(7-x));
}
}
int numToPos(int num){ //convert pixel number to actual 8x8 matrix position
int x=num%8;
int y=num/8;
return xyToPos(x,y);
}
uint32_t wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void led_fill(uint32_t c)
{
for (int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
}
void led_random()
{
for (int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, wheel(random(0,255)));
}
strip.show();
}
uint32_t parseColor(String value){
if (value.charAt(0)=='#'){ //solid fill
String color=value.substring(1);
int number = (int) strtol( &color[0], NULL, 16);
// Split them up into r, g, b values
int r = number >> 16;
int g = number >> 8 & 0xFF;
int b = number & 0xFF;
Homie.getLogger() << "r=" << r << " g=" << g << " b=" << b << endl;
//Serial.print("r=");Serial.print(r);
//Serial.print(" g=");Serial.print(g);
//Serial.print(" b=");Serial.println(b);
return strip.Color(r, g, b);
}
return 0;
}
bool effectHandler(const HomieRange& range, const String& value) {
Homie.getLogger() << "-> " << value << endl;
int sep = value.indexOf("|");
String command=value.substring(0,sep);
String parameters=value.substring(sep+1);
Homie.getLogger() << "command=" << command << " parameters=" << parameters << endl;
if (command.equals("fill")){
led_fill(parseColor(parameters));
}else if (command.equals("off")){
led_fill(strip.Color(0, 0, 0));
}else if (command.equals("random")){
led_random();
}else if (command.equals("set")){
int x=parameters.substring(0,1).toInt();
int y=parameters.substring(1,2).toInt();
String cstr=parameters.substring(2,9);
strip.setPixelColor(xyToPos(x,y), parseColor(cstr));
strip.show();
}
return true;
}
bool pixelsHandler(const HomieRange& range, const String& value) {
String remaining=value;
int i=0;
do{
String current=remaining.substring(0,7);
Homie.getLogger() << i << ":" << current << endl;
uint32_t currentcolor=parseColor(current);
strip.setPixelColor(i, currentcolor);
i++;
remaining=remaining.substring(7);
}while(remaining.length()>2 && (i<strip.numPixels()));
Homie.getLogger() << " filling rest with black" << endl;
while(i<strip.numPixels()){
strip.setPixelColor(numToPos(i), strip.Color(0,0,0));
i++;
}
strip.show();
return true;
}
void setup() {
Serial.begin(115200);
Serial << endl << endl;
Homie_setFirmware("pixelprojektor", "1.0.0");
homieNode.advertise("effect").settable(effectHandler);
homieNode.advertise("pixels").settable(pixelsHandler);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
led_fill(strip.Color(0, 0, 0));
Homie.setup();
}
void loop() {
Homie.loop();
long currentMillis = millis();
}