上一篇說到用JAVA寫Linstener 。
很多人會問網上有很多現成的(可視化的),爲啥要自己寫呢?
我想說自己寫的話對MQTT協議會更加的瞭解,而且得到的數據到時候會更加好處理,現成的東西不帶這功能。
作爲一個準電子工程師,必要的編程(Ctrl-C 、Ctrl-V)技能還是要有的。
所需工具:Apache Apollo(已運行的登錄,參考上一篇)
ESP-IDF(參考環境搭建)
Eclipse(JAVA IDE環境)
本篇內用參考Apache Apollo->Example->MQTT->JAVA;
然而好像我的電腦用maven來Build老是有點奇奇怪怪的Bug,
所以我選用了Eclispe這IDE來編寫執行。
首先 要安裝JDK,默認你們看了上一篇了,JAVA環境變量什麼的都搭好了。
地址https://www.eclipse.org/downloads/packages/
一個企業 一個個人,二選一。
下載->解壓->運行
新建JAVA工程
New->Java Project->...->Finish
添加外部JARS包 我們需要上github下載
參考鏈接:https://github.com/fusesource/mqtt-client
下載軟件包
圖中MQTT-....那個就是了
然後回到Eclispe
右鍵工程My_MQTT->Properties->Java Build Path->Libraries->Add External JARS->Appy & Close 添加並應用剛纔的軟件包
(如果左側沒有Project工具欄 在右上角Quick Access :輸入關鍵字Browser 然後有Project Browser 點一下就行)
然後
然後在src文件夾右鍵New->Java Class(如果左側沒有Project工具欄 在右上角Quick Access :輸入關鍵字Browser 然後有Project Browser 點一下就行)
然後
將內容全部替換爲下面坨代碼:
import org.fusesource.hawtbuf.*;
import org.fusesource.mqtt.client.*;
public class My_MQTT {
public static void main(String []args) throws Exception {
String user = env("APOLLO_USER", "admin");//set username
String password = env("APOLLO_PASSWORD", "password");//set password
String host = env("APOLLO_HOST", "localhost");//set localhost
int port = Integer.parseInt(env("APOLLO_PORT", "61613"));//set port
final String destination = arg(args, 0, "/topic/qos1");
//set topic
MQTT mqtt = new MQTT();
mqtt.setHost(host, port);
mqtt.setUserName(user);
mqtt.setPassword(password);
final CallbackConnection connection = mqtt.callbackConnection();
connection.listener(new org.fusesource.mqtt.client.Listener() {
long count = 0;
long start = System.currentTimeMillis();
public void onConnected() {
}
public void onDisconnected() {
}
public void onFailure(Throwable value) {
value.printStackTrace();
System.exit(-2);
}
public void onPublish(UTF8Buffer topic, Buffer msg, Runnable ack) {
String body = msg.utf8().toString();
System.out.println(String.format("Received %s", body));
}
});
connection.connect(new Callback<Void>() {
@Override
public void onSuccess(Void value) {
Topic[] topics = {new Topic(destination, QoS.AT_LEAST_ONCE)};
connection.subscribe(topics, new Callback<byte[]>() {
public void onSuccess(byte[] qoses) {
System.out.println(String.format("Connect Successfully"));
}
public void onFailure(Throwable value) {
value.printStackTrace();
System.exit(-2);
}
});
}
@Override
public void onFailure(Throwable value) {
value.printStackTrace();
System.exit(-2);
}
});
// Wait forever..
synchronized (My_MQTT.class) {
while(true)
My_MQTT.class.wait();
}
}
private static String env(String key, String defaultValue) {
String rc = System.getenv(key);
if( rc== null )
return defaultValue;
return rc;
}
private static String arg(String []args, int index, String defaultValue) {
if( index < args.length )
return args[index];
else
return defaultValue;
}
}
上面這堆東西就是設置 帳號 密碼 端口 等等東西
點擊Run
如果控制檯出現Connect Successfully 就代表成功了
好這裏只完成了JAVA部分 然後使用ESP32進行連接
ESP32
注意 這裏電腦和ESP32要連到同一路由器(同一網段)
如何查本地地址 ifconfig
我的是192.168.0.225
進入到 修改 '/home/jasper/esp/esp-idf/examples/protocols/mqtt/tcp/main/app_main.c'
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTT_EXAMPLE";
static EventGroupHandle_t wifi_event_group;
const static int CONNECTED_BIT = BIT0;
esp_mqtt_client_handle_t client;
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
{
// esp_mqtt_client_handle_t client = event->client;
client = event->client;
int msg_id;
// your_context_t *context = event->context;
switch (event->event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
return ESP_OK;
}
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID,
.password = CONFIG_WIFI_PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID);
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Waiting for wifi");
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}
static void mqtt_app_start(void)
{
esp_mqtt_client_config_t mqtt_cfg = {
.host="192.168.0.225",
.port=61613,
.username="admin",
.password="password",
.event_handle = mqtt_event_handler,
// .user_context = (void *)your_context
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_start(client);
}
void app_main()
{
unsigned int count;
char data_to_send[20];
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
esp_log_level_set("*", ESP_LOG_INFO);
esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE);
esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE);
esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE);
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);
nvs_flash_init();
wifi_init();
mqtt_app_start();
for(count=0;count<1000;count++)
{
sprintf(data_to_send,"%s%d","Hello Jasper:",count);
esp_mqtt_client_publish(client, "/topic/qos1", data_to_send, 0, 1, 0);
vTaskDelay(1000/portTICK_PERIOD_MS);
}
}
其中修改 static void mqtt_app_start(void) 中mqtt的.host 我的是192.168.0.225,你的就不知道了
然後再修改 static void wifi_init(void) 中的 .ssid .password 爲你wifi的帳號密碼 記得帶" "
make flash 燒錄到你的ESP32中 運行
然後在Eclipse的命令行那看到
大功告成,收工睡覺。