# ガチャガチャLチカ
## コード
### 最初の定義
```=c
#define NUM_LEDS 49
//LEDの数は固定ではないのでご安心を
CRGB leds[NUM_LEDS];
const int FLED = 13;
int counter = 0;
int led_mediums[2];
int insert_coin_direction_flag = 0;//コイン投入時に使う
int spin_direction_counter = 0;//ハンドル回転中に使う
int capsule_exaust_direction_flag = 0;//カプセルが出てきたときに使う
```
### setup()に書く分
```=c
FastLED.addLeds<WS2812, FLED, RGB>(leds, NUM_LEDS);
if (NUM_LEDS % 2 == 0) {
led_mediums[0] = NUM_LEDS / 2 - 1;//超重要な変数です。LEDの一連の発光の流れを左右独立させるための境目の添字が入る。NUM_LEDSが偶数か奇数かでどのように分割するかが決まる
led_mediums[1] = NUM_LEDS / 2;
} else {
led_mediums[0] = NUM_LEDS / 2 - 1;//NUM_LEDSが奇数の場合、真ん中のLEDを光らせようとすると動かないなど面倒だったので折衷案です
led_mediums[1] = NUM_LEDS / 2 + 1;
}
//消灯
for (int i = 0; i < NUM_LEDS; i++) {
leds[i].r = 0;
leds[i].g = 0;
leds[i].b = 0;
}
FastLED.show();
```
### 関数たち
```=c
void setColor(int i, int offset) {//updateLedsの中で使っています!!
if (i % 3 == 0) {
leds[i] = CRGB((255 * ((offset + 2) % 3 == 0)), (255 * ((offset + 1) % 3 == 0)), (255 * (offset % 3 == 0)));
} else if (i % 3 == 1) {
leds[i] = CRGB((255 * ((offset + 1) % 3 == 0)), (255 * (offset % 3 == 0)), (255 * ((offset + 2) % 3 == 0)));
} else {
leds[i] = CRGB((255 * (offset % 3 == 0)), (255 * ((offset + 2) % 3 == 0)), (255 * ((offset + 1) % 3 == 0)));
}
}
void updateLeds(int count) {
int offset = count % 3;
for (int i = 0; i < led_mediums[0]; i++) {
setColor(i, offset);
Serial.println("Led_A light");
}
for (int i = NUM_LEDS - 1; i >= led_mediums[1]; i--) {
setColor(i, (offset + 2) % 3);
Serial.println("Led_B light");
}
FastLED.show();
}
void led_light_from_edge(int *red_color, int *green_color, int *blue_color, int cnt) {
Serial.println("led_light_from_edge start");
//int counter = 0;
int led_current_a = 0;
int led_current_b = NUM_LEDS - 1;
while(led_current_a <= led_mediums[0] || led_current_b >= led_mediums[1]) {
if(led_current_a < cnt) {
leds[led_current_a] = CRGB(red_color[0], green_color[0], blue_color[0]);
leds[led_current_b] = CRGB(red_color[0], green_color[0], blue_color[0]);
} else {
leds[led_current_a] = CRGB(red_color[1], green_color[1], blue_color[1]);
leds[led_current_b] = CRGB(red_color[1], green_color[1], blue_color[1]);
}
led_current_a++;
led_current_b--;
}
FastLED.show();
Serial.println("led_light_from_edge end");
}
void led_light_group_line(int red_color, int green_color, int blue_color, int cnt) {
for (int i = 0; i < led_mediums[0]; i++) {
leds[i] = CRGB(red_color*(i % 5 != cnt), green_color*(i % 5 != cnt), blue_color*(i % 5 != cnt));
}
for (int i = NUM_LEDS - 1; i >= led_mediums[1]; i--) {
leds[i] = CRGB(red_color*(i % 5 != abs(cnt - 4)), green_color*(i % 5 != abs(cnt - 4)), blue_color*(i % 5 != abs(cnt - 4)));
}
FastLED.show();
}
void led_light_group_line_reverse(int red_color, int green_color, int blue_color, int cnt) {
for (int i = 0; i < led_mediums[0]; i++) {
leds[i] = CRGB(red_color*(i % 5 == cnt), green_color*(i % 5 == cnt), blue_color*(i % 5 == cnt));
}
for (int i = NUM_LEDS - 1; i >= led_mediums[1]; i--) {
leds[i] = CRGB(red_color*(i % 5 == abs(cnt - 4)), green_color*(i % 5 == abs(cnt - 4)), blue_color*(i % 5 == abs(cnt - 4)));
}
FastLED.show();
}
void led_left_right(int red_color, int green_color, int blue_color, int cnt) {
for (int i = 0; i < led_mediums[0]; i++) {
leds[i] = CRGB(red_color*(cnt % 2 == 0), green_color*(cnt % 2 == 0), blue_color*(cnt % 2 == 0));
}
for (int i = NUM_LEDS - 1; i >= led_mediums[1]; i--) {
leds[i] = CRGB(red_color*(cnt % 2 != 0), green_color*(cnt % 2 != 0), blue_color*(cnt % 2 != 0));
}
FastLED.show();
}
```
## 流れ
### 待機状態
- ``updateLeds()``を250ミリ秒間隔で呼び出す。このとき **if(counter >= 3)** の条件下でcounterはゼロにリセット
- **このタイミングで spin_direction_counter, insert_coin_direction_flag, capsule_exaust_direction_flag これら三つの変数を0に初期化しておくのがいいかも??**
```=c
spin_direction_counter = 0;
insert_coin_direction_flag = 0;
capsule_exaust_direction_flag = 0;
```
### コイン投入時
- ``led_light_from_edge()``関数を白色で呼び出し、全部LEDがついた状態で1秒おく
- 1秒おいたらcounterをリセットし、``led_light_group_line()``を白色で70ミリ秒間隔で呼び出す。これを回し始めるまで続ける。このとき **if(counter >= 5)** の条件下でcounterはゼロにリセット
参考例(loop関数の中)
```=c
if(insert_coin_direction_flag == 0) {
int red[2] = {255, 0};
int green[2] = {255, 0};
int blue[2] = {255, 0};
led_light_from_edge(red, green, blue, counter);
counter++;
delay(35);
if(counter >= led_mediums[0]) {
delay(1000);
counter = 0;
insert_coin_direction_flag++;
}
} else {
led_light_group_line(255, 255, 255, counter);
delay(70);
counter++;
if(counter >= 5) {
counter = 0;
}
}
```
### 回してる最中
- ``led_light_from_edge()``を**赤→緑→青→無色**の順に走らせていく。間隔は20ミリ秒。このとき **if(counter >= led_mediums[0])** の条件下でcounterはゼロにリセット
参考例(loop関数の中)
```=c
int red[2] = {255*(spin_direction_counter == 0), 255*(spin_direction_counter == 1)};
int green[2] = {255*(spin_direction_counter == 1), 255*(spin_direction_counter == 2)};
int blue[2] = {255*(spin_direction_counter == 2), 255*(spin_direction_counter == 3)};
/*
最初はspin_direction_counterがゼロで、redの一項目だけ255にする
spin_direction_counterが1のときは、redの二項目とgreenの一項目が0
spin_direction_counterが2のときは、greenの二項目とblueの一項目が0
spin_direction_counterが3のときは、blueの二項目だけが255
*/
led_light_from_edge(red, green, blue, counter);
counter++;
delay(10);
if(counter >= led_mediums[0]) {
counter = 0;
spin_direction_counter++;
}
if(spin_direction_counter >= 4) {
spin_direction_counter = 0;
}
```
### カプセルの色判定中
- ``led_light_group_line_reverse()``を白色で50ミリ秒間隔で呼び出す。このとき **if(counter >= 5)** の条件下でcounterはゼロにリセット
参考例(loop関数の中)
```=c
led_light_group_line_reverse(255, 255, 255, counter);
counter++;
delay(50);
if(counter >= 5) {
counter = 0;
}
```
### カプセルの色判定完了
- ``led_left_right()``を判定した色で125ミリ秒間隔で呼び出す。これを6回繰り返す
- 6回繰り返したらcounterをリセットし、``led_light_group_line()``を判定した色で70ミリ秒間隔で呼び出す。このとき **if(counter >= 5)** の条件下でcounterはゼロにリセット。終わるタイミングは映像が待機状態に戻るときを目安に
参考例(loop関数の中)
```=c
if(capsule_exaust_direction_flag == 0) {
led_left_right(0, 0, 255, counter);//今回は青になってますがここに判定結果の色を入れる
counter++;
delay(250);
if(counter >= 6) {
counter = 0;
capsule_exaust_direction_flag++;
}
} else {
led_light_group_line(0, 0, 255, counter);//今回は青になってますがここに判定結果の色を入れる
counter++;
delay(50);
if(counter >= 5) {
counter = 0;
}
}
```
## 諸注意
- 状況によってcounterをゼロに戻す条件が変わるので注意してください!
- ``led_light_from_edge()``関数の第1引数、第2引数、第3引数は配列になっています。引数は緑、赤、青の順番で、それぞれの配列の1項目は光らせる段階、2項目は光らせる前の段階を表しています。