AWS IoTでGO! - 電車でGo!コントローラとArduino YúnとAWS IoT

# はじめに

アマゾンウェブサービスジャパンの瀧澤です。
**この記事は、2016/2/16 [「JAWS-UG IoT専門支部 IoTサロン 2016-02」](http://jawsug-iot.connpass.com/event/19969/)でお話しした内容の補足です。**
コードは発表資料に含まれていないので、この投稿の内容を参照してください。

# 発表資料

下記の資料をご確認ください。
![densyago.png](https://qiita-image-store.s3.amazonaws.com/0/61619/19319a31-1cf2-21dc-37a8-72b5533db300.png)

SlideShare: http://www.slideshare.net/YoichiTakizawa/aws-iotgo


# 実現したこと

* 電車でGO!コントローラのコントローラの角度を読み取り、arduino Yunに入力。
* arduino Yunにモーターシールドを接続し、Nゲージの車両の速度を制御可能に。
* arduino Yunは、MQTTで、AWS IoTに車両の速度データを送信。
* AWS Iotで受け取ったデータは、Amazon S3にデータを保管したり、SNS, Lambda経由で、CloudWatch Logsにデータを保管したり。
* うちの子供がよろこんだ。

# 構成図

![traincontrollerAWSIoT.png](https://qiita-image-store.s3.amazonaws.com/0/61619/1be15351-7073-8593-1e35-d8872584ac24.png)


# コード

```lang:traincontroller-AWSIoT
/*
 * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/* 
 * This source code modified by Yoichi Takizawa. 
 */

#include <aws_iot_mqtt.h>
#include <aws_iot_version.h>
#include "aws_iot_config.h"

aws_iot_mqtt_client myClient; // init iot_mqtt_client
char msg[32]; // read-write buffer
int cnt = 0; // loop counts
int rc = -100; // return value placeholder
bool success_connect = false; // whether it is connected


//Arduino PWM Speed Control：
int E1 = 5;  
int M1 = 4; 
int E2 = 6;                      
int M2 = 7;

int pushButton1 = 11;
int pushButton2 = 12;
int pushButton3 = 13;

int speedvalue = 0;
int dirvalue = HIGH;

int speedvalue2 = 0;
int dirvalue2 = HIGH;




// Basic callback function that prints out the message
void msg_callback(char* src, int len) {
  Serial.println("CALLBACK:");
  int i;
  for(i = 0; i < len; i++) {
    Serial.print(src[i]);
  }
  Serial.println("");
}

void setup() {
  // Start Serial for print-out and wait until it's ready
  Serial.begin(115200);
  while(!Serial);
  //
  char curr_version[80];
  sprintf(curr_version, "AWS IoT SDK Version(dev) %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
  Serial.println(curr_version);
  // Set up the client
  if((rc = myClient.setup(AWS_IOT_CLIENT_ID)) == 0) {
    // Load user configuration
    if((rc = myClient.config(AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT, AWS_IOT_ROOT_CA_PATH, AWS_IOT_PRIVATE_KEY_PATH, AWS_IOT_CERTIFICATE_PATH)) == 0) {
      // Use default connect: 60 sec for keepalive
      if((rc = myClient.connect()) == 0) {
        success_connect = true;
        // Subscribe to "topic1"
        if((rc = myClient.subscribe("topic1", 1, msg_callback)) != 0) {
          Serial.println("Subscribe failed!");
          Serial.println(rc);
        }
      }
      else {
        Serial.println("Connect failed!");
        Serial.println(rc);
      }
    }
    else {
      Serial.println("Config failed!");
      Serial.println(rc);
    }
  }
  else {
    Serial.println("Setup failed!");
    Serial.println(rc);
  }
  // Delay to make sure SUBACK is received, delay time could vary according to the server
  delay(2000);

  pinMode(M1, OUTPUT);   
  pinMode(M2, OUTPUT);
  pinMode(pushButton1, INPUT);
  pinMode(pushButton2, INPUT);
  pinMode(pushButton3, INPUT);
}

void loop() {
  
  int speedcommand;
  int controller_speed;

  int buttonState1 = digitalRead(pushButton1);
  int buttonState2 = digitalRead(pushButton2);
  int buttonState3 = digitalRead(pushButton3);

  controller_speed = buttonState1 * 4 + buttonState2 * 2 + buttonState3 -1;
  speedvalue2 = controller_speed * 255 / 5;

  // Serial.println(controller_speed);

  digitalWrite(M1, dirvalue);    // Direction         
  analogWrite(E1, speedvalue2);   // PWM Speed Control

  digitalWrite(M2, dirvalue2);    // Direction         
  analogWrite(E2, speedvalue2);   // PWM Speed Control
  
  if(success_connect) {
    // Generate a new message in each loop and publish to "topic1"
    sprintf(msg, "train speed %d", speedvalue2);
    if((rc = myClient.publish("topic1", msg, strlen(msg), 1, false)) != 0) {
      Serial.println("Publish failed!");
      Serial.println(rc);
    }
  
    // Get a chance to run a callback
    if((rc = myClient.yield()) != 0) {
      Serial.println("Yield failed!");
      Serial.println(rc);
    }
  
    // Done with the current loop
    sprintf(msg, "loop %d done", cnt++);
    Serial.println(msg);
  
    delay(2000);
  }
}
```

```lang:aws_iot_config.h
/*
 * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/* 
 * This source code modified by Yoichi Takizawa. 
 */

#ifndef config_usr_h
#define config_usr_h

// Copy and paste your configuration into this file
//===============================================================
#define AWS_IOT_MQTT_HOST "A3TCNQTE8Bxxxx.iot.ap-northeast-1.amazonaws.com"
// your endpoint
#define AWS_IOT_MQTT_PORT 8883
// your port
#define AWS_IOT_CLIENT_ID      "traincontroller"
// your client ID
#define AWS_IOT_MY_THING_NAME "traincontroller"
// your thing name
#define AWS_IOT_ROOT_CA_FILENAME "root-CA.crt"
// your root-CA filename
#define AWS_IOT_CERTIFICATE_FILENAME "5fa69bxxxx-certificate.pem.crt"
// your certificate filename
#define AWS_IOT_PRIVATE_KEY_FILENAME "5fa69bxxxx-private.pem.key"
// your private key filename
//===============================================================
// SDK config, DO NOT modify it
#define AWS_IOT_PATH_PREFIX "../certs/"
#define AWS_IOT_ROOT_CA_PATH AWS_IOT_PATH_PREFIX AWS_IOT_ROOT_CA_FILENAME			// use this in config call
#define AWS_IOT_CERTIFICATE_PATH AWS_IOT_PATH_PREFIX AWS_IOT_CERTIFICATE_FILENAME	// use this in config call
#define AWS_IOT_PRIVATE_KEY_PATH AWS_IOT_PATH_PREFIX AWS_IOT_PRIVATE_KEY_FILENAME	// use this in config call

#endif
```

# 免責

ハードウェアの分解や解析を行うことを勧める記事ではありません。自己の責任で解釈をお願いします。また、こちらは個人の意見で、所属する企業や団体は関係ありません。