1. oled显示网络时间, wifi链接网络
// ntp_get_date.h
#include "time.h"
String week[8] = {
"Sun", "Mon", "Tues", "Wednes", "Thur", "Fri", "Sat"
};
void printLocalTime(Adafruit_SSD1306 &display) { //打印本地时间函数
struct tm timeinfo;
if(!getLocalTime( & timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %Y-%m-%d %H:%M:%S");
char display_str[30] = {0};
sprintf(display_str,"%04d-%02d-%02d %02d:%02d:%02d %01d",
timeinfo.tm_year+1900,
timeinfo.tm_mon+1,
timeinfo.tm_mday,
timeinfo.tm_hour,
timeinfo.tm_min,
timeinfo.tm_sec, timeinfo.tm_wday);
display.clearDisplay();
display.setCursor(0, 0);
display.println(display_str);
display.display();
}
const char * ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 28800;
const int daylightOffset_sec = 0;
void ntp_get_date_init() {
// 将请求数据包传输到NTP服务器,并将接收到的时间戳数据包解析为可读格式
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}
// main.cpp
#include <Arduino.h>
#include <WiFi.h>
#include <Adafruit_SSD1306.h>
#include "ntp_get_date.h"
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
const char* id="Wifi账号"; //定义两个字符串指针常量
const char* psw="wifi密码";
void setup() {
// 串口初始化
Serial.begin(115200);
// oled初始化
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.display();
delay(500);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
display.clearDisplay();
// wifi初始化
WiFi.begin(id,psw);
while(WiFi.status()!=WL_CONNECTED){ //未连接上
delay(500);
Serial.println("connection...");
}
display.setCursor(0, 0);
display.println("wifi connect to Wifi007 success");
display.display();
Serial.println("wifi connect to Wifi007 success");
ntp_get_date_init();
}
void loop() {
printLocalTime(display);
delay(500);
}
2. mqtt订阅和发布信息
服务端 docker安装emqx
# http://t.csdn.cn/PqPEo
docker run -dit --name emqx -p 18083:18083 -p 1883:1883 -p 8083:8083 -p 8084:8084 emqx/emqx:latest
浏览器登录: http://192.168.3.12:18083/#/dashboard/overview
admin 密码是public
18083 管理控制端口
1883 mqtt协议端口
8083 MQTTwebSocket端口
# 认证方式
https://blog.csdn.net/weixin_43869518/article/details/127558282
客户端 esp32c3 xiao
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
const char* id="wifi账号"; //定义两个字符串指针常量
const char* psw="wifi密码";
const char* mqtt_server = "192.168.3.12"; // 服务IP
const uint16_t mqtt_port = 1883; // 服务端口
WiFiClient espClient; // WiFi客户端节点
PubSubClient mqttClient(espClient); //
void callback(char* topic, byte* payload, unsigned int length);
void reconnect();
void setup() {
// 串口初始化
Serial.begin(115200);
// wifi初始化
WiFi.mode(WIFI_STA);
WiFi.begin(id, psw);
while(WiFi.status()!=WL_CONNECTED){ //未连接上
delay(500);
Serial.println("connection...");
}
Serial.println("wifi connect to Wifi007 success");
mqttClient.setServer(mqtt_server, mqtt_port);
mqttClient.setCallback(callback);
randomSeed(micros());
}
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;
unsigned long lastMsg = 0;
void loop() {
if (!mqttClient.connected()) {
reconnect();
}
mqttClient.loop();
/*
下面是给订阅的消息队列发送随机数, 也就是mqtt的发布
*/
unsigned long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
value = random(1,50);//生成一个随机数
snprintf (msg, MSG_BUFFER_SIZE, "%ld", value);//将随机数转变成为字符串
Serial.print("Publish message: ");
Serial.println(msg);
mqttClient.publish("test/topic2", msg);//发布这个随机数
}
}
/**
* 下面是订阅获取数据
*/
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
if (mqttClient.connect("ESP32Client")) {
Serial.println("connected");
// 一旦连接上了,就发布一个主题,这个主题是自定义的,您可以在自己的MQTT服务器进行查看
mqttClient.publish("test/topic2", "hello world");
// subscribe是订阅的意思,MQTT通信的核心就是“订阅+发布”
mqttClient.subscribe("test/topic1");
mqttClient.subscribe("test/topic2");
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
客户端加密码校验
- 服务端通过访问数据库来校验账号密码
- 客户端通过账号密码进行connect
服务端配置
第一步创建数据库, 并且根据emqx的创建表提示创建表
第二步在表中添加数据
第三步在emqx的客户端认证中增加账号密码
客户端通过账号密码登录
void reconnect() {
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
if (mqttClient.connect(CLIENT_ID, mqtt_username, mqtt_password)) {
Serial.println("connected");
// 一旦连接上了,就发布一个主题,这个主题是自定义的,您可以在自己的MQTT服务器进行查看
mqttClient.publish("test/topic2", "hello world");
// subscribe是订阅的意思,MQTT通信的核心就是“订阅+发布”
mqttClient.subscribe("test/topic1");
mqttClient.subscribe("test/topic2");
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
最后的效果图, 通过web客户端发送主题消息, topic2, 客户端能够接收到
这里在增加一个demo, arduino显示电脑CPU和内存的信息(脚本自己写,只提供思路)
# 服务器上安装客户端
sudo apt install mosquitto-clients
zjq@zjq:~$ mosquitto_sub -h 192.168.31.224 -p 8083 -u zjq -P zjq -t arduino/cpu
# 这里可以查一下mqtt docker部署的端口号到底是啥
^Czjq@zjq:~$ mosquitto_sub -h 192.168.31.224 -p 1883 -u zjq -P zjq -t arduino/cpu -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: arduino/cpu, QoS: 0, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 0
Client (null) received PUBLISH (d0, q0, r0, m0, 'arduino/cpu', ... (18 bytes))
{ "msg": "hello" }
# 发送信息
mosquitto_pub -h 192.168.31.224 -p 1883 -u zjq -P zjq -t arduino/cpu -m "21472189"