M5Stick-CからInfluxDBにUDPで温度データを入れる

##概要
M5Stick-Cに温度センサーのDS18B20を複数個ぶら下げて、拾ってきた数値をWiFiからUDPで送ってInfluxDBが動いているRaspberry Pi4にデータ記録してみました。
Raspberry Pi4,Arduino,M5Stick,influxdbのインストール作業や初期設定などは、↓のネタ元や、ネット等に情報あるので省略。

###インストール例
influxDB
https://pimylifeup.com/raspberry-pi-influxdb/
grafana
https://pimylifeup.com/raspberry-pi-grafana/

ネタ元
https://www.influxdata.com/blog/how-to-send-sensor-data-to-influxdb-from-an-arduino-uno/

![IMG_3828.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/c7473747-fd9a-5785-2859-7a0c2e5f83ba.png)
ケーブルの影になってますが、4.8kの抵抗使っています。ケーブルの色がアレなのは特に意図はありません。手短にあっただけです。

##必要なライブラリ等
今回はDS18B20（温度センサー）を使いましたので、OneWireライブラリが必要です。ライブラリマネージャからインストールしておいてください。

https://github.com/PaulStoffregen/OneWire

##M5Stick-CからInfluxDBにUDPでデータを入れる
GPIOはG26を使っています。変更する場合はdefine ONE_WIREの該当項目を変えてください。

##Influxdbの設定でUDPを有効にする

```/etc/influxdb/influxdb.conf 
[[udp]]
  # enabled = false
   enabled = true
   bind-address = ":8089"
   database = "test1"
```

influxdbを再起動

```bash
sudo service influxdb restart
```

###データベースを作る

```influx
$ influx
CREATE DATABASE test1
quit
```

##ソース
<details>
<summary>tempsensor_influx_ds18b20</summary>
<div>

```tempsensor_influx_ds18b20.ino

#include <OneWire.h>
#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#define ONE_WIRE 26

char ssid[] = "SSID";
const char* password = "WiFi_Password";
// the IP address of your InfluxDB host
byte host[] = {10, 0, 1, 15};

// the port that the InfluxDB UDP plugin is listening on
int port = 8089;

WiFiUDP udp;

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library
 
OneWire ds(ONE_WIRE); // on pin 10 (a 4.7K resistor is necessary)

void setup(void) {
    Serial.begin(9600);
    Serial.println("start");
    #ifdef ARDUINO_M5Stack_Core_ESP32
    M5.begin();
    #endif
    WiFi.begin(ssid, password); 
    while (WiFi.status() != WL_CONNECTED) { 
        delay(100);
        Serial.print(".");
    }
    Serial.println();

}
 
void loop(void) {

    byte i;
    byte present = 0;
    byte type_s;
    byte data[12];
    byte addr[8];
    float celsius;

    if ( !ds.search(addr)) {
         Serial.println(" ----- ");
         ds.reset_search();
         delay(250);
         return;
    }
 
    if (OneWire::crc8(addr, 7) != addr[7]) {
        Serial.println("CRC is not valid!");
        return;
    }
 
    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1); // start conversion, with parasite power on at the end
    delay(1000); // maybe 750ms is enough, maybe not
 // we might do a ds.depower() here, but the reset will take care of it.
  
    present = ds.reset();
    ds.select(addr); 
    ds.write(0xBE); // Read Scratchpad

    String address=String(addr[0],HEX)+String(addr[1],HEX)+String(addr[2],HEX)+String(addr[3],HEX)+String(addr[4],HEX)+String(addr[5],HEX);
        
    for ( i = 0; i < 9; i++) { // we need 9 bytes
         data[i] = ds.read();
    }
    int16_t raw = (data[1] << 8) | data[0];
     if (type_s) {
        raw = raw << 3; // 9 bit resolution default
        if (data[7] == 0x10) {
            // "count remain" gives full 12 bit resolution
           raw = (raw & 0xFFF0) + 12 - data[6];
        }
     } else {
         byte cfg = (data[4] & 0x60);
         // at lower res, the low bits are undefined, so let's zero them
         if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
         else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
         else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
         //// default is 12 bit resolution, 750 ms conversion time
    }
    celsius = (float)raw / 16.0;
    String cel;
    cel = String(celsius);
    String line;
    line="temp,device="+address+" value="+cel;
    Serial.println(line);
    Serial.println("Sending UDP packet...");
    udp.beginPacket(host, port);
    udp.print(line);
    udp.endPacket();
    delay(10000);
    }

```

</div>
</details>

##あとは煮るなり焼くなり
delayをdeepsleepにするなり、M5Stack.hを入れてあるので、液晶で表示するなりお好みで。

追記：DeepSleep
http://wakwak-koba.hatenadiary.jp/entry/20170219/p1
DS18B20を複数個付けている場合、deepsleepすると1個しか読まないので、deepsleepする前にloop関数を個数分の回数ループする必要があります。