电子产业一站式赋能平台

PCB联盟网

搜索
查看: 581|回复: 0
收起左侧

【HarmonyOS HiSpark Wi-Fi IoT小视频参赛】家庭多功能智能设备

[复制链接]

2607

主题

2607

帖子

7472

积分

高级会员

Rank: 5Rank: 5

积分
7472
发表于 2021-1-26 09:56:34 | 显示全部楼层 |阅读模式
【HarmonyOS HiSpark Wi-Fi IoT小视频参赛】家庭多功能智能设备,   

Hispark Wi-Fi IOT套件试用的最后一篇连载,将介绍我做的一个demo。使用的套件板子包括扩展底板、主控板子、显示板、环境监测板、红绿灯板、炫彩灯板。


一、主要功能





  • 火灾报警,在检测到颗粒烟雾或者有毒气体时,发声报警并把报警状态发送到手机端;  
  • 防盗报警,在布防状态下,检测到人时,发声报警并把报警状态发送到手机端;  
  • 拥有手动、自动模式设置,布防、撤防状态设置功能。在手动模式下,可以人为进行设置布撤防状态;在手动模式下,会自动根据设定的布撤防时间进行布撤防。在布防下,才进行防盗检测;  
  • 具备联网功能,设备能够获取网络时间和最近3天的气候情况,并在显示屏上进行显示;  
  • 可以与手机进行数据传输,把温湿度情况、防火报警状态、防盗报警状态、手自动模式、布撤防状态发送手机APP端,可以接收手机APP下发的手自动模式、布撤防状态切换的命令;  
  • 具备灯开关控制功能,可以根据环境亮度,调节灯亮度;  
  • 可以设置自动模式下布撤防的时间;  
  • 可以通过按键或者手机APP端设置手自动模式、布撤防状态;  
  • 启动后会自动获取网络时间或者网络天气数据,也可以通过按键手动获取网络时间或者网络天气数据;
      



二、硬件使用情况介绍



主要使用到下面硬件资源
1、主控板


2、扩展底板


3、显示板

  • OLED显示屏  
  • 两个模拟按键
      



4、环境监测板

  • 温湿度传感器  
  • 可燃性气体传感器  
  • 蜂鸣器
      



5、红绿灯板

  • 一个按键  
  • 一个绿灯
      



6、炫彩灯板

  • 三色灯(红绿蓝混合)  
  • 人体红外感应器  
  • 光敏电阻
      



三、主控IO资源分配



Hi3861的GPIO口不多,一共有15个IO口,但是IO口的复用功能较多。其中GPIO3、GPIO4用来作为调试串口,如果使用了串口功能,就不能使用GPIO3、4口作为其他功能。还需要注意的是,有些IO口是复用PWM通道和ADC通道功能。如果使用了该IO作为PWM功能,ADC通道功能就无法正常使用,应该是PWM会影响ADC正常使用。
  

下面是demo的IO分配表,GPIO3/GPIO4作为调试输出口,没有接其他器件。

  

IO分配.jpg (27.1 KB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:11 上传




四、软件设计



我把整个工程软件分为了七个任务,显示任务、按键控制任务、环境监测任务、灯控制任务、RTC任务、TCP数据发送任务、数据接收任务。


1、显示任务

显示任务主要是控制OLED的显示。设置有六个显示界面,时间显示界面、现在天气情况显示界面、明天天气情况显示界面、后天天气显示界面、布撤防时间调整显示界面、设置模式界面。显示任务根据变量Now_Screen的值来选择显示什么界面。Now_Screen的值会在按键任务中进行改变。在获取网络时间或者网络天气数据时,会显示获取状态提示内容。  时间显示界面如下

时间显示.jpg (1.39 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:12 上传 现在天气情况显示界面

今天.jpg (1.28 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:12 上传 明天天气情况显示界面

明天.jpg (1.36 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:12 上传 后天天气情况显示界面

后天天气.jpg (1.38 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:11 上传 布撤防时间调整显示界面

时间设置.jpg (1.34 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:12 上传 设置模式显示界面

模式设置.jpg (1.38 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:12 上传 获取状态提示显示

时间成功提示.jpg (1.48 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:20 上传



时间提示.jpg (1.31 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:20 上传

天气提示.jpg (1.41 MB, 下载次数: 0)

下载附件  保存到相册  

昨天 21:20 上传

任务代码如下

  • static void OledTask(void *arg)
      
  • {
      
  •     (void)arg;
      
  •     //Oled初始化
      
  •     GpioInit();
      
  •     OledInit();
      
  •     OledFillScreen(0x00);
      

  •   
  •     while (1)
      
  •     {
      
  •         //自动模式下,自动进行布撤防
      
  •         Zdbcf();
      
  •         //界面更新时,需要先删除界面显示的内容
      
  •         if(Now_Screen != Last_Screen)
      
  •         {
      
  •             Last_Screen = Now_Screen;
      
  •             OledFillScreen(0);
      
  •             Get_Status = GET_NORMAL;
      
  •             Last_Get_Status = GET_NORMAL;
      
  •             i=0;
      
  •         }
      

  •   
  •         //获取时间和天气数据状态提示,会隔一段时间进行清除
      
  •         if((Get_Status == GET_FAIL) ||(Get_Status == GET_SUC))
      
  •         {
      
  •             i++;
      
  •             if(i > 20)
      
  •             {
      
  •                 Get_Status = GET_NORMAL;
      
  •                 i=0;
      

  •   
  •                 switch(Now_Screen)
      
  •                 {
      
  •                 case TIMESCREEN:
      
  •                     OledClearString(16,7,“Sync time...“,1);     //清除提示
      
  •                     break;
      
  •                 case NOWSCREEN:
      

  •   
  •                 case TOSCREEN:
      

  •   
  •                 case ATOSCREEN:
      
  •                     printf(“clear oled i = %d\n“,i);
      
  •                     OledClearString(0,7,“Get Weather...“,1);    //清除提示
      
  •                     break;
      
  •                 case BCTIMESCREEN:
      
  •                     break;
      
  •                 default :
      
  •                     break;
      
  •                 }
      
  •             }
      
  •         }
      

  •   
  •         switch (Now_Screen)
      
  •         {
      

  •   
  •         case TIMESCREEN:
      
  •             TimeScreenDisp();       //显示时间显示界面
      
  •             Defenddisplay();
      
  •             break;
      

  •   
  •         case NOWSCREEN:
      
  •             WeatherDisp(NOWSCREEN); //显示现在的天气显示界面
      
  •             break;
      

  •   
  •         case TOSCREEN:              //显示明天天气显示界面
      
  •             WeatherDisp(TOSCREEN);
      
  •             break;
      

  •   
  •         case ATOSCREEN:             //显示后天天气显示界面
      
  •             WeatherDisp(ATOSCREEN);
      
  •             break;
      
  •         case BCTIMESCREEN:
      
  •             OLED_ShowCHinese(32,0,14);//时
      
  •             OLED_ShowCHinese(48,0,15);//间
      
  •             OLED_ShowCHinese(64,0,18);//设
      
  •             OLED_ShowCHinese(80,0,19);//值
      
  •             sprintf((char *)TimeStr,“%02d:00-%02d:00“,starttime,stoptime);
      
  •             OledShowString(20,4,(char *)TimeStr,2); //显示布撤防时间
      
  •             break;
      
  •         case BCADJUSTSCEEN:
      
  •             OLED_ShowCHinese(32,0,16);//模
      
  •             OLED_ShowCHinese(48,0,17);//式
      
  •             OLED_ShowCHinese(64,0,18);//设
      
  •             OLED_ShowCHinese(80,0,19);//值
      
  •             DefendDisplay();          //显示手自动模式,布撤防状态
      
  •             break;
      
  •         default:
      
  •             break;
      
  •         }
      
  •         usleep(100000);
      
  •     }
      
  • }

复制代码


2、按键控制任务

本demo中使用了三个按键,显示板上的两个模拟按键、红绿灯板的一个按键。显示板右边按键主要功能是切换界面,通过改变Now_Screen的值。Now_Screen可以取得值为

  • //显示界面枚举类型
      
  • typedef enum
      
  • {
      
  •     TIMESCREEN=0,       //时间显示界面,开机后的界面
      
  •     NOWSCREEN,          //现在天气情况的显示界面
      
  •     TOSCREEN,           //明天天气情况的显示界面
      
  •     ATOSCREEN,          //后天天气情况的显示界面
      
  •     BCTIMESCREEN,       //布撤防时间调整的显示界面
      
  •     BCADJUSTSCEEN,      //设置手自动模式、布撤防状态的界面
      
  •     NOSCREEN,           //无界面
      
  • } SCREEN_STATUS;

复制代码



显示板左边按键和红绿灯板按键在不同的显示界面,功能是不一样的。

  • 在时间显示界面时,显示板左按键为获取网络时间功能按键,红绿灯板按键为开关灯功能按键。
      
  • 在现在、明天、后天天气情况的显示界面,显示板左按键为获取网络天气数据功能按键,红绿灯板按键无功能。
      
  • 在布撤防时间调整显示界面,显示板左按键为调整布防时间功能按键,红绿灯板按键为调整撤防时间功能按键。
      
  • 在设置模式显示界面,显示板左按键为切换手自动模式功能按键,红绿灯板按键为切换布撤防状态的功能按键。
      


按键都只能单次触发,按下后必须松开才能再一次触发功能。

任务代码如下

  • //按键任务
      
  • static void KeyTask(void *arg)
      
  • {
      
  •     (void)arg;
      
  •     unsigned short data = 0;
      

  •   
  •     //按键IO初始化
      
  •     GpioInit();
      
  •     IoSetFunc(BUTTON_GPIO, BUTTON_GPIO_FUNC);
      
  •     GpioSetDir(BUTTON_GPIO, BUTTON_GPIO_DIR);
      
  •     IoSetPull(BUTTON_GPIO,WIFI_IOT_IO_PULL_UP);     //设置为上拉
      

  •   
  •     //按键按下标志,按下置1,松开置0
      
  •     static bool keyflag = false;
      
  •     static bool buttonflag =false;
      
  •     while(1)
      
  •     {
      
  •         //获取模拟按键状态
      
  •         AdcRead(analog_KEY_CHAN_NAME, &data, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0);
      
  •         float voltage = ConvertToVoltage(data);
      

  •   
  •         //显示板的左边按键按下
      
  •         if((voltage>0.45 && voltage<0.65)&&(!keyflag))  //一直按下,不会重复操作,只有松开再按下,才能再次进入
      
  •         {
      
  •             keyflag = true;     
      
  •             //在不同的显示界面上,按键按下的操作都不一样
      
  •             switch (Now_Screen)
      
  •             {
      
  •             case TIMESCREEN:                        //在时间显示界面时,获取实时时间
      
  •                 if(connect_status == CONNECTED)
      
  •                     TcpDisconnect();                //需要先断开之前的网络连接
      
  •                 Get_Status = GET_PROPRESS;
      
  •                 if(getNtpTime())
      
  •                 {
      
  •                     Get_Status = GET_SUC;
      
  •                 }
      
  •                 else
      
  •                 {
      
  •                     Get_Status = GET_FAIL;
      
  •                 }
      
  •                 TcpConnect();                       //恢复之前的网络连接
      
  •                 break;
      
  •             case NOWSCREEN:                         //在现在天气显示界面、明天天气显示界面、后天天气显示界面,都是获取天气数据
      
  •                 if(connect_status == CONNECTED)
      
  •                     TcpDisconnect();
      
  •                 Get_Status = GET_PROPRESS;
      
  •                 if(getWeather())
      
  •                     Get_Status = GET_SUC;
      
  •                 else
      
  •                 {
      
  •                     Get_Status = GET_FAIL;
      
  •                 }
      
  •                 TcpConnect();
      
  •                 break;
      
  •             case TOSCREEN:                          //在现在天气显示界面、明天天气显示界面、后天天气显示界面,都是获取天气数据
      
  •                 if(connect_status == CONNECTED)
      
  •                     TcpDisconnect();
      
  •                 Get_Status = GET_PROPRESS;
      
  •                 if(getWeather())
      
  •                     Get_Status = GET_SUC;
      
  •                 else
      
  •                 {
      
  •                     Get_Status = GET_FAIL;
      
  •                 }
      
  •                 TcpConnect();
      
  •                 break;
      
  •             case ATOSCREEN:                         //在现在天气显示界面、明天天气显示界面、后天天气显示界面,都是获取天气数据
      
  •                 if(connect_status == CONNECTED)
      
  •                     TcpDisconnect();
      
  •                 Get_Status = GET_PROPRESS;
      
  •                 if(getWeather())
      
  •                     Get_Status = GET_SUC;
      
  •                 else
      
  •                 {
      
  •                     Get_Status = GET_FAIL;
      
  •                 }
      
  •                 TcpConnect();
      
  •                 break;
      
  •             case BCTIMESCREEN:                      //在时间调整界面,调整布防时间
      
  •                 BfTimeAdjust();
      
  •                 break;
      
  •             case BCADJUSTSCEEN:                     //在模式设置界面,切换手自动模式
      
  •                 ZdAdjust();
      
  •                 break;
      
  •             default:
      
  •                 break;
      
  •             }
      

  •   
  •         }
      
  •         else if((voltage>0.9 && voltage<1)&&(!keyflag))    //显示板右边按键按下,切换界面
      
  •         {
      
  •             keyflag = true;
      
  •             Now_Screen ++;
      
  •             if(Now_Screen >= NOSCREEN)
      
  •             {
      
  •                 Now_Screen = TIMESCREEN;
      
  •             }
      
  •         }
      
  •         //按键松开
      
  •         if((!(voltage>0.45 && voltage<0.65)) && (!(voltage>0.9 && voltage<1)))
      
  •         {
      
  •             keyflag = false;
      
  •         }
      
  •         
      
  •         //红黄绿灯板按键状态
      
  •         WifiIotGpioValue buttonValue;
      
  •         GpioGetInputVal(BUTTON_GPIO,&buttonValue);
      
  •         //按键按下
      
  •         if((buttonValue == WIFI_IOT_GPIO_VALUE0)&&(!buttonflag))
      
  •         {
      
  •             switch (Now_Screen)
      
  •             {
      
  •             case TIMESCREEN:        //在时间显示界面,打开或关闭LED灯
      
  •                 LedContrcl();
      
  •                 break;
      
  •             case NOWSCREEN:
      
  •             case TOSCREEN:
      
  •             case ATOSCREEN:
      
  •                 break;
      
  •             case BCTIMESCREEN:      //在时间设置界面,调整撤防时间
      
  •                 CfTimeAdjust();
      
  •                 break;
      
  •             case BCADJUSTSCEEN:     //在模式设置界面,切换布撤防状态
      
  •                 BcAdjust();
      
  •                 break;
      
  •             default:
      
  •                 break;
      
  •             }
      
  •             buttonflag = true;
      
  •         }
      
  •         //按键松开
      
  •         if(!(buttonValue == WIFI_IOT_GPIO_VALUE0))
      
  •         {
      
  •             buttonflag = false;
      
  •         }
      
  •         usleep(100000);
      
  •     }
      
  • }

复制代码


3、环境监测任务

该任务主要功能是测量温度、湿度,获得可燃性气体传感器和人体红外感应器ADC值,并根据获得值进行火灾和防盗检查。获得的可燃气性气体值低于一定数值时,可判断有火灾或者可燃性气体泄漏,触发火灾报警,置位烟雾报警标志位,蜂鸣器发声。只要检测的数据高于设定的数据,报警状态则恢复为未报警状态。获得的人体红外感应器ADC数值超过一定值,则视为触发防盗报警。但是需要在布防状态下,才能进行防盗检测。防盗报警触发后,蜂鸣器发声报警,置位防盗报警标志位。一旦触发防盗报警,只有通过切换到撤防状态,才能把防盗报警状态恢复到未报警。

任务代码如下
  

  • static void EnvironmentTask(void *arg)
      
  • {
      
  •     (void)arg;
      
  •     uint32_t retval = 0;
      
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条


联系客服 关注微信 下载APP 返回顶部 返回列表