# ガチャガチャ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項目は光らせる前の段階を表しています。