//1+2+3+4+5+6+7+8+9+10
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Encoder.h>
#include <avr/eeprom.h>
const int ledPin = 12, ledCount = 8;
const int hcSrTrigPin = 7, hcSrEchoPin = 6;
const int encPin1 = 3, encPin2 = 4;
const int joyVertPin = A0, joyHorzPin = A1, joyBtnPin = 11;
const int potentiometerPin = A2, btnPin = 2;
uint32_t colors[] = { Adafruit_NeoPixel::Color(255, 0, 0), //red
Adafruit_NeoPixel::Color(255, 0, 255), //magenta
Adafruit_NeoPixel::Color(255, 0, 128), //biskupi
Adafruit_NeoPixel::Color(255, 128, 0), //orange
Adafruit_NeoPixel::Color(255, 255, 0), //yellow
Adafruit_NeoPixel::Color(0, 255, 0), //green
Adafruit_NeoPixel::Color(0, 255, 255), //cyan
Adafruit_NeoPixel::Color(0, 0, 255)}; //blue
int menu = 1;
int prevEncVal = 0;
int currLed = 0, currSatId = 0;
int currDiscoColorId = 0;
int btnClicked = 0;
unsigned long timeEnc, timeJoyHorz, timeJoyVert, timeDisco;
//state
int saturations[ledCount][3], saturationsTemp[ledCount][3];
int brightness;
LiquidCrystal_I2C lcd(0x27, 16, 2);
Adafruit_NeoPixel leds = Adafruit_NeoPixel(ledCount, ledPin, NEO_GRB + NEO_KHZ800);
Encoder enc(encPin1, encPin2);
void setup() {
Serial.begin(9600);
pinMode(hcSrTrigPin, OUTPUT);
pinMode(hcSrEchoPin, INPUT);
pinMode(joyBtnPin, INPUT_PULLUP);
pinMode(btnPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(btnPin), handleBtn, CHANGE);
lcd.begin(16, 2);
lcd.clear();
leds.begin();
readEeprom();
}
void showLcd(){
char buff[16];
lcd.setCursor(0,0);
if(menu == 1){
lcd.print("Ster joystick ");
lcd.setCursor(0,1);
char c = currSatId == 0 ? 'R' : currSatId == 1 ? 'G' : 'B';
sprintf(buff, "L:%02d C:%c V:%03d", currLed, c, saturationsTemp[currLed][currSatId]);
lcd.print(buff);
}
else if(menu == 2){
lcd.print("Ster czuj odleg ");
lcd.setCursor(0,1);
sprintf(buff, "Jasnosc: %3d", brightness);
lcd.print(buff);
}
else if(menu == 3){
lcd.print("Ster potencjomet");
lcd.setCursor(0,1);
sprintf(buff, "Jasnosc: %3d", brightness);
lcd.print(buff);
}
else if(menu == 4){
lcd.print("Dyskoteka ");
}
}
void showSerial(){
char buff[100];
sprintf(buff, "Led: %2d, Jasnosc: %3d, Nasycenie: [", currLed, brightness);
Serial.print(buff);
for(int i = 0; i < ledCount; i++){
sprintf(buff, "(%d %d %d) ", saturations[i][0], saturations[i][1], saturations[i][2]);
Serial.print(buff);
}
Serial.println("]");
}
void handleEnc(){
if(millis() - timeEnc > 50){
int encVal = enc.read();
timeEnc = millis();
if(encVal < prevEncVal){
menu--;
prevEncVal = encVal;
lcd.clear();
}
else if(encVal > prevEncVal){
menu++;
prevEncVal = encVal;
lcd.clear();
}
menu = constrain(menu, 1, 4);
}
}
void handleJoystick(){
if(menu == 1){
int vert = map(analogRead(joyVertPin), 0, 1023, 0, 100);
int horz = map(analogRead(joyHorzPin), 0, 1023, 0, 100);
int isBtnClikded = digitalRead(joyBtnPin) == LOW;
if(millis() - timeJoyVert > 200){
timeJoyVert = millis();
//down
if(abs(vert - 0) < 2 && abs(horz - 50) < 2){
currLed++;
currLed = constrain(currLed, 0, ledCount-1);
}
//up
else if(abs(vert - 100) < 2 && abs(horz - 50) < 2){
currLed--;
currLed = constrain(currLed, 0, ledCount-1);
}
}
if(millis() - timeJoyHorz > 10){
timeJoyHorz = millis();
//right
if(abs(vert - 50) < 2 && abs(horz - 0) < 2){
saturationsTemp[currLed][currSatId] += 2;;
saturationsTemp[currLed][currSatId] = constrain(saturationsTemp[currLed][currSatId], 0, 255);
}
//left
else if(abs(vert - 50) < 2 && abs(horz - 100) < 2){
saturationsTemp[currLed][currSatId] -= 2;
saturationsTemp[currLed][currSatId] = constrain(saturationsTemp[currLed][currSatId], 0, 255);
}
}
if(digitalRead(joyBtnPin) == LOW){
while(digitalRead(joyBtnPin) == LOW);
saturations[currLed][currSatId] = saturationsTemp[currLed][currSatId];
currSatId++;
currSatId = currSatId > 2 ? 0 : currSatId;
}
}
}
void handleHcSr(){
if(menu == 2){
digitalWrite(hcSrTrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(hcSrTrigPin, LOW);
long impulseTime = pulseIn(hcSrEchoPin, HIGH);
int distance = impulseTime/58.0;
distance = constrain(distance, 0, 350);
brightness = map(distance, 0, 350, 255, 0);
}
}
void handlePotentiometer(){
if(menu == 3){
brightness = map(analogRead(potentiometerPin), 0, 1023, 0, 255);
}
}
void handleLedStrip(){
if(menu != 4 && btnClicked != 1){
leds.setBrightness(brightness);
for(int i = 0; i < leds.numPixels(); i++){
uint32_t color = Adafruit_NeoPixel::Color(saturations[i][0], saturations[i][1], saturations[i][2]);
if(menu == 1 && currLed == i){
color = Adafruit_NeoPixel::Color(saturationsTemp[i][0], saturationsTemp[i][1], saturationsTemp[i][2]);
}
leds.setPixelColor(i, color);
leds.show();
}
}
}
void handleBtn(){
btnClicked = 1;
timeDisco = millis();
writeEeprom();
}
void handleDiscoMode(){
if(menu == 4 || btnClicked == 1){
disco();
}
}
void disco(){
if(millis() - timeDisco > 125){
Serial.println(currDiscoColorId);
timeDisco = millis();
leds.setBrightness(255);
leds.fill(colors[currDiscoColorId], 0, ledCount);
leds.show();
currDiscoColorId++;
currDiscoColorId = currDiscoColorId > 7 ? 0 : currDiscoColorId;
if(btnClicked == 1 && currDiscoColorId == 0){
btnClicked = 0;
}
}
}
void writeEeprom(){
eeprom_write_block(&brightness, 200, 2); //2bytes on address 200
for(int i = 0; i < ledCount; i++) //for each row in array
eeprom_write_block(saturations[i], i*3*2, 3*2); //write 6bytes (one row in array)
}
void readEeprom(){
eeprom_read_block(&brightness, 200, 2); //2bytes from address 200
for(int i = 0; i < ledCount; i++) //for each row in array
eeprom_read_block(&saturations[i], i*3*2, 3*2); //read 6 bytes (one row in array)
brightness = constrain(brightness, 0, 255);
for(int i = 0; i < ledCount; i++)
for(int j = 0; j < 3; j++)
saturations[i][j] = constrain(saturations[i][j], 0, 255);
}
void loop() {
handleEnc();
handleJoystick();
handleHcSr();
handlePotentiometer();
handleDiscoMode();
handleLedStrip();
showLcd();
showSerial();
}