收藏官网首页
查看: 640|回复: 16

[技术分享] IoT大咖秀:悦国庆贺中秋,Soc方案实现简单的定时开关灯。

发表于 2017-9-30 21:57:52 | 显示全部楼层 |阅读模式
免费使用STM32、APP自动代码生成工具
本帖最后由 半颗心脏 于 2017-10-3 10:09 编辑




               悦国庆、贺中秋,Soc方案实现简单的定时开关灯。
   
           致各位机智云小伙伴:
                  
                  在编写此文前,首先祝各位小伙伴国庆节快快乐乐,中秋节与家人开开心心的。国庆节之时,感谢祖国为我们提供这么和平友善的社会环境,当然啦,还要感谢机智云为我们提供提供这么方便快捷的一式化开发。本文仅供技术参考,不做商业用途,如有不适,万分见谅,及时修改。

                             最近听到很多小伙伴想学soc方案实现远程控制,当然啦!我本来是想出视频教大家入门的,但是这个视频要等到十一月(公司事务繁多) ,所以,先出个图文并茂的教程给大家实现“soc方案远程控制定时开关灯,点亮您中秋佳节的第一盏灯”。

         回复本帖子,后面提供工程下载链接哦。


                                                                   机智云发烧友:小徐
                                                                                  2017/9/30  22:30

因为国庆忙着回家,没准备好,所以就选择了小黑板作为本帖子的硬件准备,也是参考社区的一篇文章作为参考的。
小黑板远程控制soc方案。 ,不走任何商业用途!!我这篇优化了下,增加了定时功能,给想学的小伙伴一点干货。


第一步:云端增加产品,新增数据点,自动生成soc方案的代码。

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

第三步:配合手机调试。



一:云端增加产品,新增数据点。


       步骤①:选择通讯方式为:wifi ,数据传输方式:定长。

增加数据点

增加数据点


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

定义数据点.png


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

生成mcu.png


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


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

最小系统.png








             程序篇:

步骤一:先搭建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 \n");
  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\n");  
  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. {
  8.     gizwitsSetMode(WIFI_SOFTAP_MODE);
  9. }

  10. /**
  11. * Key1 key presses a long press
  12. * @param none
  13. * @return none
  14. */
  15. LOCAL void ICACHE_FLASH_ATTR key1LongPress(void)
  16. {
  17.     gizwitsSetMode(WIFI_AIRLINK_MODE);
  18. }
复制代码

修改第④处:  因为我们是只有一个功能,并且只有使用到一个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 \n", 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 \n", 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. }
复制代码


     烧录

对于很多新手来说,烧录过程完全是个坑,完全不知道烧录哪几个文件。

①:下面是我从安信可论坛看到的一张图,希望可以帮到大家:
                                             
②:这里我再强调,blank.bin、esp_init_data_default.bin一定要烧写进去,避免内部初始化出错,这2个文件在工程下bin文件夹可以找到。一般的8266都是32M的。所以,blank.bin的固定烧录地址是:0x3FE000 ,esp_init_data_default.bin的固定烧录地址是:0x3FC000
                                                   
③:  再再强调,编译结果有 2 种,第一种不需要 boot.bin 文件,第二种则需要 boot.bin 文件。但是编译结果不管怎么样,我们都是只烧录4个文件。烧录时候:先把gpio0设置为低电平,默认是上拉高电平的。

④: 大家可以看看我写的博客参考烧录方法(注意看下部分的烧录过程):http://blog.csdn.net/xh870189248/article/details/78126689

⑤:更多的8266开发教学与经验,请多多支持我的【深度开源系列】之Esp8266学习之旅,欢迎各位star:https://github.com/xuhongv/StudyInEsp8266




151848vtsii55cstntn4sj.png

展示图:

share_1506933145890.jpg

游客,如果您要查看本帖隐藏内容请回复




1、机智云Adnroid开源框架QQ交流群: 434878850

QQ群目前非常活跃,欢迎大家参与进来,交流,讨论,答疑,解惑~~
2、机智云微信公众号: 机智云 gizwits /   机智云智能宠物屋go-iot
关注机智云Gizwits官方公众号随

3

主题

25

帖子

850

积分

高级会员

Rank: 4

积分
850
发表于 2017-10-2 18:38:45 来自手机 | 显示全部楼层
谢谢分享,找了很久智能定时开关。

4

主题

104

帖子

2183

积分

金牌会员

Rank: 6Rank: 6

积分
2183
发表于 2017-10-3 09:56:09 | 显示全部楼层
又学到了,谢谢

10

主题

100

帖子

1449

积分

金牌会员

Rank: 6Rank: 6

积分
1449
发表于 2017-10-6 23:07:20 | 显示全部楼层
版主真是给力啊

4

主题

104

帖子

2183

积分

金牌会员

Rank: 6Rank: 6

积分
2183
发表于 2017-10-8 12:05:17 | 显示全部楼层
如果把数据传输方式设置为:变长;是不是用通用的APP好控制点呢?用定长,1小时3600秒,要分开来控制多少分钟还要算下,很不方便,

点评

在真实的开发中,app是不会让你选择多少秒的!而是让用户选择一个时间点,之后让程序计算时间差来发送给下位机的。当然啦,我这个是简单的。  详情 回复 发表于 2017-10-9 20:49

0

主题

2

帖子

66

积分

注册会员

Rank: 2

积分
66
发表于 2017-10-9 10:48:12 | 显示全部楼层
免费使用STM32、APP自动代码生成工具
谢谢  ,很详细 受益匪浅。感激!
 楼主| 发表于 2017-10-9 20:49:39 | 显示全部楼层
peter58 发表于 2017-10-8 12:05
如果把数据传输方式设置为:变长;是不是用通用的APP好控制点呢?用定长,1小时3600秒,要分开来控制多少分 ...

在真实的开发中,app是不会让你选择多少秒的!而是让用户选择一个时间点,之后让程序计算时间差来发送给下位机的。当然啦,我这个是简单的。
1、机智云Adnroid开源框架QQ交流群: 434878850

QQ群目前非常活跃,欢迎大家参与进来,交流,讨论,答疑,解惑~~
2、机智云微信公众号: 机智云 gizwits /   机智云智能宠物屋go-iot
关注机智云Gizwits官方公众号随

0

主题

8

帖子

88

积分

注册会员

Rank: 2

积分
88
发表于 6 天前 | 显示全部楼层
12222如何连接

0

主题

3

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 5 天前 | 显示全部楼层
注册成为机智云开发者,手机加虚拟设备快速开发
本帖最后由 chengwh 于 2017-10-12 17:05 编辑

有app方面编辑修改的东西就更好了

点评

最近比较忙,app方面修改会出视频的  详情 回复 发表于 3 天前
 楼主| 发表于 3 天前 | 显示全部楼层
chengwh 发表于 2017-10-12 16:56
有app方面编辑修改的东西就更好了

最近比较忙,app方面修改会出视频的
1、机智云Adnroid开源框架QQ交流群: 434878850

QQ群目前非常活跃,欢迎大家参与进来,交流,讨论,答疑,解惑~~
2、机智云微信公众号: 机智云 gizwits /   机智云智能宠物屋go-iot
关注机智云Gizwits官方公众号随

0

主题

8

帖子

156

积分

注册会员

Rank: 2

积分
156
发表于 前天 13:32 | 显示全部楼层
又学到了,谢谢
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

© 2011-2017 Gizwits ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表