ESP32でserial bluetooth接続

ESP32でbluetooth接続を試した. 
ESP32もbluetooth接続デバイスをやるのも初めてなのでメモ. 

# 環境

- ESP32はbluetooth付のコレ:

>
waves NodeMCU-32S 開発ボード ESP32 ESP-32S WiFi Bluetooth 技適取得済 
waves 
固定リンク: http://amzn.asia/d7dPH9L

- Mac OSX10.11.6 El Capitan
- Arduino IDE 1.6.11

# code
https://github.com/keitasumiya/arduino/tree/master/esp32

# setup

[ESP32をArduino IDEで開発する](http://wave.hatenablog.com/entry/2017/11/12/083500)
[ESP32(ESP-WROOM-32)でLチカ (WindowsでArduino IDE使用)](https://qiita.com/rukihena/items/6a904368700eb1c7d2a3)

を参考にsetupしていきました. 

- [GitHub - espressif/arduino-esp32: Arduino core for the ESP32](https://github.com/espressif/arduino-esp32)
をDLする

- `Users/[user name]/Documents/Arduino/hardware/espressif/esp32`というディレクトリを作成. 

>- ただし, 私の場合は, arduino libralyの置き場所を変えていたので, 実際には`/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/`でした. 

>- ディレクトリの探し方は, `Arduino` > `Preferences...` > `スケッチブックの保存場所`です. 
私の場合はここが`/Volumes/T/Dropbox/arduino`となっています. 
 
- DLしたzipの中身を`esp32`以下に展開. 下記のような構造になります. 

```
esp32
├── Kconfig.projbuild
├── Makefile.projbuild
├── README.md
├── appveyor.yml
├── boards.txt
├── component.mk
├── cores
│   └── esp32
│       ├── Arduino.h
│       ├── Client.h
:       :
:       :
```

- `[hogehoge]/hardware/espressif/esp32/tools`に`cd`で移動

- `python get.py`でinstall

- [CP210x USB - UART ブリッジ VCP ドライバ](https://jp.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers)に飛んで, `Macintosh OSX（v5）用ダウンロード`の`ソフトウェア`からDL. 
>- 他のOSの場合は適宜自分の環境のものをDLすればOKかと. 

- DLした`SiLabsUSBDriverDisk.dmg`を実行してinstall

以上でsetupは完了. 

# 実行テスト
## pin
pinの配置は先のgitと購入元のamazon pageから引用しておきます. 

gitから:
![L1ZvbHVtZXMvVC9Ecm9wYm94L2FyZHVpbm8vaGFyZHdhcmUvZXNwcmVzc2lmL2VzcDMyL2RvY3MvZXNwMzJfcGlubWFwLnBuZw==.png](https://qiita-image-store.s3.amazonaws.com/0/102253/bc5a4dc9-f117-3451-9b65-cc3d0bed0ef0.png)

amazonから: 
![71+m5oDeHiL._SL1001_.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/ee61d324-f24d-9320-0b15-8824786dc243.jpeg)

実機から: 
![IMG_2408.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/c9c79da3-9608-bff2-b9a4-8c1a4b1eeba7.jpeg)
![IMG_2409.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/13030745-7132-24f1-6ec8-d37a39bcb381.jpeg)


## arduino IDEでの設定
- ボード
> 下記のどちらか:
>- `ツール > ボード> ESP32 Dev Module` 
>- `ツール > ボード> NodeMCU-32S`

- Upload Speed
>- `ツール > Upload Speed > 115200`

- Flash Frequency
>- `ツール > Flash Frequency > 80MHz`

- port
>- `ツール > シリアルポート　（cu.SLAB_USBtoUART)`

これで書き込むできるようになった. 


### error
コンソールに下記のerrorが出てしまう: 

```
「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/AzureIoT」に、無効なライブラリ「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/AzureIoT」があります。
「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/BLE」に、無効なライブラリ「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/BLE」があります。
```

以下のテストでは問題ないけど, 気になる. ver.か私のdirの配置の問題だろうか?


## serial通信

ホントはLEDのblinkで確かめたかったけど, 備え付けのLEDをblinkする方法がわからなかった(どのPIN?). 
出先でLEDと抵抗もジャンパーも持ち合わせてなかった. 
なので, serial通信でbuildできてるか確認することに. 

codeは下記を書き込む: 
[参考](https://github.com/espressif/arduino-esp32/issues/74) 

```C:serial_send_test.ino
void setup() {
    Serial.begin(9600);
}

void loop() {
    Serial.print("Hello");
  delay(1000);                      
}
```

数十秒たつとコンソールに下記が出て書き込み終了: 

```
最大1,310,720バイトのフラッシュメモリのうち、スケッチが163,053バイト（12%）を使っています。
最大294,912バイトのRAMのうち、グローバル変数が11,148バイト（3%）を使っていて、ローカル変数で283,764バイト使うことができます。
esptool.py v2.3.1
Connecting........__
Chip is ESP32D0WDQ6 (revision 0)
Features: WiFi, BT, Dual Core
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 8192 bytes to 47...

Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 6624.5 kbit/s)...
Hash of data verified.
Compressed 14320 bytes to 9327...

Writing at 0x00001000... (100 %)
Wrote 14320 bytes (9327 compressed) at 0x00001000 in 0.8 seconds (effective 138.0 kbit/s)...
Hash of data verified.
Compressed 164208 bytes to 84483...

Writing at 0x00010000... (16 %)
Writing at 0x00014000... (33 %)
Writing at 0x00018000... (50 %)
Writing at 0x0001c000... (66 %)
Writing at 0x00020000... (83 %)
Writing at 0x00024000... (100 %)
Wrote 164208 bytes (84483 compressed) at 0x00010000 in 7.5 seconds (effective 175.9 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 144...

Writing at 0x00008000... (100 %)
Wrote 3072 bytes (144 compressed) at 0x00008000 in 0.0 seconds (effective 1418.6 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/AzureIoT」に、無効なライブラリ「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/AzureIoT」があります。
「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/BLE」に、無効なライブラリ「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/BLE」があります。
「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/AzureIoT」に、無効なライブラリ「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/AzureIoT」があります。
「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/BLE」に、無効なライブラリ「/Volumes/T/Dropbox/arduino/hardware/espressif/esp32/libraries/BLE」があります。

```

シリアルモニタをみると, 

```
HelloHelloHello
```

といった具合に, 1secごとにHelloが書き込まれる. ESP32自体のbuildができたことと, arduino > macへのUSBケーブル経由でのserial通信がOKということが確認できた. 



## serail通信 via bluetooth
[issues](https://github.com/espressif/arduino-esp32/issues/190)をみると, `simpleBLE`を使うらしいのだけど, コレを実行しても, このESP32に関するBLEデバイスがmacから見つけられず...

なので, 

[ESP32 Arduino: Serial communication over Bluetooth Hello World](https://techtutorialsx.com/2018/03/09/esp32-arduino-serial-communication-over-bluetoth-hello-world/)
を参考に, 
`#include "BluetoothSerial.h"`を使いました. 

[参考ページにある動画](https://www.youtube.com/watch?v=884u3saDoi8)も見ました. 


- 下記のcodeを書きこむ: 

```C:bluetooth_serial_test.ino
#include "BluetoothSerial.h"
 
BluetoothSerial SerialBT;
 
void setup() {
  SerialBT.begin("ESP32");
}
 
void loop() {
 
  SerialBT.println("Hello World");
  delay(1000);
}
```


- macのシステム環境設定のbluetooth画面を開く

- `ESP32`というデバイスがあるはずなので, それとペアリング

- arduino IDEで`cu.ESP32-ESP32_SPP_SERVER`というportを選択
>- `ツール > シリアルポート　（cu.ESP32-ESP32_SPP_SERVER)`

- シリアルモニタをみると1secごとに`Hello World`が書き込まれる. 
>
```
Hello World
Hello World
Hello World
Hello World
```

これでESP32とBluetooth経由でserial通信ができました!!

# 今後

[MacでArduinoIDEとESP32でLチカ](https://kokensha.xyz/iot/mac-esp32-and-arduino-led/)
[ESP32でウェブからサーボを制御する！](https://kokensha.xyz/iot/control-servo-from-web-with-esp32/)
など, wifiやbluetoothでもっといろいろやってみたいです. 


# oFと連携してbluetoothコントローラー (2018/06/21)
## 環境

- [秋月のESP32](http://akizukidenshi.com/catalog/g/gM-11819/)
- Mac OSX10.11.6 El Capitan
- Arduino IDE 1.6.11
- oF 0.9.8

>
[HiLetgo ESP32 ESP-32S NodeMCU開発ボード2.4GHz WiFi + Bluetoothデュアルモード](http://amzn.asia/8lIbVSQ)
は, arduino IDEから書き込むときに接続エラーが頻発し, 使い勝手が悪かった

## 接続した図
![IMG_2452.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/3a343c9f-94bb-996f-64ad-a8a0cfa10ecb.jpeg)

## git
https://github.com/keitasumiya/ESP32/tree/master/bluetooth_controller

## code
### arduino

```bluetooth_serial_write_1byte_change_sw.ino
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
const int pin = 2;
int stateSW;
int count;
int delta;
int coe;

void setup() {
  SerialBT.begin("ESP32");
  pinMode(pin, INPUT);
  stateSW = 0;
  count = 0;
  //delta = 1;
  delta = 5;
  coe = 1;
}

void loop() {
  if(count+coe*delta<  0){coe*=-1;}
  if(count+coe*delta>200){coe*=-1;}
  count+=coe*delta;
  if(count<  0){count=  0;}
  if(count>200){count=200;}
  
  stateSW = digitalRead(pin);
  if(stateSW==0){
    SerialBT.write(count);
  }else{
    SerialBT.write(255);
  }
  delay(10);
}
```

### oF
`bin/data/`の下に`cooperBlack.ttf`を入れる(フォントのためなので本質ではない)

```main.cpp
#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main( ){
	ofSetupOpenGL(1200,1000,OF_WINDOW);			// <-------- setup the GL context

	// this kicks off the running of my app
	// can be OF_WINDOW or OF_FULLSCREEN
	// pass in width and height too:
	ofRunApp(new ofApp());

}
```

```ofApp.cpp
#include "ofApp.h"

ofSerial mySerial1;
ofSerial mySerial2;
int myByte1 = 0;
int myByte2 = 0;
int r1 = 0;
int r2 = 0;

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetCircleResolution(64);
    ofSetBackgroundColor(0);
    
    //ofSetBackgroundAuto(false);
    ofSetVerticalSync(false);
    ofSetFrameRate(0);
    //ofSetFrameRate(60);
    //mySerial.setup("/dev/cu.usbmodem1421",9600);
    //mySerial.setup("/dev/tty.usbmodem1422",9600);
    mySerial1.setup("/dev/cu.ESP32-ESP32_SPP_SERVER-3",115200);
    mySerial2.setup("/dev/cu.ESP32-ESP32_SPP_SERVER-4",115200);
    
    myFont.load("cooperBlack.ttf", 100, true, true, true);
}

//--------------------------------------------------------------
void ofApp::update(){
    myByte1 = mySerial1.readByte();
    myByte2 = mySerial2.readByte();
}

//--------------------------------------------------------------
void ofApp::draw(){
    if ( myByte1 == OF_SERIAL_NO_DATA )
        printf("1:  NULL");
    else if ( myByte1 == OF_SERIAL_ERROR )
        printf("1: ERROR");
    else
        r1 = myByte1;
        //printf("1:  %d  ", myByte1);

    printf("   ");

    if ( myByte2 == OF_SERIAL_NO_DATA )
        printf("2:  NULL \n");
    else if ( myByte2 == OF_SERIAL_ERROR )
        printf("2: ERROR \n");
    else
        r2 = myByte2;
        //printf("2:  %d \n", myByte2);


    if(r1==255){
        ofSetColor(255, 255, 255);
        ofDrawCircle(int(ofGetWidth()/2.0-300), int(ofGetHeight()/2.0), r1+ofRandom(0, 20));
    }else if(r1<255){
        ofSetColor(255, 0, 0);
        ofDrawCircle(int(ofGetWidth()/2.0-300), int(ofGetHeight()/2.0), r1);
    }
    
    if(r2==255){
        ofSetColor(255, 255, 255);
        ofDrawCircle(int(ofGetWidth()/2.0+300), int(ofGetHeight()/2.0), r2+ofRandom(0, 20));
    }else if(r2<255){
        ofSetColor(0, 0, 255);
        ofDrawCircle(int(ofGetWidth()/2.0+300), int(ofGetHeight()/2.0), r2);
    }

    ofSetColor(255);
    ofFill();
    //myFont.drawString("hello",100,100);
    myFont.drawString(ofToString(r1), int(ofGetWidth()/2.0-300-100), int(ofGetHeight()/2.0-300));
    myFont.drawString(ofToString(r2), int(ofGetWidth()/2.0+300-100), int(ofGetHeight()/2.0-300));

}
```

```ofApp.h
#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();
    
    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
		
    ofTrueTypeFont myFont;
};
```

## 動画
[https://www.youtube.com/watch?v=zQOaKefk7nE](https://www.youtube.com/watch?v=zQOaKefk7nE)