IOT体重計の製作(クラウド編)

M5STACK

体重測定値をクラウドに保存する方法としてgoogle スプレッドシートを使用しました。スプレッドシートであればデータのグラフ化などの加工も容易に行えます。測定値をスプレッドシートに書き込むためには、①測定値を受け取る側のスプレッドシートでのGoogle Apps Script(GAS)の作成と②測定値を送る側のM5stickCでのプログラムの作成作業が必要です。M5StickCで取得した体重をJsonデータとしてhttpPOSTしGAS側で受信するスクリプトとしました。

【スプレッドシートでのGoogle Apps Scriptの設計手順】
Google Driveで新規スプレッドシートを作成し、そこにM5STICKCから飛んできたデータをシートに書き込んでいくスクリプトを記載します。
1.マイドライブで右クリックー>新規作成ー>Google Sheets

2.初めて使用する場合、アカウント情報の入力を求められた場合は入力します。

3.無題のスプレッドシートが出来上がります。

4.メニューから拡張機能ー>Apps Scriptを選択する。

5.次に、この画面になりますのでスクリプトを作成していきましょう。

6.今回の体重を記録する例として以下を記載しました。

function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  // 送信されてくるJSONデータ {"ID":XXXX,"weight":XXXXX} から、各要素を取り出す
  var postdata = JSON.parse(e.postData.getDataAsString());
  var id = postdata.ID;
  var weight = postdata.weight;
  // データをシートに追加
  sheet.insertRows(2,1);  // 2行1列目に列を挿入する
  sheet.getRange(2, 1).setValue(new Date());     // 受信日時を記録
  sheet.getRange(2, 2).setValue(id);     // IDを記録
  sheet.getRange(2, 3).setValue(weight);     // tempを記録
}

7.実際の画面はこのような感じです。

8.右上のデプロイ ー>新しいデプロイをクリック。

9.歯車マークをクリック ー>ウェブアプリ

10.説明はそのままでも何か入力してもどちらでも良いです。アクセスできるユーザーを全員にしたあとに、デプロイをクリックします。

11.アクセスを承認を押します。

12.google アカウントで承認します。

13.下記のような注意画面が出ますが驚かずに左下のAdvancedをクリックします。

14.次に以下の画面になりますので、左下のgo to *** (unsafe)をクリックします。

15.次の画面の右下Allowをクリックします。なお、日本語に設定している場合は、「許可」と出ています。

16.「デプロイを更新しています…」の画面になります。

17.完了すると次の画面になりますので、ウェッブアプリのURLを「コピー」を押してコピーしておきます。このURLは送信側のM5stickでのプログラムで使用しますので、念のためにメモ帳などに転記して保存しておいたほうが良いかもしれません。その後右下の完了をクリックします。なお、URLは後でも見ることができるのでコピーを忘れても心配無いです。

以上、Google Spreadsheet側の設計は完了です。

【M5stickでのプログラムの設計手順】
「WiFiの接続」、「体重測定」、「JSONフォーマットをhttpClientでPOST」の3点の実装が必要となります。測定値をJSONフォーマットで形成しHTTP Clientでpostすることでスプレッドシートにデータを渡します。一例としてHX711のサンプルプログラムを改造すると以下のようにできます。

#include <M5GFX.h>
#include <M5StickC.h>
#include "HX711.h"
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h> //version 6.19.4
char *ssid = "*******";// WiFi SSIDを記載します。
char *password = "********";// WiFi パスワードを記載します。
const char* published_url = "https://script.google.com/macros/s/********/exec";  //GoogleスプレッドシートのデプロイされたURLを記載します。
M5GFX display;
M5Canvas canvas(&display);
// HX711 related pin Settings.  
#define LOADCELL_DOUT_PIN 33
#define LOADCELL_SCK_PIN  32
HX711 scale;
// WiFi接続
void setup_wifi(){
  Serial.println("Connecting to ");
  Serial.print(ssid);
  WiFi.disconnect();
  delay(500);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED){
  delay(500);
  }
  Serial.println("\nWiFi Connected.");
  canvas.drawString("WiFi Connected.", 80, 40);
  canvas.pushSprite(0, 0);
  delay(2000);
}

void setup() {
    M5.begin();  // M5StickC 初期化
    display.begin();
    display.setRotation(3);
    canvas.setColorDepth(1); 
    canvas.createSprite(display.width(), display.height());
    canvas.setTextDatum(MC_DATUM);
    canvas.setPaletteColor(1, GREEN);
    canvas.drawString("Calibration sensor....", 80, 40);
    canvas.pushSprite(0, 0);
    scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
    // The scale value is the adc value corresponding to 1g
    scale.set_scale(27.61f);  // set scale
    scale.tare();             // auto set offset
    setup_wifi();
}

char info[100];
void loop() {
    canvas.fillSprite(BLACK);
    canvas.setTextSize(1);
    canvas.drawString("<-Tare", 30, 20);
    canvas.drawString("Calibration", 80, 70);
    float weight = scale.get_units(10) / 1000.0;
    canvas.setTextSize(2);
    if (weight >= 0) {
        Serial.printf("%.2f", weight);
        sprintf(info, "%.2f", weight);
        canvas.drawString(String(info) + "kg", 80, 40);
    } else {
        canvas.drawString("0kg", 80, 40);
    }
    M5.update();
    if (M5.BtnB.wasPressed()) {
        scale.tare();
        canvas.drawString("0g Cal", 80, 70);
        delay(1000);
    }
    StaticJsonDocument<500> doc;
    char pubMessage[256];    
    if (M5.BtnA.wasPressed()) {
    canvas.fillSprite(BLACK);
    canvas.setTextSize(1);
    canvas.drawString("Sending...", 30, 20);
    canvas.pushSprite(0, 0);
      // JSONメッセージの作成
      JsonArray idValues = doc.createNestedArray("ID");
      idValues.add("name");//名前などのIDを記載します
      JsonArray dataValues = doc.createNestedArray("weight");
      dataValues.add(weight);
      serializeJson(doc, pubMessage);
      // HTTP通信の開始
      HTTPClient http;
      Serial.print(" HTTP通信開始 \n");
      http.begin(published_url);
      Serial.print(" HTTP通信POST \n");
      int httpCode = http.POST(pubMessage);
      if(httpCode > 0){
        canvas.drawString(" HTTP Response: "+String(httpCode) , 80, 90);   
        if(httpCode == HTTP_CODE_OK){
          canvas.drawString(" HTTP Success!!", 80, 100);
          String payload = http.getString();
          Serial.println(payload);
        }
      }else{
        canvas.drawString(" FAILED", 80, 100);  
        Serial.printf(" HTTP failed,error: %s\n", http.errorToString(httpCode).c_str());
      }
    http.end();
    }
    canvas.pushSprite(0, 0);
}

以上で、Aボタンを押すごとにスプレッドシートへのデータ書き込みができるようになりました。なお、BボタンにTARE(0補正)の機能を持たせていますので、このプログラム例では画面の表示と機能が一致していません。次回の記事で画面の表示内容の修正を行いたいと思います。

コメント

タイトルとURLをコピーしました