// GNP_TreeLamp
// 10 NeoPixel Ring 16/each
#include <Adafruit_NeoPixel.h>
#define LED_PIN 12
#define LED_TOTAL_COUNT 160
Adafruit_NeoPixel strip(LED_TOTAL_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); // 宣告 NeoPixel 物件,包含十組 LED
unsigned long previousMillis = 0;
unsigned long breatheInterval = 5;
int prizeG1 = 10;
int prizeG2 = 30; // 欲設定的數值需手動加上prizeG1取合 ex:20則為20+prizeG1
int totalPrize = 100;
int allUpSpeed = 20; // g1 y2 r3 prize all lamp lighting all the way up
int brightnessLimit = 255; // max is 255 , half is 125
int bS = 1; // breatheSpeed, led vaule step (0~255 step)
int r3bS = 1; //r3breatheSpeed, led vaule step (0~255 step)
int lampActiveSpeed = 10; //when cup put at lamp,ring light delay time
int allOffUpDelay = 3000 ; //整棵樹由下到上熄燈後等待多久回到呼吸燈
int brightness[11] = {0, 25, 100, 200, 75, 250, 125, 50, 225, 150, 0};
int r3brightness[11] = {-1000, -900, -800, -700, -600, -500, -400, -300, -200, -100, 0};
int increment[11] = {bS, bS, bS, bS, bS, bS, bS, bS, bS, bS, bS};
int r3increment[11] = {r3bS, r3bS, r3bS, r3bS, r3bS, r3bS, r3bS, r3bS, r3bS, r3bS, r3bS};
int LED_SetStart[11] {0, 0, 16, 32, 48, 64, 80, 96, 112, 128, 144}; // 10 NeoPixel Ring 16/each
int LED_SetEnd[11] {0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160}; // 第0位址捨棄不用比較直觀
int swPin[10] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; //陣列位址從0算起
// 25 50 75 100 125 150 175 200 225 250
String TreeLampMode = "standyby";
byte sw1 = swPin[9]; byte sw2 = swPin[0]; byte sw3 = swPin[1]; byte sw4 = swPin[2];
byte sw5 = swPin[3]; byte sw6 = swPin[4]; byte sw7 = swPin[5]; byte sw8 = swPin[6];
byte sw9 = swPin[7]; byte sw10 = swPin[8];
bool sw1state = false; bool sw2state = false; bool sw3state = false; bool sw4state = false;
bool sw5state = false; bool sw6state = false; bool sw7state = false; bool sw8state = false;
bool sw9state = false; bool sw10state = false;
int g1Count = 0; // 記錄g1的出現次數
int y2Count = 0; // 記錄y2的出現次數
int r3Count = 0; // 記錄r3的出現次數
void setup() {
strip.begin();
Serial.begin(9600);
// 初始化 NeoPixel
for (int i = 0; i < 10; i++) {
pinMode(swPin[i], INPUT_PULLUP);
}
}
void loop() {
unsigned long currentMillis = millis();
checkSwitch();
checkSwitchState();
if (TreeLampMode == "standyby") {
if (currentMillis - previousMillis >= breatheInterval) {
previousMillis = currentMillis;
breatheLED(); // 呼叫呼吸燈函式
}
}
}
void checkSwitch() {
// check sw1
if (digitalRead(sw1) == LOW && sw1state == false ) {
TreeLampMode = "sw1";
sw1state = true;
int lampNum = 1; // this lampNum is sw1 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw2
if (digitalRead(sw2) == LOW && sw2state == false ) {
TreeLampMode = "sw2";
sw2state = true;
int lampNum = 2; // this lampNum is sw1 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw3
if (digitalRead(sw3) == LOW && sw3state == false) {
TreeLampMode = "sw3";
sw3state = true;
int lampNum = 3; // this lampNum is sw1 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw4
if (digitalRead(sw4) == LOW && sw4state == false ) {
TreeLampMode = "sw4";
sw4state = true;
int lampNum = 4; // this lampNum is sw1 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw5
if (digitalRead(sw5) == LOW && sw5state == false) {
TreeLampMode = "sw5";
sw5state = true;
int lampNum = 5; // this lampNum is sw1 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw6
if (digitalRead(sw6) == LOW && sw6state == false ) {
TreeLampMode = "sw6";
sw6state = true;
int lampNum = 6; // this lampNum is sw1 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw7
if (digitalRead(sw7) == LOW && sw7state == false) {
TreeLampMode = "sw7";
sw7state = true;
int lampNum = 7; // this lampNum is sw7 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw8
if (digitalRead(sw8) == LOW && sw8state == false ) {
TreeLampMode = "sw8";
sw8state = true;
int lampNum = 8; // this lampNum is sw8 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw9
if (digitalRead(sw9) == LOW && sw9state == false) {
TreeLampMode = "sw9";
sw9state = true;
int lampNum = 9; // this lampNum is sw9 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
// check sw10
if (digitalRead(sw10) == LOW && sw10state == false) {
TreeLampMode = "sw10";
sw10state = true;
int lampNum = 10; // this lampNum is sw1 been press(put cup)
allLampOff();
// 開始亂數抽獎
int randomNum = random(1, totalPrize);
// Serial.println(randomNum);
if (randomNum <= prizeG1) { // 如果隨機數字小於等於prizeG1,則顯示頭獎
g1Count ++ ;
g1prizeshow(lampNum);
} else if (randomNum <= prizeG2) { // 如果隨機數字小於等於prizeG2,則顯示二獎
y2Count ++ ;
y2prizeshow(lampNum);
} else { // 其他情況顯示三獎
r3Count ++ ;
r3prizeshow(lampNum);
}
}
}
void checkSwitchState() {
if (digitalRead(sw1) == HIGH && sw1state == true ) {
sw1state = false;
delay(100);
}
if (digitalRead(sw2) == HIGH && sw2state == true ) {
sw2state = false;
delay(100);
}
if (digitalRead(sw3) == HIGH && sw3state == true ) {
sw3state = false;
delay(100);
}
if (digitalRead(sw4) == HIGH && sw4state == true ) {
sw4state = false;
delay(100);
}
if (digitalRead(sw5) == HIGH && sw5state == true ) {
sw5state = false;
delay(100);
}
if (digitalRead(sw6) == HIGH && sw6state == true ) {
sw6state = false;
delay(100);
}
if (digitalRead(sw7) == HIGH && sw7state == true ) {
sw7state = false;
delay(100);
}
if (digitalRead(sw8) == HIGH && sw8state == true ) {
sw8state = false;
delay(100);
}
if (digitalRead(sw9) == HIGH && sw9state == true ) {
sw9state = false;
delay(100);
}
if (digitalRead(sw10) == HIGH && sw10state == true ) {
sw10state = false;
delay(100);
}
}
void g1prizeshow(int lampSet) {
// lamp1 繞綠圈表示頭獎
for (int i = LED_SetStart[lampSet]; i < LED_SetEnd[lampSet]; i++) {
strip.setPixelColor(i, strip.Color(0, brightnessLimit, 0));
strip.show();
delay(lampActiveSpeed);
}
allGreenUp(lampSet);
}
void y2prizeshow(int lampSet) {
// lamp1 繞黃圈表示二獎
for (int i = LED_SetStart[lampSet]; i < LED_SetEnd[lampSet]; i++) {
strip.setPixelColor(i, strip.Color(brightnessLimit, brightnessLimit, 0));
strip.show();
delay(lampActiveSpeed);
}
allYellowUp(lampSet);
}
void r3prizeshow(int lampSet) {
// lamp1 繞紅圈表示三獎
for (int i = LED_SetStart[lampSet]; i < LED_SetEnd[lampSet]; i++) {
strip.setPixelColor(i, strip.Color(brightnessLimit, 0, 0));
strip.show();
delay(lampActiveSpeed);
}
allRedUp(lampSet);
}
void allGreenUp(int exclude) {
// 一組一組往上亮,漸層感差,時間也拖太久
for (int w = 10; w > 0; w--) {
if (w == exclude) {
continue; // 跳過指定的exclude,繼續下一個迴圈
}
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[w]; i < LED_SetEnd[w]; i++) {
strip.setPixelColor(i, strip.Color(0, b, 0));
}
strip.show();
}
}
allGreenOffUp(exclude);
}
void allGreenOffUp(int exclude) {
// 一組一組往上亮,漸層感差,時間也拖太久
for (int w = 10; w > 0; w--) {
if (w == exclude) {
continue; // 跳過指定的exclude,繼續下一個迴圈
}
for (int b = brightnessLimit; b > 0; b = b - allUpSpeed) {
for (int i = LED_SetStart[w]; i < LED_SetEnd[w]; i++) {
strip.setPixelColor(i, strip.Color(0, b, 0));
}
strip.show();
}
}
delay(allOffUpDelay);
TreeLampMode = "standyby";
}
void allYellowUp(int exclude) {
// 一組一組往上亮,漸層感差,時間也拖太久
for (int w = 10; w > 0; w--) {
if (w == exclude) {
continue; // 跳過指定的exclude,繼續下一個迴圈
}
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[w]; i < LED_SetEnd[w]; i++) {
strip.setPixelColor(i, strip.Color(b, b, 0));
}
strip.show();
}
}
allYellowOffUp(exclude);
}
void allYellowOffUp(int exclude) {
// 一組一組往上亮,漸層感差,時間也拖太久
for (int w = 10; w > 0; w--) {
if (w == exclude) {
continue; // 跳過指定的exclude,繼續下一個迴圈
}
for (int b = brightnessLimit; b > 0; b = b - allUpSpeed) {
for (int i = LED_SetStart[w]; i < LED_SetEnd[w]; i++) {
strip.setPixelColor(i, strip.Color(b, b, 0));
}
strip.show();
}
}
delay(allOffUpDelay);
TreeLampMode = "standyby";
}
void allRedUp(int exclude) {
// 一組一組往上亮,漸層感差,時間也拖太久
for (int w = 10; w > 0; w--) {
if (w == exclude) {
continue; // 跳過指定的exclude,繼續下一個迴圈
}
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[w]; i < LED_SetEnd[w]; i++) {
strip.setPixelColor(i, strip.Color(b, 0, 0));
}
strip.show();
}
}
allRedOffUp(exclude);
}
void allRedOffUp(int exclude) {
// 一組一組往上亮,漸層感差,時間也拖太久
for (int w = 10; w > 0; w--) {
if (w == exclude) {
continue; // 跳過指定的exclude,繼續下一個迴圈
}
for (int b = brightnessLimit; b > 0; b = b - allUpSpeed) {
for (int i = LED_SetStart[w]; i < LED_SetEnd[w]; i++) {
strip.setPixelColor(i, strip.Color(b, 0, 0));
}
strip.show();
}
}
delay(allOffUpDelay);
TreeLampMode = "standyby";
}
void allLampOff() {
for (int i = 0; i < LED_TOTAL_COUNT; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
delay(100);
}
void LampSelectOff(int LampSelect) {
switch (LampSelect) {
case 0:
break;
case 1:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[1]; i < LED_SetEnd[1]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 2:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[2]; i < LED_SetEnd[2]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 3:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[3]; i < LED_SetEnd[3]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 4:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[4]; i < LED_SetEnd[4]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 5:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[5]; i < LED_SetEnd[5]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 6:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[6]; i < LED_SetEnd[6]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 7:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[7]; i < LED_SetEnd[7]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 8:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[8]; i < LED_SetEnd[8]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 9:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[9]; i < LED_SetEnd[9]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
case 10:
for (int b = 0; b < brightnessLimit; b = b + allUpSpeed) {
for (int i = LED_SetStart[10]; i < LED_SetEnd[10]; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
break;
}
}
void breatheLED() {
for (int i = 1 ; i < 11 ; i++) { // 亮度遞增(或遞減)
brightness[i] = brightness[i] + increment[i];
}
for (int i = 1 ; i < 11 ; i++) { // 判斷亮度是否小於0或大於上限,如是,反向
if (brightness[i] <= 0 || brightness[i] >= brightnessLimit) {
increment[i] = -increment[i];
}
}
for (int q = 1 ; q < 11; q ++) { // q是10個燈組
for (int i = LED_SetStart[q]; i < LED_SetEnd[q]; i++) {
strip.setPixelColor(i, strip.Color(0, brightness[q], 0));
}
}
strip.show();
}