---
# System prepended metadata

title: ガチャガチャLチカ

---

# ガチャガチャ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()``関数の第１引数、第２引数、第３引数は配列になっています。引数は緑、赤、青の順番で、それぞれの配列の１項目は光らせる段階、２項目は光らせる前の段階を表しています。
