0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ESP32: MQTT を使った Lチカ

Last updated at Posted at 2023-02-08

Ubuntu 24.04 上の Arduino IDE 2.3.2 を使いました。
ボードは、 ESP32 Dev Module です。

image.png

必要なライブラリー

Arduinojson
PubSubClient

image.png

プログラム

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]

参考ページ

Go: MQTT の pub/sub
Julia: MQTT の Publish

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?