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);
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,我知道了。针对你的问题,我能够为你提供如下的解答: 在使用 MicroPython 和 ESP8266 控制 LED 的过程中,可以通过 PWM 技术实现呼吸灯效果。PWM(Pulse Width Modulation)脉宽调制技术是一种通过改变信号的占空比来控制电路输出功率的技术。 具体实现步骤如下: 1. 首先需要在 ESP8266 上安装 MicroPython,然后连接 ESP8266 和 LED。 2. 在 MicroPython 中,可以使用 machine 模块中的 Pin 和 PWM 类来控制 LED。 3. 先使用 Pin 类将 LED 连接到 ESP8266 上的一个 GPIO 引脚。 4. 再使用 PWM 类来初始化一个 PWM 对象,并设置 PWM 对象的频率和占空比。 5. 最后使用 PWM 对象的 duty() 方法来改变占空比,从而控制 LED 显示的亮度。 下面是一个简单的 MicroPython 代码示例,用于控制 LED 呼吸灯效果: ```python from machine import Pin, PWM import time led_pin = Pin(2, Pin.OUT) # 连接到GPIO2 pwm = PWM(led_pin, freq=5000) # 初始化PWM对象,设置频率为5000Hz while True: for duty_cycle in range(0, 1024, 8): # 从0到1024,每次增加8 pwm.duty(duty_cycle) # 设置占空比 time.sleep_ms(5) # 暂停5ms for duty_cycle in range(1023, -1, -8): # 从1023到0,每次减少8 pwm.duty(duty_cycle) # 设置占空比 time.sleep_ms(5) # 暂停5ms ``` 上面的代码中,使用了一个无限循环来让 LED 一直显示呼吸灯效果。在每个循环中,通过循环改变占空比,从而让 LED 呈现出呼吸灯效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

康娜喵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值