GWなのに、あいかわらず工作活動してるなぁ
はじめに
- M5Stackのminiscalesで重さを量ってみた。
- それだけだと、ネタとしては薄すぎるから、量った重さをlineに飛ばしてみた。
重さを量る
- こんなコードで量れる。公式のサンプルスケッチは、こちら。
#include <M5Unified.h>
#include "UNIT_SCALES.h"
UNIT_SCALES scales;
void setup() {
M5.begin();
M5.Lcd.setRotation(2);
M5.Lcd.setTextFont(&lgfxJapanGothic_36);
while (!scales.begin(&Wire, /*SDA*/ 2, /*SCL*/ 1, DEVICE_DEFAULT_ADDR)) {
Serial.println("scales connect error");
M5.Lcd.print("scales connect error");
delay(1000);
}
scales.setLEDColor(0x001000);
M5.Lcd.clearDisplay();
}
float offset = 0;
void loop() {
float weight = scales.getWeight() - offset;
M5.Lcd.setCursor(10, 10);
M5.Lcd.println("重さ");
M5.Lcd.printf("%7.1f\n", weight);
M5.Lcd.print(" グラム");
M5.update();
if (M5.BtnA.wasPressed()) {
offset = scales.getWeight();
M5.Lcd.clearDisplay();
}
delay(500);
}
- コードの説明はするまでもないかな。getWeight()で重さを量るけど、ゼロ点補正のために変数offsetを設定して、scaleに何も載せてないときにボタンA(M5AtomS3の場合は、液晶画面)を押してoffset値を取得するようにした。
- こんな感じの表示になるけど、0.1g単位でブレブレだから、1g単位表示で使うのがいいみたい。最大重量5kgで1g単位の測定精度なら十分なのかな?最大重量500gにして0.1g単位の精度が出るモードも用意してくれればいいのに。
- この後、10分以上放置してたら、g単位でズレとった。量る直前にゼロリセット(液晶画面押下)をしないとならないね。
lineにnotifyする
- line notifyを使って飛ばした。
- アクセス用のトークンはここから取得する。今回、トークンの名称は「notify_test」とした。
- ちなみに、macosならターミナルでcurlコマンドを打ち込むだけで飛ばせる。下記の
[access_token]
を上記で取得したトークンに塗り替えて実行すると、lineに「hello」と通知される。トークンを塗り替えるときに、[ ]を消すのを忘れずに。
curl -X POST -H 'Authorization: Bearer [access_token]' -F 'message=hello' https://notify-api.line.me/api/notify
- M5AtomS3を使って飛ばすときは、こんな感じ。
#include <M5Unified.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
//設定
char* ssid = "****"; //wifiのssid
char* wfpw = "****"; //wifiのパスワード
char* host = "notify-api.line.me"; //line_notifyのapiサーバアドレス
char* post = "/api/notify"; //line_notifyのpost先
char* token = "****"; //line_notifyのトークン
char* type = "application/x-www-form-urlencoded"; //HTMLのデフォルトのフォームの送信形式
void setup() {
M5.begin();
WiFi.begin(ssid, wfpw);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.print("\nwifi接続成功!");
M5.Lcd.setFont(&lgfxJapanGothic_24);
M5.Lcd.print("押したら\n通知!");
}
void send_msg(char* msg) {
// httpsアクセス用イニシャライザ
WiFiClientSecure client;
client.setInsecure();//サーバー証明書不要
//SSL接続(443)
if (!client.connect(host, 443)) {
Serial.println("apiサーバ接続失敗");
return;
}
Serial.println("apiサーバ接続成功");
//notify_apiへポスト
String query = String("message=") + String(msg);
String request = String("")
+ "POST " + post + " HTTP/1.1\r\n"
+ "Host: " + host + "\r\n" + "Authorization: Bearer " + token + "\r\n"
+ "Content-Length: " + String(query.length()) + "\r\n"
+ "Content-Type: " + type + "\r\n\r\n" + query + "\r\n";
client.print(request);
}
void loop() {
M5.update();
if (M5.BtnA.wasPressed()) {
char* msg = "notifyテスト";
send_msg(msg);
}
delay(10);
}
重さを量ったらlineに飛ばす
重さを量るとlineにnotifyするを合体させる。
#include <M5Unified.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "UNIT_SCALES.h"
UNIT_SCALES scales;
//設定
char* ssid = "****"; //wifiのssid
char* wfpw = "****"; //wifiのパスワード
char* host = "notify-api.line.me"; //line_notifyのapiサーバアドレス
char* post = "/api/notify"; //line_notifyのpost先
char* token = "****"; //line_notifyのトークン
char* type = "application/x-www-form-urlencoded"; //HTMLのデフォルトのフォームの送信形式
void setup() {
M5.begin();
WiFi.begin(ssid, wfpw);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nwifi接続成功!");
M5.Lcd.setRotation(2);
M5.Lcd.setFont(&lgfxJapanGothic_16);
M5.Lcd.setTextSize(2);
while (!scales.begin(&Wire, /*SDA*/ 2, /*SCL*/ 1, DEVICE_DEFAULT_ADDR)) {
Serial.println("scales connect error");
M5.Lcd.print("scales connect error");
delay(1000);
}
scales.setLEDColor(0x001000);
M5.Lcd.clearDisplay();
}
void send_msg(char* msg) {
//httpsアクセス用イニシャライザ
WiFiClientSecure client;
client.setInsecure();//サーバー証明書不要
//SSL接続(443)
if (!client.connect(host, 443)) {
Serial.println("apiサーバ接続失敗");
return;
}
Serial.println("apiサーバ接続成功");
//notify_apiへポスト
String query = String("message=") + String(msg);
String request = String("")
+ "POST " + post + " HTTP/1.1\r\n"
+ "Host: " + host + "\r\n" + "Authorization: Bearer " + token + "\r\n"
+ "Content-Length: " + String(query.length()) + "\r\n"
+ "Content-Type: " + type + "\r\n\r\n" + query + "\r\n";
client.print(request);
}
float offset = 0;
float oldWt = 0;
float sendWt = 0;
void loop() {
float weight = scales.getWeight() - offset;
M5.Lcd.setCursor(10, 10);
M5.Lcd.println("重さ");
M5.Lcd.printf("%7.1f\n", weight);
M5.Lcd.print(" グラム");
if (fabs(oldWt - weight) > 10) {
delay(2000);
weight = scales.getWeight() - offset;
oldWt = weight;
if (weight > 50.0) {
char wt[32];
sprintf(wt, "重さ%.0fグラム", weight);
char* msg = wt;
send_msg(msg);
}
}
M5.update();
if (M5.BtnA.wasPressed()) {
offset = scales.getWeight();
oldWt = 0;
M5.Lcd.clearDisplay();
}
delay(500);
}
- 合体する際、プログラムは若干変えている。
- 具体的に言えば、重さの変動が10g超発生したとき、自動的にlineにnotifyすることとした。ただし、変動後の重さが50g超のときのみに限定している。
- 次の写真は、iphone_se3の重さを量った結果。
最後に
- 初めてline_notifyのapiを利用してみたけど、apple watchと連動させると色々と便利な使い道が見つかりそう。でも、普段、iphoneを持ち歩かないからなぁ。