距離センサとDFPlayerMiniとLEDテープを組み合わせて、センサにモノを近づけた時にカウントしつつ音を鳴らしつつ光る装置を作成する

目的
距離センサとDFPlayerMiniとLEDテープを組み合わせて、センサにモノを近づけた時にカウントしつつ音を鳴らしつつ光る装置を作成した際の備忘録です。
（始めはモノをカウントするだけのつもりだったのですが、段々と機能が増えてきました。）

# 準備

Arduino Uno
[DFPlayerMini](https://www.amazon.co.jp/gp/product/B01D1D0E7Q/ref=ppx_yo_dt_b_asin_title_o06__o00_s01?ie=UTF8&psc=1)
[VL53L0X Time-of-Flight 距離センサモジュール](https://www.switch-science.com/catalog/2869/)
[MAX7219 8×8ドットマトリックスモジュール](http://e-structshop.com/item/mlk0001/)
[NeoPixel 1515 LEDテープ](https://www.switch-science.com/catalog/6008/)

マイクロSDカードへ音楽ファイルを保存します。（[ArduinoにDFPlayerMiniを繋いでmp3音楽再生をする](https://qiita.com/seigot/items/719758b66b84698d1f0d)の通り準備します）

# 回路図

以下を組み合わせます。
NeoPixelは、PIN3に繋ぎます。

> [距離センサとDFPlayerMiniを組み合わせて、センサにモノを近づけた時にカウントしつつ音を鳴らす装置を作成する](https://qiita.com/seigot/items/4ef8fb2aa3f551a06bb9)
> [NeoPixel 1515 LEDテープをarduinoで光らせる](https://qiita.com/seigot/items/467c6a5c70e8d9cf6bfe)

# コード

```
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include <VL53L0X.h>

#define BUSY_PINNO 7
#define NEOPIXEL_PIN 2
#define NUM_NEOPIXEL_PIN 75

VL53L0X sensor;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_NEOPIXEL_PIN, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
SoftwareSerial mySoftwareSerial(10, 11); // (TX, RX)
//SoftwareSerial mySoftwareSerial(3, 2); // (TX, RX)
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

 unsigned char i;
 unsigned char j; 
 int g_cnt = 0;
/*port definition*/
int Max7219_pinCLK = 6;
int Max7219_pinCS = 5;
int Max7219_pinDIN = 4;

unsigned char disp1[38][8]={
{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//0
{0x10,0x18,0x14,0x10,0x10,0x10,0x10,0x10},//1
{0x7E,0x2,0x2,0x7E,0x40,0x40,0x40,0x7E},//2
{0x3E,0x2,0x2,0x3E,0x2,0x2,0x3E,0x0},//3
{0x8,0x18,0x28,0x48,0xFE,0x8,0x8,0x8},//4
{0x3C,0x20,0x20,0x3C,0x4,0x4,0x3C,0x0},//5
{0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C,0x0},//6
{0x3E,0x22,0x4,0x8,0x8,0x8,0x8,0x8},//7
{0x0,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E},//8
{0x3E,0x22,0x22,0x3E,0x2,0x2,0x2,0x3E},//9
{0x8,0x14,0x22,0x3E,0x22,0x22,0x22,0x22},//A
{0x3C,0x22,0x22,0x3E,0x22,0x22,0x3C,0x0},//B
{0x3C,0x40,0x40,0x40,0x40,0x40,0x3C,0x0},//C
{0x7C,0x42,0x42,0x42,0x42,0x42,0x7C,0x0},//D
{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C},//E
{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x40},//F
{0x3C,0x40,0x40,0x40,0x40,0x44,0x44,0x3C},//G
{0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44},//H
{0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x7C},//I
{0x3C,0x8,0x8,0x8,0x8,0x8,0x48,0x30},//J
{0x0,0x24,0x28,0x30,0x20,0x30,0x28,0x24},//K
{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C},//L
{0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81},//M
{0x0,0x42,0x62,0x52,0x4A,0x46,0x42,0x0},//N
{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//O
{0x3C,0x22,0x22,0x22,0x3C,0x20,0x20,0x20},//P
{0x1C,0x22,0x22,0x22,0x22,0x26,0x22,0x1D},//Q
{0x3C,0x22,0x22,0x22,0x3C,0x24,0x22,0x21},//R
{0x0,0x1E,0x20,0x20,0x3E,0x2,0x2,0x3C},//S
{0x0,0x3E,0x8,0x8,0x8,0x8,0x8,0x8},//T
{0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1C},//U
{0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18},//V
{0x0,0x49,0x49,0x49,0x49,0x2A,0x1C,0x0},//W
{0x0,0x41,0x22,0x14,0x8,0x14,0x22,0x41},//X
{0x41,0x22,0x14,0x8,0x8,0x8,0x8,0x8},//Y
{0x0,0x7F,0x2,0x4,0x8,0x10,0x20,0x7F},//Z
{0x8,0x7F,0x49,0x49,0x7F,0x8,0x8,0x8},//Chinese character
{0xFE,0xBA,0x92,0xBA,0x92,0x9A,0xBA,0xFE},//Chinese character
};


void Write_Max7219_byte(unsigned char DATA) 
{   
            unsigned char i;
      digitalWrite(Max7219_pinCS,LOW);    
      for(i=8;i>=1;i--)
          {     
             digitalWrite(Max7219_pinCLK,LOW);
             digitalWrite(Max7219_pinDIN,DATA&0x80);//Obtain the MSB of the data
             DATA = DATA<<1;
             digitalWrite(Max7219_pinCLK,HIGH);
           }                                 
}


void Write_Max7219(unsigned char address,unsigned char dat)
{
        digitalWrite(Max7219_pinCS,LOW);
        Write_Max7219_byte(address);           //
        Write_Max7219_byte(dat);               //
        digitalWrite(Max7219_pinCS,HIGH);
}

void Init_MAX7219(void)
{
 Write_Max7219(0x09, 0x00);       //decode: BCD
 Write_Max7219(0x0a, 0x03);       //Brightness
 Write_Max7219(0x0b, 0x07);       //
 Write_Max7219(0x0c, 0x01);       //
 Write_Max7219(0x0f, 0x00);       //
}

void setup()
{
  Serial.begin(9600);  

  // software serial init
  mySoftwareSerial.begin(9600);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }

  // init DFMiniPlayer
  // BUSY_PINNO init
  pinMode(BUSY_PINNO, INPUT);

  // DFPlayer Init
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms  
  myDFPlayer.volume(25);  //Set volume value (0~30).
  // myDFPlayer.volumeUp(); //Volume Up
  // myDFPlayer.volumeDown(); //Volume Down  
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);    
  //myDFPlayer.play(1);  //Play the first mp3

  // init distance sensor
  Wire.begin();

  sensor.setTimeout(500);
  if (!sensor.init())
  {
    Serial.println("Failed to detect and initialize sensor!");
    while (1) {}
  }

  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  sensor.startContinuous();

  // init DotMatrix Module
  pinMode(Max7219_pinCLK,OUTPUT);
  pinMode(Max7219_pinCS,OUTPUT);
  pinMode(Max7219_pinDIN,OUTPUT);
  delay(50);
  Init_MAX7219();

  for(i=1;i<9;i++) {
    Write_Max7219(i,disp1[g_cnt][i-1]);
  }

  // init NeoPixel
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void PLAYBACK_MP3_MUSIC(void) {
  int isBusy = digitalRead(BUSY_PINNO); // 0:playing, 1:not playing (refer website)
  Serial.println(isBusy);
  //if (isBusy == 1) {
    myDFPlayer.next();  //Play next mp3 every 3 second.
  //}
}

void DelayWithLight(void) {

  for(int delayloop=0; delayloop<8; delayloop++){

    //回数
    int sensor0 = abs(analogRead(A0)-512);
    for(int i=0; i<NUM_NEOPIXEL_PIN; i++){
       if(sensor0>100){
         int r = random(0,NUM_NEOPIXEL_PIN);
         int cR = random(0,256);
         int cG = random(0,256);
         int cB = random(0,256);
         strip.setPixelColor(r, strip.Color(cR,cG,cB));
      }
      strip.show();
    } 
  
    //All off
    for(int i=0; i<NUM_NEOPIXEL_PIN; i++){
      strip.setPixelColor(i, strip.Color(0,0,0));
      strip.show();
    }
    Serial.println(sensor0);
    // delay(1);
  }
}

void loop()
{
  int val;
  val = sensor.readRangeContinuousMillimeters();
  Serial.print(val);
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

  Serial.println();

  if( val < 180 ) {
    PLAYBACK_MP3_MUSIC();
    g_cnt++;
    for(i=1;i<9;i++) {
      Write_Max7219(i,disp1[g_cnt][i-1]);
    }
    //delay(2000);
    DelayWithLight();
  }
}
```

# テスト
距離センサとDFPlayerMiniとLEDテープを組み合わせて、センサにモノを近づけた時にカウントしつつ音を鳴らしつつ光ればOKです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">センサにモノを近づけた時にカウントしつつ音を鳴らす装置を作成 <a href="https://t.co/9kpcC9uK7T">pic.twitter.com/9kpcC9uK7T</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1226008034066911235?ref_src=twsrc%5Etfw">February 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 備考
光る時間の調整にdelay()を使おうと思ったが上手くいかず、現状はforループで光る時間を調整しています。

# 参考
[距離センサとDFPlayerMiniを組み合わせて、センサにモノを近づけた時にカウントしつつ音を鳴らす装置を作成する](https://qiita.com/seigot/items/4ef8fb2aa3f551a06bb9)
[NeoPixel 1515 LEDテープをarduinoで光らせる](https://qiita.com/seigot/items/467c6a5c70e8d9cf6bfe)