[003] [ESP32开发笔记] AT指令开发远端可变UDP通信

ESP32
开发笔记
AT指令步骤
ESP串口通信代码1
串口缓冲队列
发送AT指令
发送UDP消息
UDP通信初始化

硬件:STM32F407ZGT6
SDK:HAL库
RTOS:RT-Thread

1 AT指令步骤

  1. AT+RST复位

  2. 设置WIFI模式:AT+CWMODE_DEF=1 (设置为 station 模式)

  3. 连接路由器 AT+CWJAP_DEF="ssid","password" /(_DEF保存flash)

  4. 查询 ESP8266 设备的 IP 地址 AT+CIFSR

  5. 创建 UDP 连接:AT+CIPSTART="UDP","192.168.101.110",8080,1112,2

    • 192.168.101.1108080:分别为远端ip和port;
    • 1112:为esp模块端口;
    • 2:表示当前 UDP 传输建⽴后,UDP 传输远端仍然会更改,UDP 传输远端会⾃动更改为最近⼀个与ESP8266 UDP 通信的远端。(即远端可变)
  6. 发送数据:AT+CIPSEND=32 (32为数据长度 )
    发送该指令后,紧接着可发送<=设定长度的字符数据

  7. 断开连接:AT+CIPCLOSE (连接后需要断开连接才能再次创建 UDP 传输)

2 ESP串口通信代码

2.1 串口缓冲队列

#define UART_QUEUE_MAXSIZE 512

typedef struct
{
    uint16_t front;
    uint16_t rear;
    uint8_t data[UART_QUEUE_MAXSIZE];
} uart_queue_t;
static uint8_t esp_rx_buf[UART_QUEUE_MAXSIZE];
static uint16_t pos = 0;
uart_queue_t uart4_queue;

void uart_queue_push(uart_queue_t *q, const uint8_t *data)
{
    if ((q->rear + 1) % UART_QUEUE_MAXSIZE == q->front)
        return;
    q->data[q->rear] = *data;
    q->rear = (q->rear + 1) % UART_QUEUE_MAXSIZE;
}

void uart_queue_pop(uart_queue_t *q, uint8_t *data)
{
    if (q->front == q->rear)
        return;
    *data = q->data[q->front];
    q->front = (q->front + 1) % UART_QUEUE_MAXSIZE;
}

uint16_t uart_queue_get_data(uart_queue_t *q, uint8_t *pbuf)
{
    uint8_t data;
    while ((q->rear - q->front + UART_QUEUE_MAXSIZE) % UART_QUEUE_MAXSIZE)
    {
        uart_queue_pop(q, &data);
        if (pos >= UART_QUEUE_MAXSIZE)
            return 0;
        pbuf[pos++] = data;
    }

    return pos;
}
void UART4_IRQHandler(void)
{
    uint8_t rx_data;
    if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_RXNE) != RESET){
        rx_data = READ_REG(huart4.Instance->DR);
        uart_queue_push(&uart4_queue, &rx_data);
    }
}

2.2 发送AT指令

void usart_sendString(UART_HandleTypeDef *huart, const uint8_t *str)
{
    while (*str != '\0')
    {
        HAL_UART_Transmit(huart, (uint8_t *)str, 1, 1000);
        str++;
    }
}
HAL_StatusTypeDef esp_send_cmd(const char *cmd, const char *reply, uint16_t timeout)
{
    rt_memset(cmd_buf, 0, UART_QUEUE_MAXSIZE);
    rt_memset(esp_rx_buf, 0, pos);
    pos = 0;

    strcpy(cmd_buf, cmd);
    if (strstr(cmd_buf, "\r\n") == NULL)
        strcat(cmd_buf, "\r\n");

    usart_sendString(&huart4, cmd_buf);

    while (timeout)
    {
        if (uart_queue_get_data(&uart4_queue, esp_rx_buf))
        {
            if (strstr(esp_rx_buf, reply) != NULL)
            {
                printf("%s", esp_rx_buf);
                return HAL_OK;
            }
        }
        timeout--;
        rt_thread_mdelay(1);
    }
    return HAL_TIMEOUT;
}
  • cmd:要发送的AT指令
  • reply:esp收到该指令后正确回复信息(如OK
  • timeout:超时等待时间,单位ms

2.3 发送UDP消息

void esp_send_udp(const char *data)
{
    char cmd_buf[16];
    sprintf(cmd_buf, "AT+CIPSEND=%d", strlen(data));
    if (esp_send_cmd(cmd_buf, "OK", 500) == HAL_OK)
        esp_send_cmd(data, "SEND OK", 1000);
}

示例:esp_send_udp("{\"data\":\"led\",\"status\":\"on\"}");

2.4 UDP通信初始化

void esp_init(void)
{
    // 复位
    esp_send_cmd("AT+RST", "OK", 800);
    // 设置为 station 模式
    esp_send_cmd("AT+CWMODE_CUR=3", "OK", 500);
    // 连接wifi
    esp_send_cmd("AT+CWJAP_CUR=\"ssid\",\"password\"", "OK", 5000);
    // 创建 UDP 连接, 微信小程序端口为9999
    esp_send_cmd("AT+CIPSTART=\"UDP\",\"192.168.239.14\",9999,1111,2", "OK", 1000);
    // 获取esp8266 ip
    esp_send_cmd("AT+CIFSR", "OK", 500);
}

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯西的彷徨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值