M5StickVでAzureに接続する

[TOPPERS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/toppers) 9日目の記事です。

# はじめに

[M5Stack Advent Calendar 2020](https://qiita.com/advent-calendar/2020/m5stack) 8日目の記事 [M5StickVとM5StackをつなげてWiFi通信する](https://qiita.com/fukuebiz/items/cc4fe4734e9eac6ae2bc) で、M5StickVとM5Stackを接続してWiFi接続できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/85872015-955c-8f2e-1fca-f280b519b7ed.png)

MaixAmigoやMaixCubeでも。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/61c590a0-75e0-18a0-c363-86d033d3eda8.png)

同じタイミングで @h7ga40 さんが [TOPPERS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/toppers) 7日目に [TOPPERS BASE PLATFORMを改造してESP32をATコマンドで使ってみる](https://qiita.com/h7ga40/items/a83f99653bbd1f850b27) の記事を投稿されていますので、M5StickVとM5Stackを繋げた環境でも試してみたいと思います。

# Azure IoT

これまでAWSを中心に使ってきたので、Azureはちょっと勝手が違います。ドキュメント [Azure Portal を使用して IoT Hub を作成する](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-create-through-portal) を読みながら IoT Hub を作成します。「サブスクリプション」とか「リソースグループ」という言葉が出てきて、一つずつ確認しながら進めました。

IoT Hub を作成したら、次はその IoT Hub にデバイスを登録します。登録には [TOPPERS BASE PLATFORMを改造してESP32をATコマンドで使ってみる](https://qiita.com/h7ga40/items/a83f99653bbd1f850b27) の記事では対称キーを使用してるようですので、対称キーで作成します。

TOPPERSから接続する時にこの接続文字列を使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/61dba23d-ee50-98d3-cfd6-3e041fde902a.png)

# デバイスによる違い

デバイスによってシリアル通信するピンが変わります。

| デバイス | RX | TX | LED R | LED G | LED B |
|---------|----|----|----|----|----|
| M5StickV | 35 | 34 | 6 | 9 | 8 |
| MaixAmigo | 7 | 9 | 14 | 15 | 17 |
| MaixCube | 25 | 24 | 13 | 12 | 14 |

ここに記載されています。

シリアル通信: target_serial.c
LED: kpu_main.h

esp_at_socket.cも一部修正しています。AT+CIPSEND の後でエラーになっていたのでコメントにしました。

```c:esp_at_socket.c
int esp_at_socket_send(ESP_AT_SOCKET_HANDLE espAtSocketHandle, const char *data, int length)
{
	at_connection_t *connection = (at_connection_t *)espAtSocketHandle;
	at_response_kind_t res_kind;

	if (connection->state != connection_state_connected) {
		printf("esp_at_socket_send state error %d\n", connection->state);
		return -MU_FAILURE;
	}

	ER ret;
	char temp[64];
	sprintf_s(temp, sizeof(temp), "AT+CIPSEND=%d,%d\r\n", connection->link_id, length);
	ret = esp_serial_write(connection->esp_state, temp, &res_kind, 10000);
/* CIPSEND の後に OKが返らない
	if ((ret != E_OK) || (res_kind != at_response_kind_ok)) {
		printf("send error command %s %d\n", itron_strerror(ret), res_kind);
		return -MU_FAILURE;
	}
	do {
		ret = esp_serial_read(connection->esp_state, &res_kind, 10000);
		if ((ret != E_OK) || ((res_kind != at_response_kind_ok)
			&& (res_kind != at_response_kind_progress))) {
			printf("send error progress %s %d\n", itron_strerror(ret), res_kind);
			return -MU_FAILURE;
		}
	} while(res_kind == at_response_kind_ok);
*/
	if ((ret != E_OK) || (res_kind != at_response_kind_progress)) {
		printf("send error command %s %d\n", itron_strerror(ret), res_kind);
		return -MU_FAILURE;
	}
	ret = serial_wri_dat(AT_PORTID, data, length);
	if (ret < 0) {
		printf("send error write data %s\n", itron_strerror(ret));
		return -MU_FAILURE;
	}
	do {
		ret = esp_serial_read(connection->esp_state, &res_kind, 60000);
		if (ret != E_OK) {
			printf("send error done %s\n", itron_strerror(ret));
			break;
		}
		if (res_kind == at_response_kind_send_ok)
			return length;
	} while ((res_kind == at_response_kind_no_set)
		|| (res_kind == at_response_kind_ok));

	printf("send error done kind=%d\n", res_kind);

	return -MU_FAILURE;
}

```

オリジナルではK210のKPUを使って人、車を分類してから送信してますが、今回はAzureに繋ぐところの確認だけできればと思い、その処理はスキップさせてテストしました。

# IoT Hubへ接続

httpで接続してみます。

```
mon>device WIFI <ssid> <pass>

mon>device setcs 接続文字列

mon>device iot http
Starting the IoTHub client sample HTTP...
Error: Time:Sat Dec 12 15:41:19 2020 File:../../azure_iot_sdk/iothub_client/src/iothubtransporthttp.c Func:IoTHubTransportHttp_Subscribe_DeviceTwin Line:1189 IoTHubTransportHttp_Subscribe_DeviceTwin Not supported
Error: Time:Sat Dec 12 15:41:19 2020 File:../../asp_baseplatform/../azure_iot_sdk/serializer/inc/serializer_devicetwin.h Func:Generic_IoTHubClient_SetCallbacks Line:202 failure in IoTHubClient_LL_SetDeviceTwinCallback
Error: Time:Sat Dec 12 15:41:19 2020 File:../../asp_baseplatform/../azure_iot_sdk/serializer/inc/serializer_devicetwin.h Func:IoTHubDeviceTwinCreate_Impl Line:261 failure in Generic_IoTHubClient_SetCallbacks
Failure in IoTHubDeviceTwin_LL_CreateSecurityCameraStateError: Time:Sat Dec 12 15:41:19 2020 File:../../azure_iot_sdk/c-utility/src/vector.c Func:VECTOR_find_if Line:292 invalid argument - handle(0), pred(80042bda)
Error: Time:Sat Dec 12 15:41:19 2020 File:../../azure_iot_sdk/serializer/src/schema.c Func:Schema_GetSchemaForModel Line:3230 unable to find a schema that has a model named SecurityCameraSettings
Error: Time:Sat Dec 12 15:41:19 2020 File:../../asp_baseplatform/../azure_iot_sdk/serializer/inc/serializer_devicetwin.h Func:IoTHubDeviceTwinCreate_Impl Line:232 failure in Schema_GetSchemaForModel.
Failure in IoTHubDeviceTwin_LL_CreateSecurityCameraSettingsError: Time:Sat Dec 12 15:41:19 2020 File:../../azure_iot_sdk/iothub_client/src/iothubtransporthttp.c Func:IoTHubTransportHttp_Subscribe_DeviceMethod Line:1214 not implemented (yet)
Error: Time:Sat Dec 12 15:41:19 2020 File:../../azure_iot_sdk/iothub_client/src/iothub_client_core_ll.c Func:IoTHubClientCore_LL_SetDeviceMethodCallback Line:2601 IoTHubTransport_Subscribe_DeviceMethod failed
ERROR: IoTHubClient_LL_SetDeviceMethodCallback..........FAILED!
IoTHubClient_LL_SetMessageCallback...successful.
IoTHubClient_LL_SendEventAsync accepted message [0] for transmission to IoT Hub.
Confirmation[0] received for message tracking id = 0 with result = IOTHUB_CLIENT_CONFIRMATION_OK
IoTHubClient_LL_SendEventAsync accepted message [1] for transmission to IoT Hub.
Confirmation[1] received for message tracking id = 1 with result = IOTHUB_CLIENT_CONFIRMATION_OK
IoTHubClient_LL_SendEventAsync accepted message [2] for transmission to IoT Hub.


```

エラーも出ていますが、接続はできている模様。

# まとめ

TOPPERSでIoTに一歩近づきました。

@h7ga40 さんありがとうございます。