大胖森

  • 2018-10-09
  • 发表了主题帖: ESP8266 NodeMcu机智云SOC方案开发经验分享

    实现的功能:LED_1和LED_2可以同时用APP和KEY1和KEY2按键(短按)控制适合入门级萌新,大佬请略过,谢谢! 功能:LED_1和LED_2可以同时用APP和KEY1和KEY2按键(短按)控制 一、硬件电路及开发环境的搭建 1.硬件电路 首先是从某宝购买WIFI模块ESP8266 NodeMcu,我买的下图这款,4M内存不可接天线,应该是13.5元包邮。现在一直在用,感觉还比较稳定,那种可接天线内存小的还没用过不知咋样。其他的元器件,有两个LED,两个微动开关,面包板,杜邦线若干,5v直流电源。 https://img-blog.csdn.net/2018100721314161?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 有个情况要说明下,这种WIFI模块有两种,一种正常工作时右上角蓝色LED不闪,只有通电时闪一下;另一种是正常工作和通电时都会闪。我买了两块,刚好碰到这两种情况,开始以为是坏的,哈哈。 (1)电路图 https://img-blog.csdn.net/20181007213124683?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 (2)电路实物图 https://img-blog.csdn.net/20181007213416442?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 2.开发环境的搭建 如果是Windows 64位操作系统,可以下载下面这个集成开发环境 链接:https://pan.baidu.com/s/1CdruAWopdVWMEzxKOEJ4uA 提取码:12ct 如果不是的话,可以在百度“乐鑫集成开发环境”,应该很容易找到。 下载好后压解到一个你喜欢的地方,我习惯压解在D盘,压解好后就下图这样。桌面也会出现AiThinker_IDE和ConfigTool两个快捷图标。 https://img-blog.csdn.net/20181007214249794?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 打开这个压解好的AiThinkerIDE_V0.5文件夹,蓝框里面EXE文件对应桌面上的两个图标 https://img-blog.csdn.net/20181007214319726?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 打开蓝框里ConfigTool.exe,下图1,2路径对应上图红框中的内容。如果电脑已经装过eclipse,可以选择安装好的eclipse 的路径。然后点击注册3,再点击保存4,窗口会自动退出。开发环境就配置好了。 https://img-blog.csdn.net/20181007214425767?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 可以点击蓝框里的AiThinker_IDE.exe或者点击桌面的快捷方式图标就可进入开发环境。 https://img-blog.csdn.net/20181007214451258?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 二、机智云开发者中心 接下来是机智云开发者中心上的操作。注册账号应该是基本操作,就不费时间写了。主要讲数据点和自动生成的程序和下载测试APP。进入开发者中心 创建产品 https://img-blog.csdn.net/20181007214503644?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70产品分类:自定,影响不大; 产品名称:自定,影响不大; 技术方案:Wi-Fi/移动网络方案; 通讯方式:Wi-Fi 数据传输方式:定长 https://img-blog.csdn.net/20181007214515437?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 3.产品创建好后 https://img-blog.csdn.net/20181007214530522?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 4.打开创建好的产品 https://img-blog.csdn.net/20181007214545385?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 5.点击显示完整秘钥,输入登入密码Product Secret就会完整显示,将黑色隐藏的Product Key和显示的Product Secret复制到一个记事本中,以后有用。 6.点击左侧数据点,创建数据点。我创建好的数据点如下 https://img-blog.csdn.net/20181007214626510?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 下面两个数据点不用创建,我之前打算用DHT11温湿度传感器来获取temperature温度和humidity湿度,可能是模块坏了,一直读不到值,所以这里就不做介绍了。 我这里使用了两个可写布尔值的数据点,LED_1和LED_2,用于控制LED的开关。(有条件的可以买继电器,通过控制继电器来控制家里的220v电灯或者插座的开关。废话一句,哈哈)。 Tips:标识名可以自定,但是最好让人比较容易看懂,创建好后点应用。 7.点左侧MCU开发,选择右侧SOC方案 粘贴上复制在记事本中的Product Secret ,点击生产代码包,生成好后,点击下载 https://img-blog.csdn.net/20181007214708318?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 8.下载测试APP,点击顶部下载中心 https://img-blog.csdn.net/20181007214834164?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 进入下载中心后,点击左侧“机智云Wi-Fi/移动通信产品调试APP” https://img-blog.csdn.net/20181007214844885?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 可选择扫码下载,安装在手机上,以备后用。 https://img-blog.csdn.net/20181007214906424?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 三、修改自动生成的代码、编译并烧录 1.修改代码 将上面第7步下载好的压缩包压解到桌面(位置自定,根据个人习惯),打开开发环境软件,也就是这个 https://img-blog.csdn.net/20181007215013239?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 打开后是这样 https://img-blog.csdn.net/201810072150247?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 然后是导入压解好的代码包 点击左上角File,然后是import https://img-blog.csdn.net/20181007215053141?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 点击C/C++,然后点击Existing Code as Makefile Project https://img-blog.csdn.net/20181007215107987?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 数字1处选择代码压解到的位置,数字2处选择第3个 https://img-blog.csdn.net/20181007215131411?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 导入好后,展开文件夹,并双击打开左侧红框内的文件,按照右侧红框内容修改。 大概第22行:改BOOT?=new、改APP?=1、如果只有两个数据点改SPI_SIZE_MAP?=2。 https://img-blog.csdn.net/20181007215216639?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 如下图展开文件夹,要修改的就是下面红框中的5个文件 https://img-blog.csdn.net/20181007215418667?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 首先打开gizwits_product.h,定义一个矩阵extern bool STA[2];用于存储数据点LED_1和LED_2的状态。 https://img-blog.csdn.net/20181007215433778?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 然后打开gizwits_product.c,初始化定义的矩阵bool STA[2]={0}; https://img-blog.csdn.net/20181007215447750?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 找到 int8_t ICACHE_FLASH_ATTR gizwitsEventProcess(eventInfo_t *info, uint8_t *data, uint32_t len) 大概在47行,黑框中的为机智云上定义的数据点名称,红光中的为添加的内容。 https://img-blog.csdn.net/20181007215502673?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 Tips:这个板子和我们常见的板子(51、STM32)不一样,它的IO口置1时,实际输出低电平。 我们的LED是用的共阳机接法,详见电路图。 然后是扫描数据点LED_1和LED_2的状态,并上报,添加红框中的两条代码 #define USER_TIME_MS   100 #define LED_TIMEOUT (100/USER_TIME_MS)  定义100ms https://img-blog.csdn.net/20181007215608549?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 这两条添加到user_main.c里面,避免编译的时候出现错误 https://img-blog.csdn.net/20181007215627752?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 另外改gizwits_protocol.c 中的 #define USER_TIME_MS   100 可以降低控制延时 https://img-blog.csdn.net/20181007215652504?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 找到gizwits_protocol.c 中的void ICACHE_FLASH_ATTR userHandle(void),这个上报程序 添加以下代码 GPIO_OUTPUT_SET(GPIO_ID_PIN(4),!STA[0]); GPIO_OUTPUT_SET(GPIO_ID_PIN(5),!STA[1]); static uint8_t ledtime=0;   //每100ms上报一次数据点状态 ledtime++; if(LED_TIMEOUT<ledtime) { ledtime=0; currentDataPoint.valueLED_1=STA[0]; currentDataPoint.valueLED_2=STA[1]; }1 https://img-blog.csdn.net/20181007215713938?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 找到下面的void ICACHE_FLASH_ATTR userInit(void),这个是数据点初始化 修改如下 currentDataPoint.valueLED_1 = 0; currentDataPoint.valueLED_2 = 0; https://img-blog.csdn.net/20181007215738329?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 然后是改user_main.c文件,找到大概第55行 按如下修改 #define GPIO_KEY_NUM                            2              // 定义总按键数 #define KEY_0_IO_MUX                            PERIPHS_IO_MUX_GPIO0_U // #define KEY_0_IO_NUM                            0 #define KEY_0_IO_FUNC                           FUNC_GPIO0 #define KEY_1_IO_MUX                            PERIPHS_IO_MUX_GPIO2_U #define KEY_1_IO_NUM                            2 #define KEY_1_IO_FUNC                           FUNC_GPIO2 https://img-blog.csdn.net/20181007215757301?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 接下来改KEY1也就是GPIO0对应的开关 LOCAL void ICACHE_FLASH_ATTR key1ShortPress(void)   //KEY1短按 { if(STA[0]=!STA[0])    //取反,判断开关是否按下 GIZWITS_LOG("#### GPIO0 short press ,LED_1 ON\n");  //日志elseGIZWITS_LOG("#### GPIO0 short press ,LED_1 OFF\n");  //日志12345 } /** Key1 key presses a long press@param none@return none */ LOCAL void ICACHE_FLASH_ATTR key1LongPress(void)   //KEY1长按 { GIZWITS_LOG("#### GPIO0 long press, SOFTAP ON\n");  //日志 gizwitsSetMode(WIFI_SOFTAP_MODE);   //设置为局域网模式 https://img-blog.csdn.net/20181007215822691?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 接下来改KEY2也就是GPIO2对应的开关 LOCAL void ICACHE_FLASH_ATTR key2ShortPress(void)  //KEY2短按 { if(STA[1]=!STA[1])   //取反,判断开关是否按下 GIZWITS_LOG("#### GPIO2 short press, LED_2 ON \n");  //日志 elseGIZWITS_LOG("#### GPIO2 short press, LED_2 OFF \n");  //日志123 } /** Key2 button long press@param none@return none */ LOCAL void ICACHE_FLASH_ATTR key2LongPress(void)   //KEY2长按 { GIZWITS_LOG("#### GPIO2 long press, AIRLINK ON\n");  //日志 gizwitsSetMode(WIFI_AIRLINK_MODE);  //设置为联网模式 } } https://img-blog.csdn.net/20181007215849532?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 端口初始化 LOCAL void ICACHE_FLASH_ATTR keyInit(void) { singleKey[0] = keyInitOne(KEY_0_IO_NUM, KEY_0_IO_MUX, KEY_0_IO_FUNC, key1LongPress, key1ShortPress); singleKey[1] = keyInitOne(KEY_1_IO_NUM, KEY_1_IO_MUX, KEY_1_IO_FUNC, key2LongPress, key2ShortPress); keys.singleKey = singleKey; keyParaInit(&keys); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4);//配置LED_1管脚为输出 GPIO_DIS_OUTPUT(GPIO_ID_PIN(4)); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5);//配置LED_2管脚为输出 GPIO_DIS_OUTPUT(GPIO_ID_PIN(5)); GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 0);//输出高电平 GPIO_OUTPUT_SET(GPIO_ID_PIN(5), 0);//输出高电平 } https://img-blog.csdn.net/20181007215942205?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 所有的代码都修改好了,开始编译,右击项目名,点击Build Project https://img-blog.csdn.net/20181007220028485?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 编译成功 https://img-blog.csdn.net/20181007220041853?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 烧录,烧录工具可以下载我这个 链接:https://pan.baidu.com/s/1_Bhds-uE9GreQpfVwJ2m7g 提取码:e0kr https://img-blog.csdn.net/20181007220053317?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 下载好后,打开ESPFlashDownloadTool_v3.6.4.exe这个程序,点击第一个 https://img-blog.csdn.net/20181007220113937?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 选择编译好的文件,路径、COM仅供参考,根据实际情况设置。下面的设置如下图 C:\Users\Administrator\Desktop\SoC_ESP8266_32M_source\bin\boot_v1.6.bin 0x00000 C:\Users\Administrator\Desktop\SoC_ESP8266_32M_source\bin\upgrade\user1.4096.new.4.bin 0x01000 C:\Users\Administrator\Desktop\SoC_ESP8266_32M_source\bin\esp_init_data_default.bin 0x3fc000 C:\Users\Administrator\Desktop\SoC_ESP8266_32M_source\bin\blank.bin 0x3fe000 https://img-blog.csdn.net/20181007220205672?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 终于弄完了软硬件,终于到看成果的时候了,是不是很激动。 还有一步没完成,配网。 首先,你的手机要连上你家里的WIFI。 打开下载的机智云手机APP,点击跳过,不用登入 https://img-blog.csdn.net/20181007220347922?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 点击右上角的+号,点击一键配置 https://img-blog.csdn.net/20181007220404624?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 填入你家里WIFI账号和密码 https://img-blog.csdn.net/20181007220420954?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 选择乐鑫,点击确定 https://img-blog.csdn.net/20181007220432159?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 长安KEY2键,3S以上松开,点击手机上的“我已完成上述操作” https://img-blog.csdn.net/2018100722045458?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 配网成功 https://img-blog.csdn.net/20181007221638807?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 https://img-blog.csdn.net/20181007221719407?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM1MzE2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 LED_1和LED_2可以同时用APP和KEY1和KEY2按键(短按)控制了。 祝君成功!!! That’s  all,  thanks for your reading. 写得比较琐粹,大佬请略过。。。 未完待续。。。

  • 2018-09-28
  • 回复了主题帖: 【开源方案】智能鱼缸控制器

    swordroo 发表于 2018-8-31 17:13 硬件平台是现成的吗? 机智云可以这样玩? 我也去了解一下~ 感谢分享~~!
    是啊

  • 回复了主题帖: 【开源方案】智能鱼缸控制器

    wlbyq 发表于 2018-9-18 23:10 机智云? 感谢分享
    用的是机智云的云服务 和 他们的工具

  • 2018-08-02
  • 发表了主题帖: 【开源方案】智能鱼缸控制器

    replyreload += ',' + 2387426;本次项目主要目的是实现鱼缸温度自动控制,水循环的自动控制和手动控制。 本次设计不再采用本地温度调节,一个按键用于配网即可。 物料准备: 2个温度传感器(防水型DS18B20)用于检测循环箱和鱼缸温度 继电器3个,一个用于常温水蓄水罐抽水和废水放水(合用一个,保证水位平衡),一个用于循环水送水(可接制氧机),一个用于循环水升温。 方案优势: 采用esp8266 SOC方案,节省成本 ——————进入正文—————— 第一步:在机智云自助开发平台创建“智能鱼缸”产品,建立数据点 http://club.gizwits.com/data/attachment/forum/201808/02/101559y5ti28s1x93f31kg.jpg.thumb.jpg 创建一个新产品,建立以下数据点 显示名称:加热开关 标识名:Heating_switch 读写类型:可写 数据类型:布尔值 备注: 加热开关 显示名称:循环开关 标识名:Cir_water_switch 读写类型:可写 数据类型:布尔值 备注: 循环水开关 显示名称:排水开关 标识名:drain_off_water 读写类型:可写 数据类型:布尔值 备注: 无 显示名称:模式设定 标识名:auto_mode 读写类型:可写 数据类型:枚举 枚举范围:0.自动调整 1.手动控制 备注: 无 显示名称:循环水温 标识名:Heating_box_temperature 读写类型:只读 数据类型:数值 数据范围:0 - 99 分辨率:1 增量:0 备注: 无 显示名称:鱼缸水温 标识名:fishbowl_temperature 读写类型:只读 数据类型:数值 数据范围:0 - 99 分辨率:1 增量:0 备注: 无 显示名称:温度上限 标识名:Max_temperature 读写类型:可写 数据类型:数值 数据范围:0 - 99 分辨率:1 增量:0 备注: 无 显示名称:温度下限 标识名:Min_temperature 读写类型:可写 数据类型:数值 数据范围:0 - 99 分辨率:1 增量:0 备注: 无 http://club.gizwits.com/data/attachment/forum/201808/02/102047mdmtpq5t8wf55mtx.jpg.thumb.jpg 创建好数据点之后生成SOC代码。 http://club.gizwits.com/data/attachment/forum/201808/02/102123ozm11lm55r4rrlq7.jpg.thumb.jpg 第二步:下载SOC代码,在ESP8266上烧写固件 代码此处不在介绍,项目在附件。自行查看代码。 ESP8266 SOC方案是指ESP8266同时作为微控制器和wifi模块 http://club.gizwits.com/data/attachment/forum/201808/02/101255nddpdu8m808d884e.jpg.thumb.jpg 接线如下 GPIO0            配网开关(短按SOFTAP,长按AIRLINK)GPIO4            循环温度传感器GPIO5            水箱温度传感器GPIO12          加热开关GPIO13          循环开关GPIO14          排水开关 程序基本思路 实现远程设置鱼缸温度范围,系统自动调节温度,缓慢调节温度,升温是在循环里面进行升温,而起是平衡升温。防止水温过高,升温过程中,需要和循环搭配完成。2个18B20不采用单总线,单独采集。 源码太大,上传云盘了,回帖可获取 游客,如果您要查看本帖隐藏内容请回复

  • 2018-07-17
  • 发表了主题帖: 杰杰带你解读【机智云】环形缓冲区源码

    本文转载自:  mp.weixin.qq.com/s/iBrIu6RyEx_s-MVVkv1RRQ 前言大家晚上好,我是杰杰,上个星期,研究了一下机智云的源码,也不能说是研究吧,就是看了看,人家既然能拿来做商业用,还是有很厉害的地方的,如果还不知道什么叫环形缓冲区(环形队列)的同学,请看——STM32进阶之串口环形缓冲区实现好啦。多余的话不多说,看看他们的东西比我写的好在哪吧,原理都是一样的,但是效率会比我的搞,可能应用的地方也不一样,所以,先看看吧。 ringbuffer.h先看看头文件:ringbuffer.h。主要是用宏实现了一个求最小值的函数。还有就是定义了一个环形缓冲区的结构体。
    #define min(a, b) (a)<(b)?(a):(b)                   ///< Calculate the minimum value typedef struct {     size_t rbCapacity;     uint8_t  *rbHead;     uint8_t  *rbTail;     uint8_t  *rbBuff; }rb_t;
    看英文就能知道意思了,rb是ringbuff的缩写,意思就是环形缓冲区,结构体中rbCapacity是缓冲区的容量,也就是大小。结构体中rbHead是缓冲区的头指针,rbTail是缓冲区的尾指针,而rBuff是缓冲区的首地址,在创建的时候就用到。ringbuffer.c环形缓冲区的创建下面来看看源文件:
    int8_t ICACHE_FLASH_ATTR rbCreate(rb_t* rb) {     if(NULL == rb)     {         return -1;     }     rb->rbHead = rb->rbBuff;     rb->rbTail = rb->rbBuff;     return 0; }
    这是个创建环形缓冲区的函数,就是初始化了环形缓冲区的头尾指针,这个函数的通用性很强,因为很多时候不只创建一个缓冲区。每个缓冲区的首地址都保存在了rbBuff,这个在后面的通用性会很好用。但是杰杰还是觉得不够好,因为我们在结构体中定义了缓冲区的容量,但是在这里并没有给他初始化,我觉得应该传入应该参数,给缓冲区的容量进行初始化一下。但是无所谓啦。环形缓冲区的删除
    int8_t ICACHE_FLASH_ATTR rbDelete(rb_t* rb) {     if(NULL == rb)     {         return -1;     }     rb->rbBuff = NULL;     rb->rbHead = NULL;     rb->rbTail = NULL;     rb->rbCapacity = 0;         return 0; }
    把这些指针指向NULL,但是环形缓冲区本身地址的数据是不会被清除的,只是表明了这些地址可以被重复使用了而已。
    int32_t ICACHE_FLASH_ATTR rbCapacity(rb_t *rb) {     if(NULL == rb)     {         return -1;     }     return rb->rbCapacity; }
    获取环形缓冲区的容量
    int32_t ICACHE_FLASH_ATTR rbCapacity(rb_t *rb) {     if(NULL == rb)     {         return -1;     }     return rb->rbCapacity; }
    因为可能有多个环形缓冲区,但是容量我们不一定会知道,所以还是写一个获取它容量的函数比较好。环形缓冲区可读数据大小
    int32_t ICACHE_FLASH_ATTR rbCanRead(rb_t *rb) {     if(NULL == rb)     {         return -1;     }     if (rb->rbHead == rb->rbTail)     {         return 0;     }     if (rb->rbHead < rb->rbTail)     {         return rb->rbTail - rb->rbHead;     }     return rbCapacity(rb) - (rb->rbHead - rb->rbTail); }
    如果缓冲区是没有被创建的,那么返回-1,表示非法,如果环形缓冲区的首尾都在一个位置,那么表面环形缓冲区没有数据,那么是不可读的,否则就返回正常的数据,rb->rbTail - rb->rbHead / rbCapacity(rb) - (rb->rbHead - rb->rbTail),请用数学的方法理解这段代码。获取环形缓冲区可写数据大小同理获取可写数据也是一样的
    int32_t ICACHE_FLASH_ATTR rbCanWrite(rb_t *rb) {     if(NULL == rb)     {         return -1;     }     return rbCapacity(rb) - rbCanRead(rb); }
    环形缓冲区读数据
    int32_t ICACHE_FLASH_ATTR rbRead(rb_t *rb, void *data, size_t count) {     int32_t copySz = 0;     if(NULL == rb)     {         return -1;     }     if(NULL == data)     {         return -1;     }     if (rb->rbHead < rb->rbTail)     {         copySz = min(count, rbCanRead(rb));         memcpy(data, rb->rbHead, copySz);         rb->rbHead += copySz;         return copySz;     }     else     {         if (count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff))         {             copySz = count;             memcpy(data, rb->rbHead, copySz);             rb->rbHead += copySz;             return copySz;         }         else         {             copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff);             memcpy(data, rb->rbHead, copySz);             rb->rbHead = rb->rbBuff;             copySz += rbRead(rb, (char*)data+copySz, count-copySz);             return copySz;         }     } }
    如果是缓冲区没被创建或者是读数据地址非法(NULL)都将返回错误。如果rb->rbHead < rb->rbTail,就是可读数据的地址是递增的,那么可以直接读数据,读取的最大数据不能超过缓冲区可读最大数据,所以要用copySz = min(count, rbCanRead(rb));限制一下读取数据的大小,因为是直接拷贝数据,所以,在较多数据面前的话,这种做法很好,比如像网络上的数据,更是适合用这种方法。读完之后把rbHead 头指针重新更新,rb->rbHead += copySz;因为环形缓冲区在数据存储(软件地址上)是环形的,所以,假如数据地址不是递增的,那么无法直接拷贝,需要分段拷贝,count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff)如果要读取的数据小于从环形缓冲区的首地址开始到环形缓冲区大小的地址,那么这段地址还是递增的,所以可以直接拷贝过去,并且把头指针更新一下。
    copySz = count; memcpy(data, rb->rbHead, copySz); rb->rbHead += copySz;
    最后一种情况就是,需要分段读取了,先把头指针到缓冲区最后一个地址的这部分读取了,再加上从缓冲区首地址开始读取count-copySz那么长数据的数据,就ok了。然后把两端数据拼接起来。数据保存在data中。
    copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff); memcpy(data, rb->rbHead, copySz); rb->rbHead = rb->rbBuff; copySz += rbRead(rb, (char*)data+copySz, count-copySz);
    环形缓冲区写数据
    int32_t ICACHE_FLASH_ATTR rbWrite(rb_t *rb, const void *data, size_t count) {     int32_t tailAvailSz = 0;     if((NULL == rb)||(NULL == data))     {         return -1;     }     if (count >= rbCanWrite(rb))     {         return -2;     }     if (rb->rbHead <= rb->rbTail)     {         tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);         if (count <= tailAvailSz)         {             memcpy(rb->rbTail, data, count);             rb->rbTail += count;             if (rb->rbTail == rb->rbBuff+rbCapacity(rb))             {                 rb->rbTail = rb->rbBuff;             }             return count;         }         else         {             memcpy(rb->rbTail, data, tailAvailSz);             rb->rbTail = rb->rbBuff;             return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);         }     }     else     {         memcpy(rb->rbTail, data, count);         rb->rbTail += count;         return count;     } }
    与读书同理的,将一定长度的数据从某段地(data)址写入环形缓冲区。如果数据地址非法或者是可写数据长度不够,那么就会返回错误代码。先看后面的
        else     {         memcpy(rb->rbTail, data, count);         rb->rbTail += count;         return count;     }
    如果写数据的地址是地址的话,那么是可以直接写的,注意的是,写数据的地址并非读数据的地址,刚好相反的,可读数据的地址是绝对不允许写的。同理,假如写书的地址不是递增的话,那么,也是分成两段,假如写入数据的长度小于从尾指针到环形缓冲区最后一个地址的长度,那么,写入的这段数据其实其地址也是递增的,同样是可以直接写的,然后更新一下尾指针。
    memcpy(rb->rbTail, data, count);   rb->rbTail += count;   if (rb->rbTail == rb->rbBuff+rbCapacity(rb)) {     rb->rbTail = rb->rbBuff; }
    否则,也需要分段写入,先写入从尾指针到环形缓冲区最后一个地址的长度,然后从环形缓冲区的首地址开始再写入剩下的数据长度count-tailAvailSz,
    memcpy(rb->rbTail, data, tailAvailSz); rb->rbTail = rb->rbBuff; return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);
    好了,至此,源码基本分析完毕,现在说说为什么比我的源码写得好, 第一点,代码的效率,我写的源码是一个个数据的写入,而机智云是一系列数据的写入。读数据也是一样,一系列数据读出,而我的源码则是一个个数据读出,并且使用了求模的运算防止指针越界,这在运算中效率是不够高的。 第二代码的健壮性,还是机智云的好,我的代码是没有检查是否真正有有效的数据写入。同样的代码读出也是检查了读出数据的地址是否真正有效,防止数据非法丢失。总的来说,需要不断成长,还是要研究研究别人商业上用的源码,虽然说很多原理我们都知道,但是亲自写的话,不一定能写得出来, 还有就是,重用现有源码比创新的效率更高,因为并不是所有人都能另走捷径,做开拓者的,我们用已有的好东西足以。 END需要源码的同学可以在公众号回复“机智云源码”晚安!

  • 2018-07-16
  • 发表了主题帖: STM32+机智云WebSocket实现物联网游戏

    0、简介  本人在大学本科最后的一个课程设计,做的比较有趣味,同时最近的物联网逐渐大热,所以分享一下自己的作品设计过程。作品是在机智云最为简单的STM32核心板例程上开展的,使用到的通信协议是机智云写好的机智云连接固件,网页编程也是机智云的WebSocket Demo。本人做的是在原有的核心系统上添加别踩白块的物联网游戏功能。实现效果如下:                   http://club.gizwits.com/data/attachment/forum/201807/16/142249qadt2gbdrm56gwg2.jpg.thumb.jpg          https://images2018.cnblogs.com/blog/837605/201807/837605-20180714211020389-616983121.png优酷视频地址:http://player.youku.com/embed/XMzcyMzU0NjE0OA==得到的效果就是在网页上JavaScript 别踩白块游戏显示数据通过WebSocket发送到机智云控制平台,然后机智云下发到STM32,实现网页游戏显示与STM32显示同步(实际会有一点网络延迟)。 1、实现设备  1)SmarKit - ESP STM32核心板  2)机智云平台,注册一个开发者账号  3)0.96寸的OLED显示屏(四针,IIC通信)  4)机智云websocket Demo 加上简单的别踩白块游戏JS    5)烧录好机智云固件的ESP8266 (固件下载地址:https://download.gizwits.com/zh-cn/p/92/94) 2、实现步骤  2.1编写STM32硬件程序    在机智云的协议头文件修改自己的设备信息(在机智云创建设备后获取到):    https://images2018.cnblogs.com/blog/837605/201807/837605-20180714213612023-831672810.png http://club.gizwits.com/data/attachment/forum/201807/16/142300hb16356mzu56mm33.jpg.thumb.jpg    添加别踩白块数据的宏定义,在这我是使用两个uint8_t类型数据来传输,因为显示的白块位置共16个,原本打算用uint16_t传输的,但是需要修改整套的机智云上传包格式,所以我就直接拆分两段数据传输,宏定义是为了方便后面编程使用:    https://images2018.cnblogs.com/blog/837605/201807/837605-20180714213722324-567987899.png http://club.gizwits.com/data/attachment/forum/201807/16/142307g2b9a9ne9z9nbbb9.jpg.thumb.jpg    添加别踩白块的数据到传输包结构体:    https://images2018.cnblogs.com/blog/837605/201807/837605-20180714214524873-1980162803.png http://club.gizwits.com/data/attachment/forum/201807/16/142336i1p100hlwql347v5.jpg.thumb.jpg    游戏调度函数实现:    https://images2018.cnblogs.com/blog/837605/201807/837605-20180714215106682-1343167776.png http://club.gizwits.com/data/attachment/forum/201807/16/142344or7zhef4mbnbma2v.jpg.thumb.jpg       游戏计时显示         http://club.gizwits.com/data/attachment/forum/201807/16/142352r7lp5e399ca29295.jpg.thumb.jpg      https://images2018.cnblogs.com/blog/837605/201807/837605-20180714215152273-1371504025.png       机智云数据包获取后的事件响应函数添加:      https://images2018.cnblogs.com/blog/837605/201807/837605-20180714215301729-1023819356.pnghttp://club.gizwits.com/data/attachment/forum/201807/16/142401dhb2e7nlehtcbh17.jpg.thumb.jpg  2.2 网页别踩白块js与机智云websocket实现      具体的实现就是直接使用机智云提供的websocket的Demo添加上别踩白块的JS代码,实际的代码量有点大,这里不详细解说,后续会在文末给出整套代码。  https://images2018.cnblogs.com/blog/837605/201807/837605-20180714220655715-947689815.png http://club.gizwits.com/data/attachment/forum/201807/16/142539dhptttqnttpzn2ph.jpg.thumb.jpg  2.3 在机智云部署产品  首先就是在机智云创建一个自己的产品,以此来获取 Product Key,这个是机智云硬件的入网密匙。https://images2018.cnblogs.com/blog/837605/201807/837605-20180714220940770-748179450.pnghttp://club.gizwits.com/data/attachment/forum/201807/16/142550q2201t889819b8w8.jpg.thumb.jpg  添加数据节点:http://club.gizwits.com/data/attachment/forum/201807/16/142557hvvtzsdckzbddgg4.jpg.thumb.jpghttps://images2018.cnblogs.com/blog/837605/201807/837605-20180714221018425-142780150.png  2.4 配置网页控制信息 用网页控制接入到机智云的设备仍需要许多步骤,因为要保证设备安全,就必须实现用户与设备绑定,绑定需要获取响应的密令。具体的用户与设备绑定参考机智云官方的资料:http://docs.gizwits.com/zh-cn/UserManual/UseWebsocket.html配置成功效果如下:http://club.gizwits.com/data/attachment/forum/201807/16/142618ke5i54j4seeeiekj.jpg.thumb.jpghttps://images2018.cnblogs.com/blog/837605/201807/837605-20180714221833605-1380067025.png  2.5 websocke连接设备 https://images2018.cnblogs.com/blog/837605/201807/837605-20180714222255081-1414159340.png http://club.gizwits.com/data/attachment/forum/201807/16/142628k2zthsl7d7rpb2pj.jpg.thumb.jpg   2.6 测试物联网别踩白块游戏https://images2018.cnblogs.com/blog/837605/201807/837605-20180714222352910-670675831.pnghttp://club.gizwits.com/data/attachment/forum/201807/16/142635yr7ra77dc3cdfttv.jpg.thumb.jpg3、工程整套源代码  由于博客园的没有很好的文件分享端口,所以我就使用隔壁CSDN的文件分享:https://download.csdn.net/download/vitcou/10541825   如果有人想要用其他的STM32实现如此效果,就必须配置好机智云连接,我是直接使用烧录好机智云固件的ESP8266来实现的。

  • 2018-05-31
  • 发表了主题帖: Gokit3试用:STM32底板秒变Arduino板

    STM32可以直接变成Arduino板,并不局限于GOKIT的STM32底板,其他STM32板子也是同理,只要安装了下面的库就能实现arduino兼容STM32快速开发和DIY:https://github.com/rogerclarkmelbourne/Arduino_STM32库的安装很简单,就是把压缩包解压后复制到ARDUINO IDE根目录的hardware文件夹下,如图 http://b02.ickimg.com/201710/dae5177185acf9418266329844017d49.png 做完这一切准备工作我们就开始使用它了 1、首先打开ArduinoIDE,在开发板管理器里安装下图开发板支持库 http://b02.ickimg.com/201709/c64a06355ad23c995b434654a620611a.png 2、然后在工具中选择如下配置 http://b02.ickimg.com/201709/771b60e16e67b4b8148e5dc2e7778b44.png 3、找到blink实例 http://b02.ickimg.com/201709/46d5e5d6a7ae43a521967671e1cd4542.png 4、插上STM32底板的USB to UART接口,选择到SYSTEM端(注意:下载完成需要拨回Flash状态),然后编译下载 http://b02.ickimg.com/201709/158b3615867c92287db082fddadb7a02.jpghttp://b02.ickimg.com/201709/9129bbe791b3715ddea63afc140f7c23.jpg 5、你会看到久违的LED闪烁程序了 http://b02.ickimg.com/201709/669d9859ed719d0f9a9ccd270229e804.gif

  • 2018-05-23
  • 发表了主题帖: 【体验】+0基础实现GPRS远程插座

    准备材料: 一丶硬件部分 1.G510模块,可以在机智云淘宝店铺购买到,已经下载好固件的; 2.物联网卡一张 3.STM32F103最小系统板一块 4.插板一块 5.继电器一个(根据需求选择4 3 2 1位的继电器,我这儿采用2位继电器) 6.220转5V电源,可以拆手机充电器(建议用2A的,不能低于1A) 7.微动开关3个(一个用于继电器开关操作,此处我是长按开继电器1,短按开继电器2,还有一个用于STM32复位,还有一个用于GSM开机) 8.导线若干 9.电脑一台 10.ch340下载器(给STM32下载程序用,可以用其他的下载器) 二丶软件部分 1.keil MDK5 2.STM32CubeMX F1版本 3.浏览器 4.mcuisp下载软件(其他下载软件也可以) 5.机智云的手机APP(官网可以下载) 接下来开始制作 1.首先注册登陆机智云开发者中心 2.登陆之后点击右上角,创建新产品 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/120210ylcww9s50lczcelf.png 3.按照下图1234依次设置好参数,然后点5建立新的产品 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/120636fxfukxxpfuzkz7xf.png 4.点击左面数据点 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/120809ogiyzbffryff7aar.png 5.进入数据点之后,点击新建数据点,然后按照下图中步骤进行数据点的创建 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/121527msruucsv0ee3had1.png http://www.eeboard.com/bbs/data/attachment/forum/201803/12/121528igmzhgg1i3wos555.jpg http://www.eeboard.com/bbs/data/attachment/forum/201803/12/121529y2ww7zvw24ncmgcz.jpg http://www.eeboard.com/bbs/data/attachment/forum/201803/12/121529cj86imuun55innw6.jpg 然后点击应用,数据点就创建完毕了 6.点击左面菜单栏的基本信息,输入密码把Product Secret:完全显示了之后复制一下, http://www.eeboard.com/bbs/data/attachment/forum/201803/12/121905gbafbx6p5whud70b.jpg 7.点击菜单栏MCU开发,选择独立MCU方案,硬件平台选择STM32F103C8X,粘贴刚才复制的Product Secret,然后点击5生成代码包,等待生成代码包之后下载代码包。 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/122239aagiibauuxn2xzwa.png 8.到此处云平台的设置就完成了,接下来我们先编译生成代码生成hex下载到STM32里面(记住,先不要做任何修改,直接编译下载的文件),然后按照下面进行接线之后,通电运行(G510需要插入能上网的卡。电信卡不行) STM32   G510 PA2-------RxD PA3-------TxD GND------GND 5V--------VCC 通电运行过后云端产品里面设备日志就能看见当前的IMEI(GPRS的标识码),把这个标识码复制下来备用。一会儿要用到这个IMEI, http://www.eeboard.com/bbs/data/attachment/forum/201803/12/123357xmzq8m7c24477ww7.jpg 9.二维码的生成,由于新手按照官网教程生成的二维码总是不能用,我这儿就说一下我的步骤,按照我的步骤去生成肯定能用。 a.打开二维码生成地址 b.点击右上角 Authorize,在弹出对话框api_key里面输入”G”,并点击 “Authorize” 按钮 C.如果菜单没有自动打开,那么久点击default打开一下 d.展开之后点击创建二维码任务,然后把你产品的product_key复制过来粘贴在里面,product_key在产品基本信息菜单栏目里面,然后点击右边的Example Value,在左边就会看到如下内容 {   "start_mac": "string",   "end_mac": "string" } e.接下来就把2个string都换成我们复制的IMEI,然后点下面的Try it out! f.然后点击上面的查询二维码生成任务,输入 product_key,点击”Try it out!”,查询生成任务 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/124735svt2va0c66t6244v.png g.复制闪图箭头那一段,在浏览器输入http://qrcode.gizwitsapi.com:1800/加你复制那一段,就能下载生成的二维码了,由于GPRS要在手机上控制只能通过扫描二维码进行,所以此步骤绝对不能出错。 10.生成二维码之后就能用手机APP扫描二维码绑定设备了。 接下来说一下生成的工程,如果你还是打开keil的,那么就先关闭keil。找到下载的项目文件里面的STM32F103C8x.ioc。双击打开(需要安装了STM32CubeMX 才能打开),打开之后我们需要新增2个输出IO口用于继电器的控制,这里我新增了B3和B42个IO口,直接在PB3和PB4上面单击,选择GPIO_output,然后点击左上角剪头说是的图标生成代码,之后就完成了GPIO的初始化了,用的是hal库,会写hal的可以直接跳过此步骤。关闭STM32CubeMX 再次用keil打开工程。 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/125708k4cmof8i8aq44qf4.jpg 接下来我们用一个按键接到PA8,实现长按和短按控制2个不同继电器的开关 实现的方法就是修改void key2ShortPress(void)函数和void key2LongPress(void)函数,这里我采用2个布尔变量来表示开关状态,布尔变量是在gizwits_product的C和H函数定义的全局 具体定义地方参考最后我打包的代码,此处不再说明 按键内容修改成如下(可以直接进行取反操作,此处我写成if新手更容易看懂) void key2ShortPress(void) {         if(STA[0]) STA[0]=0;         else STA[0]=1; } void key2LongPress(void) {         if(STA[1]) STA[1]=0;         else STA[1]=1; } 然后找到主函数。在while循环里面加入端口的控制 if(STA[0]==1) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); else        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); if(STA[1]==1)HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET) ; else        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET); 打开gizwits_product.c,找到gizwitsEventProcess函数, 修改下面对应的内容 if(0x01 == currentDataPoint.valuesw1)         {           STA[0]=0;//user handle         }         else         {           STA[0]=1;//user handle            }         break;       case EVENT_sw2:         currentDataPoint.valuesw2 = dataPointPtr->valuesw2;         GIZWITS_LOG("Evt: EVENT_sw2 %d \n", currentDataPoint.valuesw2);         if(0x01 == currentDataPoint.valuesw2)         {           STA[1]=0;//user handle         }         else         {           STA[1]=1;//user handle            } 此处是处理云端的数据,直接对标志位进行取反即可(标志位要用于上报) 找到userHandle函数 修改内容为 void userHandle(void) {         if(STA[0]) currentDataPoint.valuesw1 = 0;                 else        currentDataPoint.valuesw1 = 1;         if(STA[1]) currentDataPoint.valuesw2 = 0;                 else        currentDataPoint.valuesw2 = 1; } 找到,数据点初始化函数userInit,修改内容为 void userInit(void) {     memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));       /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/       currentDataPoint.valuesw1 = 0;       currentDataPoint.valuesw2 = 0; } STA定义:在gizwits_product.c的头文件下面加入bool STA[2]={1}; 在gizwits_product.h头文件下面加入extern bool STA[2]; 编译下载到单片机,连接好硬件之后即可使用。附上我只做的图和源代码 如果有不懂地地方可以加我QQ问也可以加群交流点击链接加入群【电子技术交流】 http://www.eeboard.com/bbs/data/attachment/forum/201803/12/132329pybcycxmtne0lk77.jpg http://www.eeboard.com/bbs/data/attachment/forum/201803/12/132335kg6n9i9r73n9ui1e.jpg http://www.eeboard.com/bbs/data/attachment/forum/201803/12/132339hqhi63z7icucr6qc.gif

TA暂时无记录哦~

最近访客

< 1/1 >

统计信息

已有5人来访过

  • 芯币:40
  • 好友:--
  • 主题:8
  • 回复:3
  • 课时:--
  • 资源:--

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言