打印
[应用相关]

ESP8266刷固件-模式设置-HAL库移植MQTT

[复制链接]
963|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
(一)模式设置
ESP8266有两种模式,AP和Station。可设置为AP、Station、AP&Station三种工作模式。
AP模式:无线接入点,例如路由器。
Station:AP的Client模式,例如手机连接路由器,手机就是Station模式。

1、AP模式设置
设置为AP模式:
AT+AT+CWMODE_DEF=2

设置WIFI名、密码、通道、加密方式、最大连接数:
AT+CWSAP_DEF="esp8266-ap","1234567890",5,3,1

设置WIFI的IP地址、网关、掩码:
AT+CIPAP_DEF="192.168.166.4.1","192.168.4.1","255.255.255.0"

重启使配置生效(选做,如果命令不带DEF字样,此步骤不需要):
AT+RST

开启WIFI多连接:
AT+CIPMUX=1

开启WIFI服务器:
AT+CIPSERVER=1

AP模式ESP8266数据接收并解析:

void WIFI_APModeRecvHanler(void)
{
        if (WIFI_RX_STA & 0x8000)
        {
                char* start = NULL;
                const char* header = "+IPD,0,";

                if ((start = strstr((const char *) WIFI_RX_BUF, header)) != NULL)
                {
                        if ((start = strstr((const char *) start, ":")) != NULL)
                        {
                                uint32_t datalen = WIFI_RX_STA & 0x3FFF;
                                const uint8_t* dataptr = (uint8_t *) (start + 1);
                                WIFI_RX_BUF[datalen] = '\0';
                                printf("tcp:%s\r\n", dataptr);
                        }
                }
                WIFI_RX_STA = 0;
        }
}


使用特权

评论回复
沙发
renzheshengui|  楼主 | 2021-8-4 15:29 | 只看该作者
2、Station模式与透传
设置为Station模式:
AT+CWMODE_DEF=1

加入路由器:
AT+CWJAP_DEF="路由器WIFI名","密码"

重启配置生效(不带DEF字样,此步骤不需要):
AT+RST

关闭多连接(多连接模式关闭才能开启透传):
AT+CIPMUX=0

设置为透传模式:
AT+CIPMODE=1

连接到服务器:
AT+CIPSTART="TCP","服务器IP地址",服务器端口号

进入透传模式:
AT+CIPSEND

退出透传模式(不加回车):
+++


使用特权

评论回复
板凳
renzheshengui|  楼主 | 2021-8-4 15:30 | 只看该作者
(二)固件更新
乐鑫ESP8266刷机软件和固件可以在这里下载:https://www.espressif.com/zh-hans/products/hardware/esp8266ex/resources

ESP8266-01S引脚说明:


所以ESP8266-01S刷机需要将GPIO0拉低,接线图如下:
注意:如果点击start后,一直处于等待上电同步,需要我们拉低一下复位引脚,或者直接断电再上电。

使用特权

评论回复
地板
renzheshengui|  楼主 | 2021-8-4 15:30 | 只看该作者
刷AT固件配置:

使用特权

评论回复
5
renzheshengui|  楼主 | 2021-8-4 15:30 | 只看该作者
刷MQTT固件配置:

使用特权

评论回复
6
renzheshengui|  楼主 | 2021-8-4 15:31 | 只看该作者
(三)STM32移植MQTT
平台:战舰mini板(stm32f03rb)
软件版本:STM32CUBEMX V5.3、TrueSTUDIO V9.3
MQTT服务器:emqx
效果:stm32订阅主题led_control,数据为on和off,以此来控制mini板上的led灯。




注意:ESP8266需要首先初始化为Station模式并进入透传。

嵌入式移植工作比较简单,只需要修改transport文件的硬件驱动读写函数即可,打开和关闭
函数暂时不需要。MQTTClient.c和MQTTClient.h文件是我自己编写,可根据需要自行修改。完整目录如下图所示:



使用特权

评论回复
7
renzheshengui|  楼主 | 2021-8-4 15:31 | 只看该作者
transport.c
#include "../inc/transport.h"
#include "../Inc/usart.h"
#include "../Inc/main.h"
#include "../Inc/app.h"

int transport_sendPacketBuffer(unsigned char* buf, int buflen)
{
        if (HAL_UART_Transmit(&huart3, (uint8_t *) buf, buflen, 0xFFFF) == HAL_OK)
                return buflen;
        return 0;
}

int transport_getdata(unsigned char* buf, int count)
{
        static uint32_t index = 0;
        uint32_t datalen = WIFI_RX_STA & 0x3FFF;

        if (WIFI_RX_STA & 0x8000)
        {
                if(datalen >= count)
                {
                        memcpy(buf, WIFI_RX_BUF + index, count);
                        index += count;
                        if(index == datalen)
                        {
                                WIFI_RX_STA = 0;
                                index = 0;
                        }
                        return count;
                }
        }
        return 0;
}


使用特权

评论回复
8
renzheshengui|  楼主 | 2021-8-4 15:31 | 只看该作者
MQTTClient.c
/*
* MQTTClient.c
*
*  Created on:
*      Author:
*/

#include "../inc/MQTTClient.h"
#include "../Inc/app.h"

uint8_t MQTT_ClientConnect(const void* clientId, const void* username, const void* password, uint16_t keepalive, bool cleansession)
{
        int len = 0;
        int buflen = 256;
        uint8_t buf[256];
        uint8_t sessionPresent, connack_rc;
        MQTTPacket_connectData data = MQTTPacket_connectData_initializer;

        data.clientID.cstring = (char *) clientId;
        data.keepAliveInterval = keepalive;
        data.cleansession = cleansession;
        data.username.cstring = (char *) username;
        data.password.cstring = (char *) password;
        data.MQTTVersion = 4;

        if ((len = MQTTSerialize_connect((unsigned char *) buf, buflen, &data)) <= 0)
                return 1;

        WIFI_RX_STA = 0;
        if (transport_sendPacketBuffer(buf, len) != len)
                return 2;

        delay_ms(1000);

        if (MQTTPacket_read(buf, buflen, transport_getdata) != CONNACK)
                return 3;

        if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
                return 4;

        return 0;
}

uint8_t MQTT_ClientPublish(const void* topic, const void* data)
{
        uint8_t buf[256];
        MQTTString topicString = MQTTString_initializer;
        int len = 0;

        topicString.cstring = (char *) topic;
        if ((len = MQTTSerialize_publish((uint8_t *) buf, sizeof(buf), 0, 0, 0, 0,
                        topicString, (uint8_t*) data, strlen((const char*) data))) <= 0)
                return 1;
        if (transport_sendPacketBuffer(buf, len) != len)
                return 2;
        return 0;
}

uint8_t MQTT_ClientSubscribe(const void* topic, int qos)
{
        uint8_t buf[200] =
        { 0 };
        uint32_t buflen = sizeof(buf);
        uint32_t len = 0;
        uint16_t packetid;
        int maxcount = 1;
        int count;
        int grantedQoSs;
        MQTTString topicString = MQTTString_initializer;
        topicString.cstring = (char *) topic;

        if ((len = MQTTSerialize_subscribe(buf, buflen, 0, 1, 1, &topicString, &qos)) <= 0)
                return 1;

        WIFI_RX_STA = 0;
        if (transport_sendPacketBuffer(buf, len) != len)
                return 2;

        delay_ms(1000);

        if (MQTTPacket_read(buf, buflen, transport_getdata) != SUBACK)
                return 3;

        if (MQTTDeserialize_suback(&packetid, maxcount, &count, &grantedQoSs, buf, buflen) == 0)
                return 4;

        return 0;
}

extern bool G_isConnected;

void MQTT_RecvParser(void)
{
        size_t topiclen = 0;
        size_t datalen = 0;
        static uint8_t topic[0xFF];
        static uint8_t message[0xFF];
        static const uint8_t* buf = WIFI_RX_BUF;

        if(G_isConnected == true)
        {
                if (WIFI_RX_STA & 0x8000)
                {
                        WIFI_RX_BUF[WIFI_RX_STA & 0x3FFF] = '\0';
                        if(strstr((char *)WIFI_RX_BUF, "CLOSED") != 0)
                        {
                                G_isConnected = false;
                                WIFI_RX_STA = 0;
                                return;
                        }

                        topiclen = buf[3];
                        datalen = buf[1] - buf[3] - 2;
                        memcpy((char *) topic, (const char *) (buf + 4), topiclen);
                        memcpy((char *) message, (const char *) (buf + 4 + topiclen), datalen);

                        topic[topiclen] = '\0';
                        message[datalen] = '\0';

                        if(strncmp(TOPIC_LED, (const char *)topic, strlen(TOPIC_LED)) == 0)
                        {
                                if(strncmp(MSG_LED_ON, (const char *)message, strlen(MSG_LED_ON)) == 0)
                                {
                                        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
                                }else if(strncmp(MSG_LED_OFF, (const char *)message, strlen(MSG_LED_OFF)) == 0){
                                        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
                                }
                        }

                        printf("\r\n");
                        printf("topic:%s\r\ndara:%s\r\n", (char *) topic, (char *) message);
                        WIFI_RX_STA = 0;
                }
        }
}



使用特权

评论回复
9
renzheshengui|  楼主 | 2021-8-4 15:32 | 只看该作者
main.c


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

4079

帖子

2

粉丝