开源教程:基于ESP8266和机智云的智能雨林缸,成本低、高...-Arduino中文社区 - Powered by Discuz! Archiver

机智小子 发表于 2022-1-17 15:49

开源教程:基于ESP8266和机智云的智能雨林缸,成本低、高...

项目内容:1.灯光控制2.循环控制3.温度采集4.温度和喷淋自动控制(手动控制下加热和喷淋可控,自动模式下加热和喷淋不可控)5.状态断电记忆
https://club.gizwits.com/static/image/hrline/1.gif

云端部署:本次设计以esp8266作为主控,SOC方案,利用赛博坦工具快速生成APP。1.创建产品, 进入开发者中心,点击右上角,创建新产品,按照如图所示创建新的产品。https://club.gizwits.com/data/attachment/forum/202201/15/143913a68nnq8g88vsrws4.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202201/15/144142tqrx7x5yg77gh82d.png.thumb.jpg
2.创建数据点。https://club.gizwits.com/data/attachment/forum/202201/16/143927nsuhpz0rhvn8b8tz.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202201/16/143510sowpvq1opvhwkokz.png.thumb.jpg3.生成ESP8266_32M SOC代码,下载到电脑备用。https://club.gizwits.com/data/attachment/forum/202201/16/143510w8hju8zr0jmuj089.png.thumb.jpg4.由左上角的体验新版本切换到新版本开发者中心,点击右上角+创建一个新的移动应用。https://club.gizwits.com/data/attachment/forum/202201/16/143510fmgkx1o33kb9bioq.png.thumb.jpg5.点开创建好的应用,关联设备到移动应用里面。其他参数根据自己需求进行更改https://club.gizwits.com/data/attachment/forum/202201/16/143511br6m9o7700ma70hh.png.thumb.jpg6.回到新版本主页,在左侧选择自己创建的产品,然后进行模组配置。配置成乐鑫模组,注意只需要修改模组就行,热点参数无需更改。https://club.gizwits.com/data/attachment/forum/202201/16/143511me5jewe6360bjej0.png.thumb.jpg7.进入应用页面,进行控制页面修改。https://club.gizwits.com/data/attachment/forum/202201/16/143511qt4v626gj215rwtm.png.thumb.jpg8.根据自己需求设置好控制模块的大小以及图标。其余参数根据自己的需求修改。级的每个页面都需要保存。https://club.gizwits.com/data/attachment/forum/202201/16/143511ryjjkkk13q63yqif.png.thumb.jpg9.配置好所有参数过后,回到之前创建的移动应用里面,进行应用的构建,构建成功以后扫描后面的二维码下载安装到手机,到此云端部署完成。https://club.gizwits.com/data/attachment/forum/202201/16/143512rt36dfownzrrf8nm.png.thumb.jpg
https://club.gizwits.com/static/image/hrline/1.gif

硬件接线:此项目不公开PCB,可以自己购买4路继电器,及防水温度传感器DS18B20探头,ESP12S小系统板。继电器----GPIO13(加热管)GPIO12(循环电机)GPIO16(喷淋电机)GPIO5(灯光)配网按键----GPIO14(按下低电平)温度传感器----GPIO4(传感器需要上拉电阻)https://club.gizwits.com/data/attachment/forum/202201/16/143512tvwktppo9czzp2c2.png.thumb.jpg
https://club.gizwits.com/static/image/hrline/1.gif

程序修改:       1.本次采用IDE方式进行开发编译(开发环境链接:https://pan.baidu.com/s/1TTIU-74mBxo9UqxLbX7Grw 提取码:0htq,解压过后即可使用,路径不能有中文),将前面下载的代码进行解压,路径不要含有中文。在IDE环境里面导入项目。导入步步骤易出错,注意根据下图中所示步骤进行导入。https://club.gizwits.com/data/attachment/forum/202201/16/143512fac15k2at3zrttt2.png.thumb.jpg
https://club.gizwits.com/data/attachment/forum/202201/16/143512ssmyj3d553jh4ul3.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202201/16/143512dnvdanvvdf8dvmdv.png.thumb.jpg       2.修改编译参数,打开根目录下面的Makefile文件,然后修改23到27行的内容。(注意:本教程代码不可以在网页上进行复制粘贴,由于编码不一致可能会导致程序不能编译,无法编译需要重新解压代码从头再来。代码需要自己手打。每次输入代码过后需要保存以后编译才会生效。)
[*]BOOT?=new
[*]APP?=1
[*]SPI_SPEED?=40
[*]SPI_MODE?=QIO
[*]SPI_SIZE_MAP?=6

复制代码

https://club.gizwits.com/data/attachment/forum/202201/16/143513huq6fou33x6z8q7k.png.thumb.jpg       3.按键部分无需修改,因为自动生成的代码就是gpio14按键长按短按进行网络配置。继电器引脚的初始化我们写在按键函数的初始化里面, 初始化为输出模式。
[*]GPIO_OUTPUT_SET(GPIO_ID_PIN(5),1);//灯光
[*]    GPIO_OUTPUT_SET(GPIO_ID_PIN(13),1);//加热管
[*]    GPIO_OUTPUT_SET(GPIO_ID_PIN(12),1);//循环电机
[*]    gpio16_output_conf();//喷淋电机

复制代码

https://club.gizwits.com/data/attachment/forum/202201/16/143513c1ysz77f7s1yv1ge.png.thumb.jpg4.在gizwits_product.c和gizwits_product.h增加全局变量。
[*]//flash相关
[*]#define sec 137 //137扇区,程序小于480K flash存储的安全区域的起始地址137-1024扇区
[*]#define sec1 138 //138扇区,程序小于480K flash存储的安全区域的起始地址137-1024扇区
[*]bool STATE = {0,0,0,0,0,0};//开机各个开关状态标识
[*]uint32_t Set_Temp=0;   //温度自动控制
[*]uint32_t Open_Time=0;       //喷淋开时间
[*]uint32_t Off_Time=0;    //喷淋关时间
[*]extern bool STATE;   //开机各个开关状态标识
[*]extern uint32_t Set_Temp;    //温度自动控制
[*]extern uint32_t Open_Time; //喷淋开时间
[*]extern uint32_t Off_Time;   //喷淋关时间

复制代码

https://club.gizwits.com/data/attachment/forum/202201/16/143513cwwf4elljwgfpjo9.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202201/16/143513fhii4ekioooblbhv.png.thumb.jpg       5.在gizwits_product.c的gizwitsEventProcess函数里面对开关状态进行缓存。程序带有注释,此处不做截图,具体参考下面的程序更改。(注意:此函数的是数据点下发过后,可写类型的数据处理,会根据数据点的不同而不同。程序不能再网页复制,会导致编码不一致程序出错)
[*]int8_t ICACHE_FLASH_ATTR gizwitsEventProcess(eventInfo_t *info, uint8_t *data, uint32_t len)
[*]{
[*]    uint8_t i = 0;
[*]    dataPoint_t * dataPointPtr = (dataPoint_t *)data;
[*]    moduleStatusInfo_t * wifiData = (moduleStatusInfo_t *)data;
[*]    if((NULL == info) || (NULL == data))
[*]    {
[*]      GIZWITS_LOG("!!! gizwitsEventProcess Error \n");
[*]      return -1;
[*]    }
[*]    for(i = 0; i < info->num; i++)
[*]    {
[*]      switch(info->event)
[*]      {
[*]      case EVENT_Water_Cycle :
[*]            currentDataPoint.valueWater_Cycle = dataPointPtr->valueWater_Cycle;
[*]            GIZWITS_LOG("Evt: EVENT_Water_Cycle %d \n", currentDataPoint.valueWater_Cycle);
[*]            if(0x01 == currentDataPoint.valueWater_Cycle)
[*]            {
[*]                   STATE=1;   //水循环打开
[*]            }
[*]            else
[*]            {
[*]                   STATE=0;   //水循环关闭
[*]            }
[*]            STATE=1;//flash存储状态
[*]            break;
[*]      case EVENT_Spray :
[*]            currentDataPoint.valueSpray = dataPointPtr->valueSpray;
[*]            GIZWITS_LOG("Evt: EVENT_Spray %d \n", currentDataPoint.valueSpray);
[*]            if(0x01 == currentDataPoint.valueSpray)
[*]            {
[*]                   if(STATE==0)
[*]                            {
[*]                        STATE=1;   //如果为手动模式,喷淋开关打开,否则不动作
[*]                        STATE=1;//flash存储状态
[*]                            }
[*]            }
[*]            else
[*]            {
[*]                   if(STATE==0)
[*]                   {
[*]                        STATE=0; //如果为手动模式,喷淋开关关闭,否则不动作
[*]                        STATE=1;//flash存储状态
[*]                   }
[*]            }
[*]            currentDataPoint.valueSpray = STATE;//更新数据点,APP更新
[*]            break;
[*]      case EVENT_Lamp :
[*]            currentDataPoint.valueLamp = dataPointPtr->valueLamp;
[*]            GIZWITS_LOG("Evt: EVENT_Lamp %d \n", currentDataPoint.valueLamp);
[*]            if(0x01 == currentDataPoint.valueLamp)
[*]            {
[*]                   STATE=1;   //灯光打开
[*]            }
[*]            else
[*]            {
[*]                   STATE=0;   //灯光关闭
[*]            }
[*]            STATE=1;//flash存储状态
[*]            break;
[*]      case EVENT_Heating :
[*]            currentDataPoint.valueHeating = dataPointPtr->valueHeating;
[*]            GIZWITS_LOG("Evt: EVENT_Heating %d \n", currentDataPoint.valueHeating);
[*]            if(0x01 == currentDataPoint.valueHeating)
[*]            {
[*]                   if(STATE==0)
[*]                   {
[*]                        STATE=1;   //如果为手动模式,加热开关打开,否则不动作
[*]                        STATE=1;//flash存储状态
[*]                   }
[*]            }
[*]                     else
[*]                     {
[*]                            if(STATE==0)
[*]                            {
[*]                                 STATE=0; //如果为手动模式,加热开关关闭,否则不动作
[*]                                 STATE=1;//flash存储状态
[*]                            }
[*]                     }
[*]                     currentDataPoint.valueHeating = STATE;//更新数据点,APP更新
[*]            break;
[*]      case EVENT_mode:
[*]            currentDataPoint.valuemode = dataPointPtr->valuemode;
[*]            GIZWITS_LOG("Evt: EVENT_mode %d\n", currentDataPoint.valuemode);
[*]            switch(currentDataPoint.valuemode)
[*]            {
[*]            case mode_VALUE0:
[*]                   STATE=0;   //手动模式
[*]                break;
[*]            case mode_VALUE1:
[*]                   STATE=1;   //自动模式
[*]                break;
[*]            default:
[*]                break;
[*]            }
[*]            STATE=1;//flash存储状态
[*]            break;
[*]      case EVENT_Set_Temperature:
[*]            currentDataPoint.valueSet_Temperature= dataPointPtr->valueSet_Temperature;
[*]            GIZWITS_LOG("Evt:EVENT_Set_Temperature %d\n",currentDataPoint.valueSet_Temperature);
[*]            Set_Temp = currentDataPoint.valueSet_Temperature;   //缓存设置温度
[*]            STATE=1;//flash存储状态
[*]            break;
[*]      case EVENT_Spray_Open_Time:
[*]            currentDataPoint.valueSpray_Open_Time= dataPointPtr->valueSpray_Open_Time;
[*]            GIZWITS_LOG("Evt:EVENT_Spray_Open_Time %d\n",currentDataPoint.valueSpray_Open_Time);
[*]            Open_Time = currentDataPoint.valueSpray_Open_Time;//缓存设置开时间
[*]            STATE=1;//flash存储状态
[*]            break;
[*]      case EVENT_Spray_Off_Time:
[*]            currentDataPoint.valueSpray_Off_Time= dataPointPtr->valueSpray_Off_Time;
[*]            GIZWITS_LOG("Evt:EVENT_Spray_Off_Time %d\n",currentDataPoint.valueSpray_Off_Time);
[*]            Off_Time = currentDataPoint.valueSpray_Off_Time;//缓存设置关时间
[*]            STATE=1;//flash存储状态
[*]            break;

复制代码

6. 接下来我们处理断电开机之后开关以及各项参数的初始化。主要是利用flash读取获取参数。数据状态存放在flash,后续教程及程序会有存储体现。初始化主要修改userInit函数。
[*]void ICACHE_FLASH_ATTR userInit(void)
[*]{
[*]    gizMemset((uint8_t *)¤tDataPoint, 0, sizeof(dataPoint_t));
[*]    //flash相关
[*]       uint32 value;
[*]       //定义数组addr_case1
[*]       uint8* addr_case1 = (uint8*)&value;//四字节对齐
[*]       uint8* addr_case2 = (uint8*)&value;//四字节对齐
[*]       //读取flash数据,sec*4*1024就是读取起始地址,就是具体的字节地址
[*]       spi_flash_read(sec*4*1024, (uint32*)addr_case1, sizeof(addr_case1));
[*]       spi_flash_read(sec1*4*1024, (uint32*)addr_case2, sizeof(addr_case2));
[*]       if(addr_case1==1) STATE=1;      //水循环
[*]            else STATE=0;
[*]       if(addr_case1==1) STATE=1;      //灯光
[*]            else STATE=0;
[*]       if(addr_case1==1) STATE=1;      //喷淋
[*]            else STATE=0;
[*]       if(addr_case1==1) STATE=1;      //加热
[*]            else STATE=0;
[*]       if(addr_case2==1) STATE=1;      //模式
[*]            else STATE=0;
[*]       currentDataPoint.valueSet_Temperature = (uint32_t)addr_case2;
[*]       currentDataPoint.valueSpray_Open_Time = (uint32_t)addr_case2;
[*]       currentDataPoint.valueSpray_Off_Time = (uint32_t)addr_case2;
[*]       currentDataPoint.valueWater_Cycle = STATE;
[*]       currentDataPoint.valueSpray = STATE;
[*]       currentDataPoint.valueLamp = STATE;
[*]       currentDataPoint.valueHeating = STATE;
[*]       currentDataPoint.valuemode = STATE;
[*]       currentDataPoint.valueTemperature = 0;
[*]       Set_Temp = currentDataPoint.valueSet_Temperature;
[*]       Open_Time = currentDataPoint.valueSpray_Open_Time;
[*]       Off_Time = currentDataPoint.valueSpray_Off_Time;
[*]       GPIO_OUTPUT_SET(GPIO_ID_PIN(12),!STATE);//水循环
[*]       GPIO_OUTPUT_SET(GPIO_ID_PIN(5),!STATE);//灯光
[*]}

复制代码

7.在gizwits_product.c新增DS18B20驱动函数。由于程序太长此处不再截图。
[*]/************************
[*]* 函 数 名         : Ds18b20Init
[*]* 函数功能            : 初始化
[*]* 输    入         : 无
[*]* 输    出         : 初始化成功返回1,失败返回0
[*]************************/
[*]uint8 Ds18b20Init() {
[*]       int i;
[*]       PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
[*]       GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 0);            //将总线拉低480us~960us
[*]       os_delay_us(642);         //延时642us
[*]       GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 1);   //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
[*]       while (GPIO_INPUT_GET(GPIO_ID_PIN(4))) //等待DS18B20拉低总线
[*]       {
[*]            os_delay_us(500);
[*]            os_delay_us(500);
[*]            i++;
[*]            if (i > 5)   //等待>5MS
[*]                            {
[*]                     return 0;//初始化失败
[*]            }
[*]       }
[*]       return 1;//初始化成功
[*]}
[*]/************************
[*]* 函 数 名         : Ds18b20WriteByte
[*]* 函数功能            : 向18B20写入一个字节
[*]* 输    入         : dat
[*]* 输    出         : 无
[*]************************/
[*]void Ds18b20WriteByte(uint8 dat) {
[*]       int i, j;
[*]       for (j = 0; j < 8; j++) {
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 0);               //每写入一位数据之前先把总线拉低1us
[*]            i++;
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(4), dat & 0x01);                //然后写入一个数据,从最低位开始
[*]            os_delay_us(70); //延时68us,持续时间最少60us
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 1);   //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
[*]            dat >>= 1;
[*]       }
[*]}
[*]/************************
[*]* 函 数 名         : Ds18b20ReadByte
[*]* 函数功能            : 读取一个字节
[*]* 输    入         : 无
[*]* 输    出         : byte
[*]************************/
[*]uint8 Ds18b20ReadByte() {
[*]       uint8 byte, bi;
[*]       int i, j;
[*]       for (j = 8; j > 0; j--) {
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 0);   //先将总线拉低1us
[*]            i++;
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(4), 1);       //然后释放总线
[*]            i++;
[*]            i++;   //延时6us等待数据稳定
[*]            bi = GPIO_INPUT_GET(GPIO_ID_PIN(4));    //读取数据,从最低位开始读取
[*]            /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
[*]            byte = (byte >> 1) | (bi << 7);
[*]            os_delay_us(48); //读取完之后等待48us再接着读取下一个数
[*]       }
[*]       return byte;
[*]}
[*]/************************
[*]* 函 数 名         : Ds18b20ChangTemp
[*]* 函数功能            : 让18b20开始转换温度
[*]* 输    入         : 无
[*]* 输    出         : 无
[*]************************/
[*]void Ds18b20ChangTemp() {
[*]       Ds18b20Init();
[*]       os_delay_us(500);
[*]       os_delay_us(500);
[*]       Ds18b20WriteByte(0xcc);             //跳过ROM操作命令
[*]       Ds18b20WriteByte(0x44);         //温度转换命令
[*]//   延时100ms 等待转换成功,而如果你是一直刷着的话,就不用这个延时了
[*]}
[*]/************************
[*]* 函 数 名         : Ds18b20ReadTempCom
[*]* 函数功能            : 发送读取温度命令
[*]* 输    入         : 无
[*]* 输    出         : 无
[*]************************/
[*]void Ds18b20ReadTempCom() {
[*]       Ds18b20Init();
[*]       os_delay_us(500);
[*]       os_delay_us(500);
[*]       Ds18b20WriteByte(0xcc);      //跳过ROM操作命令
[*]       Ds18b20WriteByte(0xbe);   //发送读取温度命令
[*]}
[*]/************************
[*]* 函 数 名         : Ds18b20ReadTemp
[*]* 函数功能            : 读取温度
[*]* 输    入         : 无
[*]* 输    出         : temp
[*]************************/
[*]float Ds18b20ReadTemp() {
[*]       float temp = 0;
[*]       uint8 tmh, tml;
[*]       uint32_t temp1;
[*]       Ds18b20ChangTemp();                  //先写入转换命令
[*]       Ds18b20ReadTempCom();               //然后等待转换完后发送读取温度命令
[*]       tml = Ds18b20ReadByte();          //读取温度值共16位,先读低字节
[*]       tmh = Ds18b20ReadByte();         //再读高字节
[*]       temp1 = tmh;
[*]       temp1 <<= 8;
[*]       temp1 |= tml;
[*]       temp = temp1*0.0625;
[*]       temp = ((temp+0.005)*100)/100;//保留2位小数,四舍五入
[*]       return temp;
[*]}

复制代码

在gizwits_product.c新增温度传感器的函数**。
[*]uint8 Ds18b20Init();
[*]void Ds18b20WriteByte(uint8 dat);
[*]uint8 Ds18b20ReadByte();
[*]void Ds18b20ChangTemp();
[*]void Ds18b20ReadTempCom();
[*]float Ds18b20ReadTemp();

复制代码

https://club.gizwits.com/data/attachment/forum/202201/16/143514i3bypmct7t9gety9.png.thumb.jpg       8.在gizwits_product.c的userHandle函数里面对GPIO输出点,温度采集,flash存储以及逻辑控制进行编写。此处不在截图。
[*]void ICACHE_FLASH_ATTR userHandle(void)
[*]{
[*]       //flash相关
[*]       uint32 value;
[*]       //定义数组addr_case1
[*]       uint8* addr_case1 = (uint8*)&value;
[*]       uint8* addr_case2 = (uint8*)&value;
[*]       LOCAL float tempvalue;//采集温度
[*]       LOCAL uint32_t opentime=0;//开计时
[*]       LOCAL uint32_t offtime=0;//关计时
[*]       LOCAL bool onoff=0;//开关状态,0关,1开
[*]       os_delay_us(642);
[*]       LOCAL uint8_t temp_time=0;//温度采集间隔时间
[*]       if(temp_time<=1)temp_time++;
[*]       else
[*]       {
[*]            temp_time=0;
[*]            tempvalue = Ds18b20ReadTemp();
[*]            currentDataPoint.valueTemperature = tempvalue;
[*]       }
[*]       if(STATE)//自动模式下喷淋和加热控制
[*]       {
[*]            //加热温度控制
[*]            if(tempvalue<(float)Set_Temp) STATE=1;
[*]                     else STATE=0;
[*]            //喷淋控制
[*]            if(onoff)//开状态
[*]            {
[*]                     if(opentime>0) opentime--;
[*]                     else
[*]                     {
[*]                            onoff=0;//切换关状态
[*]                            offtime=Off_Time*60;//赋值关闭时间
[*]                            STATE=0;
[*]                     }
[*]            }
[*]            else if(onoff==0)//关状态
[*]            {
[*]                     if(offtime>0) offtime--;
[*]                     else
[*]                     {
[*]                            onoff=1;//切换开状态
[*]                            opentime=Open_Time*60;//赋值打开时间
[*]                            STATE=1;
[*]                     }
[*]            }
[*]            gpio16_output_set(!STATE);//喷淋
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(13),!STATE);//加热
[*]            currentDataPoint.valueSpray = STATE;
[*]            currentDataPoint.valueHeating = STATE;
[*]       }
[*]       else //手动模式
[*]       {
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(13),!STATE);//加热
[*]            gpio16_output_set(!STATE);//喷淋
[*]       }
[*]       if(STATE==1)   //状态改变
[*]       {
[*]            STATE=0;//清除状态
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(12),!STATE);//水循环
[*]            GPIO_OUTPUT_SET(GPIO_ID_PIN(5),!STATE);//灯光
[*]            //flash存储数据前转换数据
[*]            addr_case1 = (uint8)STATE;
[*]            addr_case1 = (uint8)STATE;
[*]            addr_case1 = (uint8)STATE;
[*]            addr_case1 = (uint8)STATE;
[*]            addr_case2 = (uint8)STATE;
[*]            addr_case2 = (uint8)currentDataPoint.valueSet_Temperature;
[*]            addr_case2 = (uint8)currentDataPoint.valueSpray_Open_Time ;
[*]            addr_case2 = (uint8)currentDataPoint.valueSpray_Off_Time;
[*]            //擦除要写入的Flash扇区
[*]            spi_flash_erase_sector(sec);
[*]            //写入数据,sec*4*1024就是写入起始地址,就是具体的字节地址
[*]            spi_flash_write(sec*4*1024, (uint32*)addr_case1, sizeof(addr_case1));
[*]            //擦除要写入的Flash扇区
[*]            spi_flash_erase_sector(sec1);
[*]            //写入数据,sec*4*1024就是写入起始地址,就是具体的字节地址
[*]            spi_flash_write(sec1*4*1024, (uint32*)addr_case2, sizeof(addr_case2));
[*]       }
[*]    system_os_post(USER_TASK_PRIO_2, SIG_UPGRADE_DATA, 0);
[*]}

复制代码

9.修改完代码之后ctrl+B进行编译固件编译。https://club.gizwits.com/data/attachment/forum/202201/16/143514kl3sy0mx3njoq0xl.png.thumb.jpg10.利用乐鑫烧录软件将生成的固件烧录到ESP8266里面。参数参考下图,注意参数不能有错。下载硬件接线如下表下载模式。记住通电瞬间就要保持这个状态才是下载模式。https://club.gizwits.com/data/attachment/forum/202201/16/143514zy8bmm53hz8m8yg7.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202201/16/143514dhoou44hoxuwzxu4.png.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202201/16/143515tieg46gbci2b7ae7.png.thumb.jpg11.程序烧录完成之后通过按键长按触发airlink配网(或短按触发softap配网),在APP选择对应的配网进行网络配置及绑定设备。绑定后进入设备即可进行采集和控制https://club.gizwits.com/data/attachment/forum/202201/16/143515s1o77ie2yy7kzeo7.jpg.thumb.jpghttps://club.gizwits.com/data/attachment/forum/202201/16/143515ru33zswjeide73ed.jpg.thumb.jpg12.实物展示展示https://club.gizwits.com/data/attachment/forum/202201/16/144555vapj2fm231jpmt1i.jpg.thumb.jpg
https://v.youku.com/v_show/id_XNTgzNTI0NzIzMg==.html?spm=a2hbt.13141534.0.13141534

页: [1]
查看完整版本: 开源教程:基于ESP8266和机智云的智能雨林缸,成本低、高...