ESP32聯網-MQTT-連接到本地服務器(LInux)

上一篇說到用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

下載鏈接:https://repository.jboss.org/nexus/content/groups/fs-public/org/fusesource/mqtt-client/mqtt-client/1.7/mqtt-client-1.7-uber.jar

下載軟件包

圖中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的命令行那看到

大功告成,收工睡覺。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章