Ubuntu 24.04 上の Arduino IDE 2.3.2 を使いました。
ボードは、 ESP32 Dev Module です。
必要なライブラリー
Arduinojson
PubSubClient
プログラム
config.h
// ---------------------------------------------------------------------
// common/config.h
//
// Feb/08/2023
// ---------------------------------------------------------------------
#define MQTT_SERVER_HOST "broker.emqx.io"
#define MQTT_SERVER_PORT 1883
const char *ssid = "*****";
const char *password = "*****";
#define LED1 32
#define LED2 33
#define LED3 25
#define LED4 26
#define LED5 27
#define LED6 14
#define LED7 12
#define LED8 13
int leds[8] = {LED1,LED2,LED3,LED4,LED5,LED6,LED7,LED8};
// ---------------------------------------------------------------------
mqtt_led.ino
// ---------------------------------------------------------------
// mqtt_led.ino
//
// Feb/08/2023
// ---------------------------------------------------------------
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "config.h"
#define PROGRAM "mqtt_led.ino"
#define VERSION "2023-2-8 PM 14:22"
WiFiClient espClient;
PubSubClient client(espClient);
#define TOPIC "M5Stack"
int icount = 0;
// ---------------------------------------------------------------
void setupWifi()
{
delay(10);
Serial.printf("Connecting to %s", ssid);
WiFi.mode( WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.printf("\r\nSuccess\r\n");
}
// ---------------------------------------------------------------
void msg_proc(String msg)
{
DynamicJsonDocument doc(1024);
deserializeJson(doc, msg);
if ((doc.containsKey("ledno")) && (doc.containsKey("status")))
{
const int ledno = doc["ledno"];
Serial.println(ledno);
const bool status = doc["status"];
Serial.println(status);
if (status)
{
digitalWrite(leds[ledno], HIGH);
}
else
{
digitalWrite(leds[ledno], LOW);
}
}
else
{
Serial.println("*** error *** lendo ***");
Serial.println("*** error *** status ***");
}
}
// ---------------------------------------------------------------
void callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
payload[length] = '\0';
String msg = String((char*) payload);
Serial.println(msg);
msg_proc(msg);
}
// ---------------------------------------------------------------
void reConnect()
{
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "M5Stack-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.printf("\r\nSuccess\r\n");
client.subscribe(TOPIC);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println("try again in 5 seconds");
delay(5000);
}
}
}
// ---------------------------------------------------------------
void setup()
{
Serial.begin(115200);
delay(3000);
Serial.println(PROGRAM);
Serial.println(VERSION);
Serial.println();
setupWifi();
client.setServer(MQTT_SERVER_HOST, 1883);
client.setCallback( callback);
for (int it=0; it<8; it++)
{
pinMode(leds[it], OUTPUT);
}
}
// ---------------------------------------------------------------
void loop()
{
if (!client.connected())
{
reConnect();
}
client.loop();
if ((icount % 100) == 0)
{
Serial.printf("*** loop *** %d ***\r\n",icount);
}
// delay(2000);
delay(100);
icount++;
}
// ---------------------------------------------------------------
テスト用スクリプト
go_publish.sh
#
HOST="broker.emqx.io"
TOPIC="M5Stack"
ARGS="-d -t orz -h ${HOST} --topic ${TOPIC}"
#
mosquitto_pub $ARGS -m '{"ledno": 0,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 0,"status": false}'
#
mosquitto_pub $ARGS -m '{"ledno": 1,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 1,"status": false}'
#
mosquitto_pub $ARGS -m '{"ledno": 2,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 2,"status": false}'
#
mosquitto_pub $ARGS -m '{"ledno": 3,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 3,"status": false}'
#
mosquitto_pub $ARGS -m '{"ledno": 4,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 4,"status": false}'
#
mosquitto_pub $ARGS -m '{"ledno": 5,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 5,"status": false}'
#
mosquitto_pub $ARGS -m '{"ledno": 6,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 6,"status": false}'
#
mosquitto_pub $ARGS -m '{"ledno": 7,"status": true}'
sleep 2
mosquitto_pub $ARGS -m '{"ledno": 7,"status": false}'
#
Python のテストプログラム
publish.py
#! /usr/bin/python
#
# publish.py
#
# Feb/08/2023
#
# ------------------------------------------------------------------
import sys
import json
from time import sleep
import paho.mqtt.client as mqtt
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
host = 'example.com'
port = 1883
topic = 'M5Stack'
client = mqtt.Client(protocol=mqtt.MQTTv311)
client.connect(host, port=port, keepalive=60)
for it in range(8):
unit_aa = {}
unit_aa["ledno"] = it
unit_aa["status"] = True
#
str_json = json.dumps(unit_aa)
client.publish(topic, str_json)
sleep(2.0)
#
unit_aa["status"] = False
str_json = json.dumps(unit_aa)
client.publish(topic, str_json)
#
client.disconnect()
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
Node.js のテストプログラム
publish.js
#! /usr/local/bin/node
// ---------------------------------------------------------------
// publish.js
//
// Feb/08/2023
// ---------------------------------------------------------------
'use strict'
require('date-utils')
var mqtt = require('mqtt')
var count = 0
// ---------------------------------------------------------------
function publish_proc(msg)
{
console.error("*** publish_proc ***")
var client = mqtt.connect('mqtt://example.com')
const topic = 'M5Stack'
client.on('connect', function () {
client.publish(topic, msg)
client.end()
})
}
// ---------------------------------------------------------------
function counter_proc () {
var dt = new Date()
var formatted = dt.toFormat("HH24:MI:SS")
console.log(count, "只今の時刻:",formatted)
var timeoutId
if ((count % 2) == 0)
{
timeoutId = setTimeout(counter_proc, 2000)
}
else
{
timeoutId = setTimeout(counter_proc, 0)
}
var unit_aa = {}
unit_aa["ledno"] = Math.trunc(count / 2)
unit_aa["status"] = (count + 1) % 2
const json_str = JSON.stringify(unit_aa)
publish_proc(json_str)
count++
if (count == 16)
{
clearTimeout(timeoutId)
console.error ("*** 終了 ***")
}
}
// ---------------------------------------------------------------
console.error ("*** 開始 ***")
counter_proc()
// ---------------------------------------------------------------
実行スクリプト
start.sh
export NODE_PATH=/usr/local/lib/node_modules
./publish.js
Go のテストプログラム
publish.go
// ---------------------------------------------------------------
//
// publish.go
//
// Feb/09/2023
// ---------------------------------------------------------------
package main
import (
"os"
"encoding/json"
"fmt"
"log"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
// ---------------------------------------------------------------
func main() {
fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
opts := mqtt.NewClientOptions()
opts.AddBroker("tcp://example.com:1883")
cc := mqtt.NewClient(opts)
if token := cc.Connect(); token.Wait() && token.Error() != nil {
log.Fatalf("Mqtt error: %s", token.Error())
}
for it := 0; it < 16; it++ {
unit_aa := make (map[string]interface{})
unit_aa["ledno"] = it / 2
if ((it % 2) == 0) {
unit_aa["status"] = true
} else {
unit_aa["status"] = false
}
output, _ := json.Marshal(unit_aa)
token := cc.Publish("M5Stack", 0, false, output)
token.Wait()
if ((it % 2) == 0) {
time.Sleep(time.Second * 2)
}
}
cc.Disconnect(250)
fmt.Println("Complete publish")
fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}
// ---------------------------------------------------------------
実行の準備
go mod init publish
go mod tidy
実行コマンド
go run publish.go
Ruby のテストプログラム
publish.rb
#!/usr/bin/env ruby
# ---------------------------------------------------------------------
# publish.rb
#
# Feb/09/2023
# ---------------------------------------------------------------------
require 'mqtt'
require 'json'
host = 'example.com'
port = 1883
topic = 'M5Stack'
STDERR.puts "*** 開始 ***"
client = MQTT::Client.connect(:remote_host => host, :remote_port => port)
for it in 0..7 do
unit_aa = {}
unit_aa["ledno"] = it
unit_aa["status"] = true
json_str = JSON.generate(unit_aa)
client.publish(topic, json_str, retain=false)
sleep(2)
unit_aa["status"] = false
json_str = JSON.generate(unit_aa)
client.publish(topic, json_str, retain=false)
end
#
STDERR.puts "*** 終了 ***"
# ---------------------------------------------------------------------
ライブラリーのインストール
gem install mqtt
実行結果
$ ./publish.rb
*** 開始 ***
*** 終了 ***
確認したバージョン
$ ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]