ESP8266学习记录6——常用的API整理(持续更新)

零之前言

这里先说一下,这只是我个人的对ESP8266 rtos3.0+版本的整理与记录,可能与其他人的有差别。本人能力有限,如果有问题,请斧正,谢谢。

一.内核类

0.说明:

创建一个task,就类似于创建一个线程,然后我能力有限,不好说清楚那种感觉。。。
可以看看官方文档,挺好理解的FreeRTOS

1.创建、销毁:

创建:
static BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint32_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, TaskHandle_t *const pvCreatedTask)
可能看起来太复杂,简化一下:
xTaskCreate(创建线程的函数, "task的名字", 1024(栈大小), NULL(创建时运行的程序), 10(优先级), NULL(线程句柄));
一般来说,我们只需要用前两个参数就可以了:xTaskCreate(echo_task, "uart_echo_task", 1024, NULL, 10, NULL);
更多的内容,可以看官方文档:
官方文档-xTaskCreate
销毁:
vTaskDelete(TaskHandle_t xTaskToDelete) 传入指针就行

2.延时

这样用就行vTaskDelay(2000 / portTICK_PERIOD_MS);延时两秒

3.事件组

①创建

官方文档翻译:

在FreeRTOS实施内部,事件组使用[小]内存块,其中存储了事件组的结构。 如果使用xEventGroupCreate()创建事件组,则所需的内存将自动在xEventGroupCreate()函数内部动态分配。
事件标志组可以实现多任务间的任务同步,简单来说就是在不同的任务间传递简单的标志位。可以用于一些任务调用同一个反馈子程序。
EventGroupHandle_t xxx = xEventGroupCreate();

②销毁

在创建了之后注册系统事件,最后销毁vEventGroupDelete(xxx);

二.wifi类

1.station模式(模块去连接wifi)

初始化wifi
当然你在以下代码,创建一个xEventGroupCreate()事件组。

tcpip_adapter_init();
esp_event_loop_create_default();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = "your wifi ssid",
            .password = "your wifi's password"
        },
    };
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
esp_wifi_start();
esp_wifi_connect();  //connect wifi

如果需要重连回调,则需要注册:
esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL);
并且编写:event_handler:

static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        if (s_retry_num < 5) {  // retry times
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    }
}

2.AP模式(单片机等着被别人连)

代码:

void wifi_init_softap()
{
    
    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    //ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));

    wifi_config_t wifi_config = {
        .ap = {
            .ssid = "Wifi_ssid",
            .ssid_len = strlen("Wifi_ssid"),
            .password = "wifi_password",
            .max_connection = 99,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
        },
    };
    if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
    }

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

}

如果需要获取mac地址,则注册wifi_event事件:

static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                                    int32_t event_id, void* event_data)
{
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    }
}

如果需要获取ip地址,本来有个IP_event有代码,结果试了试,8266会重启,不知道是我哪里搞错了,后面再修改试试,破案了,官方原话回复:

I see function tcpip_adapter_dhcps_cb in tcpip_adapter_lwip.c sends the event with the client IP address in event_info via esp_event_send(&evt), but the mapping between the legacy and new event system doesn’t map the event_info - it’s missing the ARGS HANDLE_SYS_EVENT(IP, AP_STAIPASSIGNED)
They have it working properly in ESP-IDF.
需要将event_send_compat.c 94 lines 改为HANDLE_SYS_EVENT_ARG(IP, AP_STAIPASSIGNED, ap_staipassigned);,即可使用该事件:

else if (event_id == IP_EVENT_AP_STAIPASSIGNED){
        ip_event_ap_staipassigned_t* event = (ip_event_ap_staipassigned_t*) event_data;
        ESP_LOGI(TAG,"got ip form event loop:%s", ip4addr_ntoa(&event->ip));
    }

三.IO类

1.输入与输出

需要用到#include "driver/uart.h"

①.输入

初始化函数:

static void gpio_input_init(int pin){
    gpio_config_t io_conf;
    io_conf.pin_bit_mask = (1ULL << pin);
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_down_en = 1;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);
}

应用初始化:gpio_input_init(14);
获取电平:gpio_get_level(14)

②.输出

初始化函数:

static void gpio_output_init(int pin){
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = (1ULL << pin);
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);
}

应用初始化:gpio_output_init(15);
设置低电平:gpio_set_level(15,0);

2.串口

①.初始化

配置代码:

static void uart_init(int bord, int Buf){
    uart_config_t uart_config = {
        .baud_rate = bord,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_param_config(UART_NUM_0, &uart_config);
    uart_driver_install(UART_NUM_0, Buf * 2, 0, 0, NULL, 0);
}

应用初始化:uart_init(74880,1024);

②.串口输出:

static void uart_print(char* str){
    uart_write_bytes(UART_NUM_0, (const char*)str, strlen(str));
}

uart_print("USART TEST\r\n");

四.socket类

1.tcp_client

这是官方的代码,直接创建以你个xtask就可以了。然后稍作修改即可。

static void tcp_client_task(void *pvParameters)
{
    char rx_buffer[128];
    char addr_str[128];
    int addr_family;
    int ip_protocol;
    static const char *payload = "Message from ESP32 ";

    while (1) {
        vTaskDelay(2000 / portTICK_PERIOD_MS);
        struct sockaddr_in destAddr;
        destAddr.sin_addr.s_addr = inet_addr("192.168.249.187");
        destAddr.sin_family = AF_INET;
        destAddr.sin_port = htons(3333);
        addr_family = AF_INET;
        ip_protocol = IPPROTO_IP;
        inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
        int sock =  socket(addr_family, SOCK_STREAM, ip_protocol);
        if (sock < 0) {
            ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Socket created");

        int err = connect(sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
        if (err != 0) {
            ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
        }
        ESP_LOGI(TAG, "Successfully connected");

        while (1) {
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            int err = send(sock, payload, strlen(payload), 0);
            if (err < 0) {
                ESP_LOGE(TAG, "Error occured during sending: errno %d", errno);
                break;
            }

            int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
            // Error occured during receiving
            if (len < 0) {
                ESP_LOGE(TAG, "recv failed: errno %d", errno);
                break;
            }
            // Data received
            else {
                rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
                send(sock, rx_buffer, len - 1, 0);
            }
        }
        if (sock != -1) {
            ESP_LOGE(TAG, "Shutting down socket and restarting...");
            shutdown(sock, 0);
            close(sock);
        }
    }
    vTaskDelete(NULL);
}

2.tcp_server

static void tcp_server_task(void *pvParameters)
{
    char rx_buffer[128];
    char addr_str[128];
    int addr_family;
    int ip_protocol;

    while (1) {
        struct sockaddr_in destAddr;
        destAddr.sin_addr.s_addr = htonl("0.0.0.0");
        destAddr.sin_family = AF_INET;
        destAddr.sin_port = htons(3333);
        addr_family = AF_INET;
        ip_protocol = IPPROTO_IP;
        inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);


        int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
        if (listen_sock < 0) {
            ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Socket created");

        int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
        if (err != 0) {
            ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Socket binded");

        err = listen(listen_sock, 1);
        if (err != 0) {
            ESP_LOGE(TAG, "Error occured during listen: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Socket listening");

        struct sockaddr_in sourceAddr;

        uint addrLen = sizeof(sourceAddr);
        int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
        if (sock < 0) {
            ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Socket accepted");

        while (1) {
            int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
            // Error occured during receiving
            if (len < 0) {
                ESP_LOGE(TAG, "recv failed: errno %d", errno);
                break;
            }
            // Connection closed
            else if (len == 0) {
                ESP_LOGI(TAG, "Connection closed");
                break;
            }
            // Data received
            else {
                rx_buffer[len] = 0;
                ESP_LOGE(TAG, "%s", rx_buffer);
                //int err = send(sock, rx_buffer, len, 0);
                if (err < 0) {
                    ESP_LOGE(TAG, "Error occured during sending: errno %d", errno);
                    break;
                }
            }
        }

        if (sock != -1) {
            ESP_LOGE(TAG, "Shutting down socket and restarting...");
            shutdown(sock, 0);
            close(sock);
        }
    }
    vTaskDelete(NULL);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

康娜喵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值