大胖森

  • 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

  • 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)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 rbTail)     {         tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);         if (count 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来实现的。

最近访客

< 1/1 >

统计信息

已有6人来访过

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

留言

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


现在还没有留言