M5stackをIoT端末として使うときにサーバー(この場合はラズパイ)にメッセージを送る必要がありますが、Wi-Fiが一番汎用性がありそう。
というわけで、UDP使ってメッセージを送ってみます。ラズパイ側はサーバーにNode.js使うので同じくNode.jsスタイルで記述します。
<M5stack側>
NTPサーバー使って現在時刻の取得、mDNS機能を使ってラズパイのアドレスを検索しています。参考サイトは、以下の通りです。
・タイムサーバーの使い方
https://kuracux.hatenablog.jp/entry/2018/10/08/160000
・IPアドレスを4オクテット記法に変換する
https://qiita.com/dojyorin/items/ac56a1c2c620782d90a6
#include <m5stack.h>
#include <WiFi.h>
#include <wifiudp.h>
#include <espmdns.h>
// Wi-Fi connection info.
const char* ssid = "your said";
const char* password = "your pw";
const int port = 3002;
String string_buf = "message from M5stack";
//ntp server and time info
const char* ntpServer = "ntp.nict.jp";
const long gmtOffset_sec = 9 * 3600;
const int daylightOffset_sec = 0;
struct tm timeinfo;
// The udp library class
WiFiUDP udp;
// mDNS target & M5stack
const String target_dev = "raspberrypi";
IPAddress ip; // IPAdress of the target device
String ip_addr = ""; // 4 octet style target address
const char *mdns_name = "m5stick"; //M5stack mDNS name
// convert IP address to 4 octet style
String ipToString(uint32_t ip){
String result = "";
result += String((ip & 0xFF), 10); // base number : 10
result += ".";
result += String((ip & 0xFF00) >> 8, 10);
result += ".";
result += String((ip & 0xFF0000) >> 16, 10);
result += ".";
result += String((ip & 0xFF000000) >> 24, 10);
return result;
}
void mdns(){
mdns_init();
ip = MDNS.queryHost(target_dev);
// target dev IP
Serial.println("");
Serial.print(target_dev + " : ");
Serial.println(ip);
// M5 self IP
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
ip_addr = ipToString(ip);
// register mDNS name
if (MDNS.begin(mdns_name)) {
Serial.println("MDNS responder started");
}
}
void print_wifi_state(){
M5.Lcd.clear(BLACK); // clear LCD
M5.Lcd.setTextColor(YELLOW);
M5.Lcd.setCursor(3, 3);
M5.Lcd.println("");
M5.Lcd.println("WiFi connected.");
M5.Lcd.print("IP address: ");
M5.Lcd.println(WiFi.localIP());
M5.Lcd.print("Port: ");
M5.Lcd.println(port);
}
void setup_wifi(){
M5.Lcd.setTextColor(RED);
M5.Lcd.setTextSize(2);
M5.Lcd.setCursor(3, 10);
M5.Lcd.print("Connecting to ");
M5.Lcd.println(ssid);
// setup wifi
WiFi.mode(WIFI_STA); // WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF
WiFi.begin(ssid, password);
// WiFi.begin();
// Connecting ..
while (WiFi.status() != WL_CONNECTED) {
delay(100);
M5.Lcd.print(".");
}
// print state
print_wifi_state();
udp.begin(port);
// mDNS
mdns();
}
void setup() {
M5.begin();
Serial.begin(115200);
// setup wifi
setup_wifi();
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}
void loop(){
// get current rime
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
String cur_time = String(timeinfo.tm_year + 1900)
+ "/" + String(timeinfo.tm_mon)
+ "/" + String(timeinfo.tm_mday)
+ " " + String(timeinfo.tm_hour)
+ ":" + String(timeinfo.tm_min)
+ " " + String(timeinfo.tm_sec) + " ";
Serial.println(cur_time);
//udp send
const char *ipadr = ip_addr.c_str();
udp.beginPacket(ipadr, port);
// current time
int i = 0;
while( cur_time.length() > i){
char tmp = cur_time.charAt(i);
udp.write(tmp);
i++;
}
// contents
i = 0;
while( string_buf.length() > i){
char tmp = string_buf.charAt(i);
udp.write(tmp);
i++;
}
udp.endPacket();
delay(1000);
}
<ラズパイ側>
Node.js配下のスクリプトです。
const dgram = require('dgram');
const port = 3002;
const client ='0.0.0.0';
const socket = dgram.createSocket('udp4');
socket.bind(port, client);
socket.on('message', (message, remote) => {
console.log(remote.address + ':' + remote.port +' - ' + message);
});
参考サイトは、
・ラズパイのavahiユティリティのインストールと使い方
$ sudo apt-get install avahi-utils
Wi-Fi内のデバイスリスト
$ avahi-browse -at
・Node.jsのUDP通信ドキュメント
https://runebook.dev/ja/docs/node/dgram
・what’s socket.io
ラズパイ側の出力、
admin