UDP で温度と湿度を Harvest に送る

![IMG_20210808_094508.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d9235ada-7baf-f4c4-067f-15af37fd6f82.jpeg)


ソースファイルは4つに分割しました。

フォルダー構造

```text
$ tree harvest_temperature/
harvest_temperature/
├── harvest_temperature.ino
├── setupLTE.ino
├── temperature.ino
└── udp.ino
```

Arduino IDE で見た場合
![ide_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/2b236acf-4be5-4001-ef22-dca7e35db9d0.png)

メインプログラム

```text:harvest_temperature.ino
// ---------------------------------------------------------------
/*
	harvest_temperature.ino

					Aug/09/2021
*/
// ---------------------------------------------------------------
#include <WioLTEforArduino.h>
#include <ArduinoJson.h>
#include <stdio.h>

// #define INTERVAL	(600000)
#define INTERVAL  (60000)

#define RECEIVE_TIMEOUT (10000)
#define SENSOR_PIN    (WIOLTE_D38)

WioLTE Wio;
DynamicJsonDocument doc(1024);
int TemperatureAndHumidityPin;
int count = 0;

// ---------------------------------------------------------------
void setup() {
	setupLTE();

	TemperatureAndHumidityBegin(SENSOR_PIN);

	SerialUSB.println("### Setup completed. *** Aug/09/2021 AM 09:55");
}

// ---------------------------------------------------------------
void loop() {
	char data_json[128];
	float temp;
	float humi;

	SerialUSB.println("*** loop *** aaa *** count = " + String(count));

	if (!TemperatureAndHumidityRead(&temp, &humi))
		{
		SerialUSB.println("ERROR! *** TemperatureAndHumidityRead");
		}
	else
		{
		SerialUSB.print("Current humidity = ");
		SerialUSB.print(humi);
		SerialUSB.print("%	");
		SerialUSB.print("temperature = ");
		SerialUSB.print(temp);
		SerialUSB.println("C");
		}

	doc["temp"] = temp;
	doc["humi"] = humi;

	serializeJson(doc, data_json);

	int connectId = udp_open_proc("harvest.soracom.io", 8514);

	if (0 <= connectId)
		{
		boolean result = udp_send_proc(connectId,data_json);

		if (result)
			{
			result = udp_receive_proc(connectId);
			}
		}

	udp_close_proc(connectId);
	
	Wio.LedSetRGB(0, 0, 1); 
	delay(INTERVAL / 4);
	Wio.LedSetRGB(0, 1, 0); 
	delay(INTERVAL / 4);
	Wio.LedSetRGB(1, 1, 1); 
	delay(INTERVAL / 4);
	Wio.LedSetRGB(0, 0, 0); 
	delay(INTERVAL / 4);

	count++;
}

// ---------------------------------------------------------------
```

LTE関連のセットアップ

```text:setupLTE.ino
// ---------------------------------------------------------------
/*
	setupLTE.ino

					Aug/09/2021
*/
// ---------------------------------------------------------------
#define APN               "soracom.io"
#define USERNAME          "sora"
#define PASSWORD          "sora"

// ---------------------------------------------------------------
void setupLTE() {
	delay(200);

	SerialUSB.println("");
	SerialUSB.println("*** START *** seupLTE ***");

	SerialUSB.println("### I/O Initialize.");
	Wio.Init();

	SerialUSB.println("### Power supply ON.");
	Wio.PowerSupplyLTE(true);
	delay(500);

	SerialUSB.println("### Turn on or reset.");
	if (!Wio.TurnOnOrReset()) {
		SerialUSB.println("### ERROR! TurnOnOrReset ###");
	return;
	}

	SerialUSB.println("*** Connecting to \"soracom.io\" ***");
	if (!Wio.Activate(APN, USERNAME, PASSWORD))
		{
		SerialUSB.println("### ERROR! Activate ###");
		}
	else
		{
		SerialUSB.println("*** SetupLTE completed ***");
		}
}

// ---------------------------------------------------------------
```

温度と湿度の測定

```text:temperature.ino
// ---------------------------------------------------------------
/*
	temperature.ino

					Aug/07/2021
*/
// ---------------------------------------------------------------
// #include <stdio.h>

// ---------------------------------------------------------------
void TemperatureAndHumidityBegin(int pin)
{
	TemperatureAndHumidityPin = pin;
	DHT11Init(TemperatureAndHumidityPin);
}

// ---------------------------------------------------------------
bool TemperatureAndHumidityRead(float* temperature, float* humidity)
{
	byte data[5];
	
	DHT11Start(TemperatureAndHumidityPin);
	for (int i = 0; i < 5; i++) data[i] = DHT11ReadByte(TemperatureAndHumidityPin);
	DHT11Finish(TemperatureAndHumidityPin);
	
	if(!DHT11Check(data, sizeof (data))) return false;
	if (data[1] >= 10) return false;
	if (data[3] >= 10) return false;

	*humidity = (float)data[0] + (float)data[1] / 10.0f;
	*temperature = (float)data[2] + (float)data[3] / 10.0f;

	return true;
}

// ---------------------------------------------------------------
void DHT11Init(int pin)
{
	digitalWrite(pin, HIGH);
	pinMode(pin, OUTPUT);
}

// ---------------------------------------------------------------
void DHT11Start(int pin)
{
	// Host the start of signal
	digitalWrite(pin, LOW);
	delay(18);
	
	// Pulled up to wait for
	pinMode(pin, INPUT);
	while (!digitalRead(pin)) ;
	
	// Response signal
	while (digitalRead(pin)) ;
	
	// Pulled ready to output
	while (!digitalRead(pin)) ;
}

// ---------------------------------------------------------------
byte DHT11ReadByte(int pin)
{
	byte data = 0;
	
	for (int i = 0; i < 8; i++) {
		while (digitalRead(pin)) ;

		while (!digitalRead(pin)) ;
		unsigned long start = micros();

		while (digitalRead(pin)) ;
		unsigned long finish = micros();

		if ((unsigned long)(finish - start) > 50) data |= 1 << (7 - i);
	}
	
	return data;
}

// ---------------------------------------------------------------
void DHT11Finish(int pin)
{
	// Releases the bus
	while (!digitalRead(pin)) ;
	digitalWrite(pin, HIGH);
	pinMode(pin, OUTPUT);
}

// ---------------------------------------------------------------
bool DHT11Check(const byte* data, int dataSize)
{
	if (dataSize != 5) return false;

	byte sum = 0;
	for (int i = 0; i < dataSize - 1; i++) {
		sum += data[i];
	}

	return data[dataSize - 1] == sum;
}

// ---------------------------------------------------------------
```

udp 関連


```text:udp.ino
// ---------------------------------------------------------------
/*
	udp.ino

					Aug/07/2021
*/
// ---------------------------------------------------------------
int udp_open_proc(char url[],int port)
{
//	SerialUSB.println("### Open.");
	int connectId;
	connectId = Wio.SocketOpen(url, port, WIOLTE_UDP);
	if (connectId < 0) {
		SerialUSB.println("### ERROR! SocketOpen ###");
	}

	return connectId;
}

// ---------------------------------------------------------------
void udp_close_proc(int connectId){
//	SerialUSB.println("### Close.");
	if (!Wio.SocketClose(connectId)) {
		SerialUSB.println("### ERROR! SocketClose ###");
	}

}

// ---------------------------------------------------------------
boolean udp_send_proc(int connectId,char data_json[]){
//	SerialUSB.println("### Send.");
	SerialUSB.print("Send:");
	SerialUSB.print(data_json);
	SerialUSB.println("");
	boolean result = Wio.SocketSend(connectId, data_json);
	if (!result){
		SerialUSB.println("### ERROR! SocketSend ###");
	}
	return result;
}

// ---------------------------------------------------------------
boolean udp_receive_proc(int connectId){
		char data_rec[128];

	boolean result = true;
	
//	SerialUSB.println("### Receive.");
	int length;
	length = Wio.SocketReceive(connectId, data_rec, sizeof (data_rec), RECEIVE_TIMEOUT);
	if (length < 0) {
		SerialUSB.println("### ERROR! SocketReceive ###");
		result = false;
	}
	else if (length == 0) {
		SerialUSB.println("### RECEIVE TIMEOUT! ###");
		result = false;
	}
	else {
	SerialUSB.print("Receive:");
	SerialUSB.print(data_rec);
	SerialUSB.println("");

	return result;
	}
}

// ---------------------------------------------------------------
```

Harvest でデータの確認
![harvest_aug08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/97c92224-81d1-3d3e-c30e-fae34f5c56f7.png)