• 基于SOC方案的嵌入式开发-远程定时设备


    Soc方案实现简单的定时开关灯

    http://club.gizwits.com/forum.php?mod=viewthread&tid=7787&highlight=%E5%AE%9A%E6%97%B6


    <ignore_js_op> 

         步骤②:定义三个数据点:
                 灯的总开关 (lightOpenOff): 布尔值类型  可写
                 定时器的总开关(isTimerOpen):布尔值  可写
                 定时开的时间(timerOpen):数值   0~3660 单位:秒  

    <ignore_js_op> 


       步骤③:选择MCU开发,选择硬件平台:esp8266-32M   Product Secret不用我多说了。

    <ignore_js_op> 


    二:电路图的设计与程序编写。


         电路图
              按键S1长按就是进入airlink配网模式了
              按键S2按下接通时候就是烧录模式了
              LED是接在GPIO12和VCC之间的。

    <ignore_js_op> 








                 程序篇:

    步骤一:先搭建8266的开发环境,我这使用的是安信可的集成环境,并且导入工程如果有不懂的,可以看这篇:http://blog.csdn.net/xh870189248/article/details/77985541

    步骤二:我们先修改我们程序的进入 “配网模式”的按键程序,首先我们打开工程的 app --> user --> user_main.c 文件,修改过程如下:

    修改第①处:

    我们先把按键定义改下,我们这个是只有一个按键,所以key的数量为1,见下面的修改。

    修改前:



    1. #define GPIO_KEY_NUM                            2                           ///< Defines the total number of key members
    2. #define KEY_0_IO_MUX                            PERIPHS_IO_MUX_GPIO0_U      ///< ESP8266 GPIO function
    3. #define KEY_0_IO_NUM                            0                           ///< ESP8266 GPIO number
    4. #define KEY_0_IO_FUNC                           FUNC_GPIO0                  ///< ESP8266 GPIO name
    5. #define KEY_1_IO_MUX                            PERIPHS_IO_MUX_MTMS_U       ///< ESP8266 GPIO function
    6. #define KEY_1_IO_NUM                            14                          ///< ESP8266 GPIO number
    7. #define KEY_1_IO_FUNC                           FUNC_GPIO14                 ///< ESP8266 GPIO name
    8. LOCAL key_typedef_t * singleKey[GPIO_KEY_NUM];                              ///< Defines a single key member array pointer
    9. LOCAL keys_typedef_t keys;                                                  ///< Defines the overall key module structure pointer
    复制代码


    修改后    (我们在电路图看到是GPIO4触发配网模式,所以该为GPIO4

    1. #define GPIO_KEY_NUM                            1                           ///< Defines the total number of key members
    2. #define KEY_0_IO_MUX                            PERIPHS_IO_MUX_GPIO4_U      ///< ESP8266 GPIO function
    3. #define KEY_0_IO_NUM                            4                          ///< ESP8266 GPIO number
    4. #define KEY_0_IO_FUNC                           FUNC_GPIO4                 ///< ESP8266 GPIO name
    复制代码


    修改第②处:

    把以下的代码删除:

    1. **
    2. * Key2 key to short press processing
    3. * @param none
    4. * @return none
    5. */
    6. LOCAL void ICACHE_FLASH_ATTR key2ShortPress(void)
    7. {</p><p>GIZWITS_LOG("#### key2 short press, soft ap mode ");
    8.   gizwitsSetMode(WIFI_SOFTAP_MODE);
    9. }
    10. /**
    11. * Key2 button long press
    12. * @param none
    13. * @return none
    14. */
    15. LOCAL void ICACHE_FLASH_ATTR key2LongPress(void)
    16. {
    17.     GIZWITS_LOG("#### key2 long press, airlink mode ");  
    18.     gizwitsSetMode(WIFI_AIRLINK_MODE);
    19. }
    复制代码


    同时把   ICACHE_FLASH_ATTR 函数里面以下代码去掉:    

       singleKey[1] = keyInitOne(KEY_1_IO_NUM, KEY_1_IO_MUX, KEY_1_IO_FUNC,  key2LongPress, key2ShortPress);

    最后得到的按键初始化函数 ICACHE_FLASH_ATTR 如下代码:


    1. /**
    2. * Key to initialize
    3. * @param none
    4. * @return none
    5. */
    6. LOCAL void ICACHE_FLASH_ATTR keyInit(void)
    7. {
    8.     singleKey[0] = keyInitOne(KEY_0_IO_NUM, KEY_0_IO_MUX, KEY_0_IO_FUNC,
    9.                                 key1LongPress, key1ShortPress);  //key1LongPress方法回调对应上面的,key1shortPress同样也是
    10.     keys.singleKey = singleKey;
    11.     keyParaInit(&keys);
    12. <strong><font color="seagreen">}</font></strong>
    复制代码

    修改第③处:

        我们把按键短按和长按的方法修改下,让按键短按进入 AirLink配网模式,长按进入softAP配网模式,修改如下:

    1. /**
    2. * Key1 key short press processing
    3. * @param none
    4. * @return none
    5. */
    6. LOCAL void ICACHE_FLASH_ATTR key1ShortPress(void)
    7.     gizwitsSetMode(WIFI_SOFTAP_MODE);
    8. }
    9. /**
    10. * Key1 key presses a long press
    11. * @param none
    12. * @return none
    13. */
    14. LOCAL void ICACHE_FLASH_ATTR key1LongPress(void)
    15. {
    16.     gizwitsSetMode(WIFI_AIRLINK_MODE);
    17. }
    复制代码


    修改第④处:  因为我们是只有一个功能,并且只有使用到一个GPIO口,所以我们仅仅初始化一个就好了,我这在user_init()主函数直接加入以下代码:

    1.     PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); //GPIO12初始化
    2.     GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);//GPIO12 低电平输出
    复制代码


    修改第五处:我们现在把目标转到 app --->Gizwits_product.c 文件(下同),修改我们8266收到指令后作出动作的代码:

    修改前

    1. case EVENT_lightOnOff :
    2.             currentDataPoint.valuelightOnOff = dataPointPtr->valuelightOnOff;
    3.             GIZWITS_LOG("Evt: EVENT_lightOnOff %d ", currentDataPoint.valuelightOnOff);
    4.             if(0x01 == currentDataPoint.valuelightOnOff)
    5.             {
    6.                 //user handle
    7.             }
    8.             else
    9.             {
    10.                 //user handle
    11.             }
    12.             break;
    复制代码


    修改后:  收到0x01(true)开灯,0x00(false)关灯,因为8266的内部GPIO是默认上拉,所以选择高电平输出,反而灯会亮!!博主也是从这篇文章了解到的:http://blog.csdn.net/jackhuang2015/article/details/50839401

    1. case EVENT_lightOnOff :
    2.             currentDataPoint.valuelightOnOff = dataPointPtr->valuelightOnOff;
    3.             GIZWITS_LOG("Evt: EVENT_lightOnOff %d ", currentDataPoint.valuelightOnOff);
    4.             if(0x01 == currentDataPoint.valuelightOnOff)
    5.             {
    6.                      GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1); //开灯
    7.             }
    8.             else
    9.             {
    10.                      GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0); //关灯
    11.             }
    12.             break;
    复制代码

    修改第⑥处:

        我们在文件新增一个定时器使能的bool类型、一个软件定时器结构体和一个定时时间

    1. //布尔值,定时器开关的状态
    2. bool isTimer ;
    3. //定时时间
    4. uint16_t timer_timers;
    5. /** 定时器结构体 */
    6. static os_timer_t os_timer;
    复制代码


       我们在收到app发来的 isTimerOpen数据点(开关定时器的指令)的方法处理这样做:

    1. <p>   case EVENT_isTimerOpen :
    2.             currentDataPoint.valueisTimerOpen = dataPointPtr->valueisTimerOpen;
    3.             if(0x01 == currentDataPoint.valueisTimerOpen)
    4.              {
    5.                       isTimer=true;
    6.              }   else   {
    7.               /** 关闭该定时器 */
    8.             os_timer_disarm( &os_timer );         </p><p>            /** 定时器使能为false */
    9.             isTimer=false;
    10.                      }
    11.             break;</p>
    复制代码



      我们在收到app发来的 TimerOpen数据点(定时时间)的方法处理这样做:    注意,每次开启定时器,要先把其关闭掉,再重新初始化使能。


    1. case EVENT_timerOpen:
    2.                   currentDataPoint.valuetimerOpen= dataPointPtr->valuetimerOpen;         </p><p> //只有当使能状态为true就可以开启定时器
    3.               if(isTimer){
    4.                                 /** 关闭该定时器 */
    5.                                 os_timer_disarm( &os_timer );
    6.                                 // 配置该定时器回调函数,指定的执行方法是: Led_Task_Run (),下面会提供代码
    7.                          os_timer_setfn( &os_timer, (ETSTimerFunc *) (<font color="red"> Led_Task_Run</font> ), NULL );
    8.                                 /** 开启该定时器 :下发的是秒数,这里的单位是毫秒,要乘1000* ,后面false表示仅仅执行一次**/
    9.                                 os_timer_arm( &os_timer, currentDataPoint.valuetimerOpen*1000, false );
    10.                                 /**赋值给timer_timers,方便会调用 */
    11.                                 timer_timers=currentDataPoint.valuetimerOpen;
    12.                           }
    13.                break;
    复制代码


      定时任务函数这样做:

    1. /**
    2. * 定时任务函数
    3. */
    4. void Led_Task_Run(void){
    5. //开灯
    6. GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);
    7. //执行完毕,我们要把定时时间设置0 ,定时使能状态为false
    8. timer_timers=0;
    9. isTimer=false;
    10. }
    复制代码


    修改⑦:改变上报数据的方法:

    1. void ICACHE_FLASH_ATTR userHandle(void)
    2. {
    3.                 //获取GPIO12的高低电平,因为高电平是触发开灯,所以ture就是开灯
    4.                 currentDataPoint.valuelightOnOff = GPIO_INPUT_GET(12)  ;
    5.                 //是否开启定时器的回调
    6.                                currentDataPoint.valueisTimerOpen =isTimer ;
    7.                                //定时时间回调,如果用戶設置了定時器关闭,那么我们返回0,否则返回定时时间,注意这个定时时间是固定的。不是倒计时时间。
    8.                               if(isTimer){
    9.                          currentDataPoint.valuetimerOpen =timer_timers ;
    10.                     }else{
    11.              currentDataPoint.valuetimerOpen =0;
    12.                                        }
    13.       system_os_post(USER_TASK_PRIO_2, SIG_UPGRADE_DATA, 0);
    14. }
    复制代码
  • 相关阅读:
    [PHP]AES加密----PHP服务端和Android客户端
    [PHP]memcache安装
    [Android]apk反编译方法
    [PHP]生成随机数(建立字典)
    [PHP]Mysql的运用
    [PHP]对象数组和普通数组总结
    ThinkPHP5+Redis单例型购物车
    移动硬盘新建选项消失、不能新建文件夹和文件的解决方案
    PHP substr() 函数截取中文字符串乱码
    php开发中遇到问题的找错误的方法
  • 原文地址:https://www.cnblogs.com/pengwenzheng/p/9372657.html
Copyright © 2020-2023  润新知