Esp8266进阶之路17 esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。(附带Demo)

时间:2023-02-01 22:21:32


一、前言。


  • 8266的全部教程也学的差不多了,准备往ESP32搞了。在公司看到这样的产品,“快速开关五次,灯光出现闪烁,则进去一键配网模式。”,虽然我个人不是公司的嵌入式开发,但是凭借我这对8266娴熟的技术,2个小时就搞出来了;

  • 这个开关五次进去配网模式对于我们某些产品还是大有好处的 ,比如灯具… 我说的是天花板的灯具额~不用拿着*在灯具上面按键… 哈哈


二、实现的原理。


上个草图。


Esp8266进阶之路17 esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。(附带Demo)


  • ①、上述的标志位是保存在flash中,是掉电不丢失的数据。听说8266-12f或其他模块的外置flash模块都是25Qxx系列,可擦除次数有三万次,甚至更多。所以这点擦除不算什么的。

  • ②、每次模块上电后,标志位+1,之后开启定时器(自动重载),定时器任务有2个,首次执行时候将检查该标志位是否大于4,因为开关五次,这个标志位就是加到了5,如果大于4就是要进去一键配网模式。同时进去一键配网后要把标志位设置为0,否则下次检查就是6了哦!!

  • ③、如果定时器任务首次检查的标志位不是大于4而且三秒后还没掉电,那么就是正常的上电,那么我们也要把标志位设置为0,因为这样也就下次上电后不可能是大于4的。


Esp8266进阶之路17 esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。(附带Demo)


三、代码。(注意保存的数要四字节对齐!)


  • ①、设置标志位。形参:true设置标志位为0,false设置在原来的数值加一。
LOCAL void ICACHE_FLASH_ATTR setTurnOnOffFlag(bool isReset) {

    if (!isReset) {
        //先读出来再加一
        u8 saveNumber[4];
        spi_flash_read(550 * 4096 + 20, (uint32 *) &saveNumber, 4);
        if (saveNumber[0] > 8 || saveNumber[0] < 0) {
            saveNumber[0] = 1;
        } else {
            saveNumber[0]++;
        }
        //先擦除再保存
        spi_flash_erase_sector(550);
        spi_flash_write(550 * 4096 + 20, (uint32 *) &saveNumber, 4);
    } else {
        u8 saveNumber[4];
        saveNumber[0] = 0;
        //先擦除再保存
        spi_flash_erase_sector(550);
        spi_flash_write(550 * 4096 + 20, (uint32 *) &saveNumber, 4);
    }
}

  • ②、查询标志位。返回值就是标志位。
LOCAL u8 ICACHE_FLASH_ATTR getTurnOnOffFlag() {
    u8 tempSaveData[4];
    spi_flash_read(550 * 4096 + 20, (uint32 *) &tempSaveData, 4);
    os_printf("current save tempSaveData : %d \n:", tempSaveData[0]);
    //如果读取失败
    if (tempSaveData[0] == -1) {
        tempSaveData[0] = 1;
        spi_flash_erase_sector(550);
        spi_flash_write(550 * 4096 + 20, (uint32 *) &tempSaveData, 4);
    }
    return tempSaveData[0];
}

  • ③、程序入口;
void ICACHE_FLASH_ATTR user_init(void) {

    uart_init(57600, 57600);
    os_printf("SDK version:%s\n", system_get_sdk_version());

    //标志位加一
    setTurnOnOffFlag(false);

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); //GPIO选择
    GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0); //常亮

    /** 关闭该定时器 */
    os_timer_disarm(&os_timer);
    /** 配置该定时器回调函数 */
    os_timer_setfn(&os_timer, (ETSTimerFunc *) (hw_test_timer_cb), NULL);
    /** 启动该定时器 */
    os_timer_arm(&os_timer, 1000, true);

}

  • ④、定时器回调函数;大家还可以在这里做其他操作,比如是否获取到了IP;
void hw_test_timer_cb(void) {

    static u8 statusFlag = 0;
    statusFlag++;
    if (statusFlag == 1) {
        u8 flag = getTurnOnOffFlag();
        os_printf("current save flag : %d \n:", flag);
        if (flag > 4) {
            //LED开始闪烁
            Led_Cmd();
            //保存为0
            setTurnOnOffFlag(true);
            //进去一键配网模式
            smartconfig_set_type(SC_TYPE_ESPTOUCH);
            wifi_set_opmode(STATION_MODE);
            smartconfig_start(smartconfig_done);
            //关闭定时器
            os_timer_disarm(&os_timer);
        }
    } else if (statusFlag == 3) {
        setTurnOnOffFlag(true);
        //关闭定时器
        //os_timer_disarm(&os_timer);
    }

}

留念一下:

本博文代码下载:https://download.csdn.net/download/xh870189248/10364502

8266汇总,欢迎star: https://github.com/xuhongv/StudyInEsp8266


Esp8266进阶之路17 esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。(附带Demo)