#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <Arduino_FreeRTOS.h>
#include <queue.h>
int CLK = 4;
int DT = 3;
int SW = 2;
int RED_PIN = 5;
int GREEN_PIN = 6;
int BLUE_PIN = 9;
static int oldCLK = LOW;
static int oldDT = LOW;
LiquidCrystal_I2C lcd(0x27, 20, 4);
int RED, GREEN, BLUE;
int mr, mg, mb;
char buf[20];
int mode = 0; // 0=normal, 1=setup
int menu = 0; // 0=RED, 1=GREEN, 2=BLUE, 3=END
QueueHandle_t queue;
void ledlightTask(void *pvParameters);
void lcdshowTask(void *pvParameters);
void rotdialTask(void *pvParameters);
void setup() {
initsetting();
loadsetting();
lcd.init();
lcd.backlight();
pinMode(CLK, INPUT_PULLUP);
pinMode(DT, INPUT_PULLUP);
pinMode(SW, INPUT_PULLUP);
queue = xQueueCreate(10, sizeof(int[3]));
xTaskCreate(ledlightTask, "LedlightTask", 100, NULL, 1, NULL);
xTaskCreate(lcdshowTask, "LcdshowTask", 100, NULL, 1, NULL);
xTaskCreate(rotdialTask, "RotdialTask", 100, NULL, 1, NULL);
}
void loop() {
}
void lcdshow() {
if (mode == 0) {
lcd.setCursor(0, 0);
sprintf(buf, "==RGB LED LIGHTING==");
lcd.print(buf);
lcd.setCursor(0, 1);
sprintf(buf, " R:%3d G:%3d B:%3d ", RED, GREEN, BLUE);
lcd.print(buf);
}
if (mode == 1) {
switch (menu) {
case 0:
lcd.setCursor(0, 0);
sprintf(buf, "<<<CHANGE SETTING>>>");
lcd.print(buf);
lcd.setCursor(0, 2);
sprintf(buf, " %3d", mr);
lcd.print(buf);
lcd.setCursor(0, 3);
sprintf(buf, " RED INTENSITY");
lcd.print(buf);
break;
case 1:
lcd.setCursor(0, 0);
sprintf(buf, "<<<CHANGE SETTING>>>");
lcd.print(buf);
lcd.setCursor(0, 2);
sprintf(buf, " %3d", mg);
lcd.print(buf);
lcd.setCursor(0, 3);
sprintf(buf, " GREEN INTENSITY");
lcd.print(buf);
break;
case 2:
lcd.setCursor(0, 0);
sprintf(buf, "<<<CHANGE SETTING>>>");
lcd.print(buf);
lcd.setCursor(0, 2);
sprintf(buf, " %3d", mb);
lcd.print(buf);
lcd.setCursor(0, 3);
sprintf(buf, " BLUE INTENSITY");
lcd.print(buf);
break;
case 3:
lcd.setCursor(0, 2);
sprintf(buf, "STORING SETTING .");
lcd.print(buf);
delay(500);
lcd.setCursor(0, 2);
sprintf(buf, "STORING SETTING ..");
lcd.print(buf);
delay(500);
lcd.setCursor(0, 2);
sprintf(buf, "STORING SETTING ...");
lcd.print(buf);
delay(500);
savesetting();
mode = 0;
menu = 0;
break;
}
}
}
void ledlightTask(void *pvParameters) {
int rgb[3];
while (true) {
if (xQueueReceive(queue, &rgb, portMAX_DELAY) == pdTRUE) {
analogWrite(RED_PIN, 255 - rgb[0]);
analogWrite(GREEN_PIN, 255 - rgb[1]);
analogWrite(BLUE_PIN, 255 - rgb[2]);
}
}
}
void lcdshowTask(void *pvParameters) {
while (true) {
lcdshow();
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void rotdialTask(void *pvParameters) {
int currb = HIGH, lastb = HIGH;
while (true) {
currb = digitalRead(SW);
if (currb == LOW && lastb == HIGH) {
lcd.clear();
if (mode == 0) {
mode = 1;
menu = 0;
mr = RED;
mg = GREEN;
mb = BLUE;
} else if (mode == 1 && menu < 3) {
menu++;
} else if (mode == 1 && menu == 3){
menu = 0;
mode = 0;
}
delay(100);
}
lastb = currb;
int direct = 0;
int newCLK = digitalRead(CLK);
int newDT = digitalRead(DT);
if (newCLK != oldCLK) {
if (oldCLK == LOW) {
direct = -1 * (oldDT * 2 - 1);
}
}
oldCLK = newCLK;
oldDT = newDT;
if (mode == 1) {
switch (menu) {
case 0: mr += 5 * direct; if (mr > 255) mr = 0; if (mr < 0) mr = 255; break;
case 1: mg += 5 * direct; if (mg > 255) mg = 0; if (mg < 0) mg = 255; break;
case 2: mb += 5 * direct; if (mb > 255) mb = 0; if (mb < 0) mb = 255; break;
}
int rgb[3] = {mr, mg, mb};
xQueueSend(queue, &rgb, portMAX_DELAY);
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void loadsetting() {
RED = EEPROM.read(1);
GREEN = EEPROM.read(2);
BLUE = EEPROM.read(3);
}
void initsetting() {
EEPROM.update(1, 255);
EEPROM.update(2, 255);
EEPROM.update(3, 255);
}
void savesetting() {
RED = mr; EEPROM.update(1, RED);
GREEN = mg; EEPROM.update(2, GREEN);
BLUE = mb; EEPROM.update(3, BLUE);
}