/*
Forum: https://forum.arduino.cc/t/irremote-unvollstandige-auswertung-in-while-schleife/1346983
Wokwi: https://wokwi.com/projects/421312361290532865
ec2021
*/
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library
#include <Arduino.h>
#include <IRremote.hpp>
#include <Adafruit_NeoPixel.h>
const int IR_RECEIVE_PIN = 7;
unsigned long key_value_old = 0;
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 8 // On Trinket or Gemma, suggest changing this to 1
#define NUMPIXELS 24 // Popular NeoPixel ring size 256
int BRIGHTNESS = 192; // Set BRIGHTNESS to about 1/5 (max = 255)
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 50 // Time (in milliseconds) to pause between pixels
/*
const unsigned long buttonAn {0xF807FF00};
const unsigned long buttonAus {0xF906FF00};
const unsigned long buttonRot {0xF609FF00};
const unsigned long buttonGruen {0xF708FF00};
const unsigned long buttonHellblau {0xF10EFF00};
const unsigned long buttonGrau {0xF40BFF00};
const unsigned long buttonDunkelblau {0xF50AFF00};
const unsigned long buttonOrange {0xF20DFF00};
const unsigned long buttonHellgruen {0xF30CFF00};
const unsigned long buttonGelb {0xEE11FF00};
const unsigned long buttonHeller {0xFA05FF00};
const unsigned long buttonDunkler {0xFB04FF00};
const unsigned long buttonPink {0xED12FF00};
const unsigned long buttonFade {0xE41BFF00};
const unsigned long buttonStrobe {0xE817FF00};
const unsigned long buttonSmooth {0xEC13FF00};
const signed long buttonIrgendwas {-1935048056};
*/
// Wokwi IR Codes
const unsigned long buttonAn {0x5DA2FF00}; // POWER
const unsigned long buttonAus {0x1DE2FF00}; // MENU
const unsigned long buttonRot {0xDD22FF00}; // TEST
const unsigned long buttonGruen {0x9768FF00}; // 0
const unsigned long buttonHellblau {0x3DC2FF00}; // Backspace
const unsigned long buttonGrau {0x1FE0FF00}; // Fastrewind
const unsigned long buttonDunkelblau {0x57A8FF00}; // Play
const unsigned long buttonOrange {0x6F90FF00}; // Fastforward
const unsigned long buttonHellgruen {0x4FB0FF00}; // C
const unsigned long buttonGelb {0xCF30FF00}; // 1
const unsigned long buttonHeller {0xFD02FF00}; // +
const unsigned long buttonDunkler {0x6798FF00}; // -
const unsigned long buttonPink {0xE718FF00}; // 2
const unsigned long buttonFade {0x857AFF00}; // 3
const unsigned long buttonStrobe {0xEF10FF00}; // 4
const unsigned long buttonSmooth {0xC738FF00}; // 5
const unsigned long buttonIrgendwas {0xA55AFF00}; // 6
enum States {sIDLE, sAUS, sROT, sGRUEN, sHELLBLAU,
sGRAU, sDUNKELBLAU, sORANGE,
sHELLGRUEN, sGELB, sHELLER, sDUNKLER,
sPINK, sFADE, sSTROBE, sSMOOTH,
sIRGENDWAS
};
States state = sIDLE;
States prevState = sIDLE;
boolean newCmd = false;
unsigned long keyValue;
boolean isReady = false;
const int cHell = 7; // Für ursprüngliche Werte auf 1 setzen
void pixelsShow() {
if (IrReceiver.isIdle()) {
pixels.show();
}
}
void setup() {
Serial.begin(115200);
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
pixels.begin(); // INITIALIZE NeoPixel pixels object (REQUIRED)
pixelsShow(); // Turn OFF all pixels ASAP
pixels.setBrightness(BRIGHTNESS);
}
void loop() {
checkForIRCodes();
stateMachine();
}
void checkForIRCodes() {
if (IrReceiver.decode()) {
IrReceiver.resume(); // Enable receiving of the next value
if (IrReceiver.decodedIRData.numberOfBits > 31) {
keyValue = IrReceiver.decodedIRData.decodedRawData;
// Serial.print(" 0x");
// Serial.println(keyValue, HEX);
ledCode(keyValue);
}
}
}
void storeKey(long key) {
key_value_old = key;
}
void ledCode(long key_value) {
if (key_value == buttonAn) { // Button An
key_value = key_value_old;
Serial.println(F("An"));
}
switch (key_value) {
case buttonAus: // Button Aus
Serial.println(F("Aus"));
state = sAUS;
break;
case buttonRot: //Farbe Rot
Serial.println(F("Rot"));
storeKey(key_value);
state = sROT;
break;
case buttonGruen: //Farbe Grün
Serial.println(F("Grün"));
storeKey(key_value);
state = sGRUEN;
break;
case buttonHellblau: // Farbe Blau Hell
Serial.println(F("Hellblau"));
storeKey(key_value);
state = sHELLBLAU;
break;
case buttonGrau:
Serial.println(F("Grau"));
storeKey(key_value);
state = sGRAU;
break;
case buttonDunkelblau: // Farbe Blau Dunkel
Serial.println(F("Dunkelblau"));
storeKey(key_value);
state = sDUNKELBLAU;
break;
case buttonOrange: // Farbe Orange
Serial.println(F("Orange"));
storeKey(key_value);
state = sORANGE;
break;
case buttonHellgruen: // Farbe Hellgrün
Serial.println(F("Hellgrün"));
storeKey(key_value);
state = sHELLGRUEN;
break;
case buttonGelb: // Farbe Gelb
Serial.println(F("Gelb"));
storeKey(key_value);
state = sGELB;
break;
case buttonHeller: // Helligkeit hoch
Serial.println(F("Heller"));
state = sHELLER;
break;
case buttonDunkler: // Helligkeit runter
Serial.println(F("Dunkler"));
state = sDUNKLER;
break;
case buttonPink: //Farbe Pink
Serial.println(F("Pink"));
storeKey(key_value);
state = sPINK;
break;
case buttonFade: // Button Fade
Serial.println(F("Fade"));
storeKey(key_value);
state = sFADE;
fadingDone(false); // Startwerte setzen
break;
case buttonStrobe: // Button Strobe
Serial.println(F("Strobe"));
storeKey(key_value);
state = sSTROBE;
theaterChaseRainbow(-1); // Startwerte setzen durch Parameter < 0
break;
case buttonSmooth: // Button Smooth
Serial.println(F("Smooth"));
storeKey(key_value);
state = sSMOOTH;
rainbowDone(-1); // Startwerte setzen durch Parameter < 0
break;
case buttonIrgendwas:
Serial.println(F("Irgendwas"));
state = sIRGENDWAS;
break;
default:
Serial.println(F("Unbekannt oder fehlerhaft"));
state = sIDLE;
pixels.clear();
pixelsShow();
break;
}
}
void stateMachine() {
if (state != sFADE && prevState == sFADE) {
pixels.setBrightness(BRIGHTNESS);
pixelsShow();
}
prevState = state;
switch (state) {
case sIDLE:
break;
case sAUS: // Button Aus
pixels.clear();
pixelsShow();
state = sIDLE;
break;
case sROT: //Farbe Rot
colorSwitch(pixels.Color(255, 0, 0));
state = sIDLE;
break;
case sHELLGRUEN: //Farbe Grün
colorSwitch(pixels.Color(0, 255, 0));
state = sIDLE;
break;
case sHELLBLAU: // Farbe Blau Hell
colorSwitch(pixels.Color(0, 0, 255));
state = sIDLE;
break;
case sGRAU:
colorSwitch(pixels.Color(128, 128, 128));
state = sIDLE;
break;
case sDUNKELBLAU: // Farbe Blau Dunkel
colorSwitch(pixels.Color(20, 0, 255));
state = sIDLE;
break;
case sORANGE: // Farbe Orange
colorSwitch(pixels.Color(255, 147, 5));
state = sIDLE;
break;
case sGRUEN: // Farbe Grün
colorSwitch(pixels.Color(118, 235, 2));
state = sIDLE;
break;
case sGELB: // Farbe Gelb
colorSwitch(pixels.Color(252, 244, 3));
state = sIDLE;
break;
case sHELLER: // Helligkeit hoch
if (BRIGHTNESS < 255) {
BRIGHTNESS++;
pixels.setBrightness(BRIGHTNESS);
pixelsShow();
}
state = sIDLE;
break;
case sDUNKLER: // Helligkeit runter
if (BRIGHTNESS > 0) {
BRIGHTNESS--;
pixels.setBrightness(BRIGHTNESS);
pixelsShow();
}
state = sIDLE;
break;
case sPINK: //Farbe Pink
colorSwitch(pixels.Color(202, 21, 230));
state = sIDLE;
break;
case sFADE: // Button Fade
if (fadingDone(true)) {
state = sIDLE;
}
break;
case sSTROBE: // Button Strobe
theaterChaseRainbow(50); // Bis ihn ein anderer IR Code beendet ...
break;
case sSMOOTH: // Button Smooth
if (rainbowDone(10)) {
state = sIDLE;
};
break;
case sIRGENDWAS:
pixels.clear(); // Set all pixel colors to 'off'
colorSwitch(pixels.Color(0, 150, 0));
state = sIDLE;
break;
}
}
void colorSwitch(uint32_t color) {
for (int i = 0; i < pixels.numPixels(); i++) { // For each pixel in pixels...
pixels.setPixelColor(i, color); // Set pixel's color (in RAM)
}
pixelsShow();
}
boolean fadingDone(boolean run) {
static int h = 1;
static unsigned long lastAction = 0;
static byte mode = 0;
if (!run) {
h = 1;
lastAction = millis();
mode = 0;
return true;
}
switch (mode) {
case 0:
if (millis() - lastAction > 10) {
lastAction = millis();
pixels.setBrightness(h * cHell);
pixelsShow();
h++;
}
if (h >= 32) {
mode = 1;
};
break;
case 1:
if (millis() - lastAction > 50) {
lastAction = millis();
pixels.setBrightness(h * cHell);
pixelsShow();
h--;
}
if (h <= 1) {
mode = 2;
};
break;
case 2:
pixels.setBrightness(BRIGHTNESS);
pixelsShow();
return true;
break;
}
return false;
}
void theaterChaseRainbow(unsigned long wait) { // call mit 50 ms
static unsigned long lastAction = 0;
static int firstPixelHue = 0; // First pixel starts at red (hue 0)
static int b = 0;
if (wait < 0) { // wait kleiner 0 setzt die Startwerte und kehrt direkt zurück
lastAction = 0;
firstPixelHue = 0;
b = 0;
return;
}
if (millis() - lastAction > wait) {
lastAction = millis();
pixels.clear();
for (int c = b; c < pixels.numPixels(); c += 3) {
int hue = firstPixelHue + c * 65536L / pixels.numPixels();
uint32_t color = pixels.gamma32(pixels.ColorHSV(hue)); // hue -> RGB
pixels.setPixelColor(c, color); // Set pixel 'c' to value 'color'
}
pixelsShow(); // Update pixels with new contents
firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
b++;
}
if (b > 2) {
b = 0;
}
}
boolean rainbowDone(unsigned long wait) {
static long firstPixelHue = 0;
static unsigned long lastAction = 0;
if (wait < 0) {
firstPixelHue = 0;
lastAction = 0;
return;
}
if (millis() - lastAction > wait) {
lastAction = millis();
pixels.rainbow(firstPixelHue);
pixelsShow(); // Update pixels with new contents
if (firstPixelHue < 5 * 65536) {
firstPixelHue += 256;
} else {
firstPixelHue = 0;
return true;
}
}
return false;
}