ArduinoとWi-Fiを使ったLED演出の詳細


<img width="700" alt="DSC_0263.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/149571/d625b82d-2841-94c5-9919-406fb5f2345a.jpeg">

`サマーソニックでの学生展示にてESP32とArduinoNanoを使用してLED光らせました。
結果：人の多いところで2.4GHzを使うのは良くない。有線にしたほうがいい。
`

`サマソニ会場にて作品の展示を終え、参考にさせていただいた方々への感謝の意を込めた備忘録。
コードを書き始めて3か月の人間なのでこの記事だけ参考にするのはアブナイ`

#使用したもの#
PC - 音響、UDPからのLEDテープ制御
ESP32 - Wi-FiでUDP受信
Arduino Nano　- LED制御
モバイルバッテリー　- 基板用電源
Wi-Fiルーター - 通信
美しい影を作り出す創作物
nanoKONTROL2　- MIDI


#構造#
nanoKONTROL2
*↓　MIDI*
vvvv入りPC
*↓　WiFi*
ESP32
*↓　アナログ信号*
Arduino Nano
*↓  　*
LEDテープ

#プログラム#
MIDIinとピーク解析し良いタイミングでUDPを送るvvvv(PC)、UDPを受けて色情報と更新速度をAnalogPinに送る(ESP32)、AnalogPinからLEDテープを制御する(ArduinoNano)
この3系統に分かれているのでそれらに分けて書いていく。
##vvvv##

`全体画面`
<img width="952" alt="v4-1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/149571/44cfa71f-8322-00d6-b3c6-dd29f224da55.png">

`UDP送信`
<img width="387" alt="v4-UDP.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/149571/76faa33b-de2a-b9b9-888f-49bd668b9e69.png">

`FFT4Channelの改変`
<img width="358" alt="v4-FFT.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/149571/2fdcd1e4-7d58-fa2f-ebcb-b9cd359d05af.png">

`ピークを取る値をFFTから取り出す部分`
<img width="252" alt="v4-PEAK.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/149571/ab8696c5-e084-3929-e407-f814132226a0.png">


##ESP32##

```c:ESP32inWiFiUdpAnalog
//子機
#include <Wire.h>

#include <WiFi.h>
#include <WiFiUdp.h>

#define rOutPin  12
#define gOutPin  13
#define bOutPin  14
#define sOutPin  25

static char packetBuffer[255];

const char * networkName = "TP-Link_A8C2";
const char * networkPswd = "91859655";

//IP address to send UDP data to:
// either use the ip address of the server or 
// a network broadcast address

const char * udpAddress = "192.168.1.175";
const int udpPort = 10000;//親機ポート番号

boolean connected = false;

//The udp library class
WiFiUDP udp;


int data;
int r;
int g;
int b;
int s;



void setup() {


 ///RGB出力設定
  pinMode(rOutPin,OUTPUT);
  pinMode(gOutPin,OUTPUT);
  pinMode(bOutPin,OUTPUT);
  pinMode(sOutPin,OUTPUT);
  sigmaDeltaSetup(0,312500);
  sigmaDeltaSetup(1,312500);
  sigmaDeltaSetup(2,312500);
  sigmaDeltaSetup(3,312500);
  sigmaDeltaAttachPin(rOutPin,0);
  sigmaDeltaAttachPin(gOutPin,1);
  sigmaDeltaAttachPin(bOutPin,2);
  sigmaDeltaAttachPin(sOutPin,3);

/*
  //Wire設定
  int SDA = 25;
  int SCL = 26;
  Wire.begin(SDA, SCL); // ()だと親。()内に数字入れると子機のアドレスになる
  */

  
  Serial.begin(115200);

  //WiFi接続
  connectToWiFi(networkName, networkPswd);
  if(connected == false){
    connectToWiFi(networkName, networkPswd);
    }

}

//WiFi接続設定
void connectToWiFi(const char * ssid, const char * pwd){
  Serial.println("Connecting to WiFi network: " + String(ssid));
  // delete old config
  WiFi.disconnect(true);
  //register event handler
  WiFi.onEvent(WiFiEvent);
  //Initiate connection
  WiFi.begin(ssid, pwd);
  Serial.println("Waiting for WIFI connection...");
}

//wifi event handler
void WiFiEvent(WiFiEvent_t event){
    switch(event) {
      case SYSTEM_EVENT_STA_GOT_IP:
          //When connected set 
          Serial.print("WiFi connected! IP address: ");
          Serial.println(WiFi.localIP());  
          //initializes the UDP state
          //This initializes the transfer buffer
          udp.begin(WiFi.localIP(),udpPort);
          connected = true;
          break;
      case SYSTEM_EVENT_STA_DISCONNECTED:
          Serial.println("WiFi lost connection");
          connected = false;
          break;
    }
}


void loop() {
  int x ;
  
  //Serial.println(x); // print the integer　数字をシリアルモニタに表示
  
  int packetSize = udp.parsePacket();
  int len = udp.read(packetBuffer, 255);
  for(int i=0;i<packetSize;i++){
  int x = packetBuffer[0];
  int y = packetBuffer[1];
  Serial.print(x);
  Serial.print(" : ");
  Serial.println(y);
  if(y !=1){
   if(x != 0){
    if(x <= 100){
     int r = x;
     r = r*5;
      sigmaDeltaWrite(0,r);
    }else
    if(x >= 100 && x <=200 ){
      int g = x-100;
      g = g*5;
      sigmaDeltaWrite(1,g);
    }else
    if(x >= 200 && x <=300 ){
      int b = x-200;
      b = b*5;
      sigmaDeltaWrite(2,b);
      }
     }
   }
    if(y != 0){
      int s = x-44;
      s = s*5;
      sigmaDeltaWrite(3,s);
      }
//  Serial.print(" R :");
//      Serial.println(r);
//  Serial.print(" G :");
//      Serial.println(g);
//  Serial.print(" B :");
//      Serial.println(b);
//  Serial.print(" I2C :");
 //     Serial.println(s);
   
 }
}
```


##ArduinoNano##
```c:ArduinoNanoAnalogLed
#include <SoftwareSerial.h>
#include <Adafruit_NeoPixel.h>
#define Array 10
int myArrayNum[Array]={2,3,4,5,6,7,8,9};
int myArray[Array]={1,1,2,2,5,5,10,10,20,20};

#define MAX_VAL  50 // 0 to 255 for brightness
#define DELAY_TIME 10
#define NUMPIXELS 350
#define OVERTIME 450
#define CAB 675 //AnalogIn最大値
int r ;
int g ;
int b ;
int s ;
int fnR;
int fnG;
int fnB;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, 13, NEO_GRB + NEO_KHZ800);


void setup() {
  pinMode(A0,INPUT);
  pinMode(A1,INPUT);
  pinMode(A2,INPUT);
  pinMode(A3,INPUT);
  pinMode(13,OUTPUT);
  
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
//Serial.begin(9600); // start serial for output　シリアルモニタ表示用
}

void loop() {
 for(int i=0;i <=OVERTIME; i++){
  
  //アナログ信号からR値を変換
  int r = map(analogRead(0),0,CAB,0,255);
  Serial.print(analogRead(0));
  Serial.print("R :");
  Serial.print(r);
  
  //アナログ信号からG値を変換
  int g = map(analogRead(1),0,CAB,0,255);
  Serial.print("  G :");
  Serial.print(g);
  
  //アナログ信号からB値を変換
  int b = map(analogRead(2),0,CAB,0,255);
  Serial.print("  B :");
  Serial.print(b);

  //アナログ信号からDlay値を変換
  float s = map(analogRead(3),0,CAB,1,5);
  float fs = map(analogRead(3),0,CAB,50,100);
  fs=fs/100;
  Serial.print("  delay :");
  Serial.print(s);
  delay(s);
  
  Serial.println(",");

 
  
  //ON/OFF判別、ONになると加算。加算が終わるまでON
  
  //R値がONの時LED数分加算する
  if(r>=100||fnR >=1){
  fnR = fnR +s;
  if(fnR >=NUMPIXELS)fnR=0;
  }
  
  //G値がONの時LED数分加算する
  if(g>=100||fnG >=1){
  fnG = fnG +s;
  if(fnG >=NUMPIXELS)fnG=0;
  }
  
   //B値がONの時LED数分加算する
  if(b>=100||fnB >=1){
  fnB = fnB +s;
  if(fnB >=NUMPIXELS)fnB=0;
  }
  

  //加算結果をもとにLEDを点灯
  
    //LEDを黒で塗りつぶし
      for(int i=0 ; i<NUMPIXELS; i++){
     strip.setPixelColor(i, strip.Color(0,0,0));
     } 

   //LED用にrgb変数をトリム

   //LEDを加算値のflowFishで塗りつぶせ
      for(int p=0 ; p<Array; p++){
       strip.setPixelColor(fnR - myArrayNum[p], strip.Color(0,255*fs/myArray[p],255*fs/myArray[p]));
       strip.setPixelColor(fnG - myArrayNum[p], strip.Color(255*fs/myArray[p],255*fs/myArray[p],0));
       strip.setPixelColor(fnB - myArrayNum[p], strip.Color(255*fs/myArray[p],0,255*fs/myArray[p]));
       }
      
  Serial.println(fnR);
  Serial.println(fnG);
  Serial.println(fnB);
        
    //LED表示
     strip.show();
     delay(70/s);
 }
}



```

#さいごに#
雑感備忘録なので、詳細な部分を見たいという方が居ましたらtwitter[(@skckmdtk2m)](https://twitter.com/skckmdtk2m)かコメントにてお教えください
追記します。