[文章]

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

2021-1-25 21:49:21  350 物联网 智能家居 OpenHarmony
分享

家庭多功能智能设备

2

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


四、软件设计

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


1、显示任务

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

时间显示界面如下
时间显示.jpg
现在天气情况显示界面
今天.jpg
明天天气情况显示界面
明天.jpg
后天天气情况显示界面
后天天气.jpg
布撤防时间调整显示界面
时间设置.jpg
设置模式显示界面
模式设置.jpg
获取状态提示显示
时间成功提示.jpg
时间提示.jpg
天气提示.jpg
任务代码如下
  1. static void OledTask(void *arg)
  2. {
  3.     (void)arg;
  4.     //Oled初始化
  5.     GpioInit();
  6.     OledInit();
  7.     OledFillScreen(0x00);

  8.     while (1)
  9.     {
  10.         //自动模式下,自动进行布撤防
  11.         Zdbcf();
  12.         //界面更新时,需要先删除界面显示的内容
  13.         if(Now_Screen != Last_Screen)
  14.         {
  15.             Last_Screen = Now_Screen;
  16.             OledFillScreen(0);
  17.             Get_Status = GET_NORMAL;
  18.             Last_Get_Status = GET_NORMAL;
  19.             i=0;
  20.         }

  21.         //获取时间和天气数据状态提示,会隔一段时间进行清除
  22.         if((Get_Status == GET_FAIL) ||(Get_Status == GET_SUC))
  23.         {
  24.             i++;
  25.             if(i > 20)
  26.             {
  27.                 Get_Status = GET_NORMAL;
  28.                 i=0;

  29.                 switch(Now_Screen)
  30.                 {
  31.                 case TIMESCREEN:
  32.                     OledClearString(16,7,"Sync time...",1);     //清除提示
  33.                     break;
  34.                 case NOWSCREEN:

  35.                 case TOSCREEN:

  36.                 case ATOSCREEN:
  37.                     printf("clear oled i = %d\n",i);
  38.                     OledClearString(0,7,"Get Weather...",1);    //清除提示
  39.                     break;
  40.                 case BCTIMESCREEN:
  41.                     break;
  42.                 default :
  43.                     break;
  44.                 }
  45.             }
  46.         }

  47.         switch (Now_Screen)
  48.         {

  49.         case TIMESCREEN:
  50.             TimeScreenDisp();       //显示时间显示界面
  51.             Defenddisplay();
  52.             break;

  53.         case NOWSCREEN:
  54.             WeatherDisp(NOWSCREEN); //显示现在的天气显示界面
  55.             break;

  56.         case TOSCREEN:              //显示明天天气显示界面
  57.             WeatherDisp(TOSCREEN);
  58.             break;

  59.         case ATOSCREEN:             //显示后天天气显示界面
  60.             WeatherDisp(ATOSCREEN);
  61.             break;
  62.         case BCTIMESCREEN:
  63.             OLED_ShowCHinese(32,0,14);//时
  64.             OLED_ShowCHinese(48,0,15);//间
  65.             OLED_ShowCHinese(64,0,18);//设
  66.             OLED_ShowCHinese(80,0,19);//值
  67.             sprintf((char *)TimeStr,"%02d:00-%02d:00",starttime,stoptime);
  68.             OledShowString(20,4,(char *)TimeStr,2); //显示布撤防时间
  69.             break;
  70.         case BCADJUSTSCEEN:
  71.             OLED_ShowCHinese(32,0,16);//模
  72.             OLED_ShowCHinese(48,0,17);//式
  73.             OLED_ShowCHinese(64,0,18);//设
  74.             OLED_ShowCHinese(80,0,19);//值
  75.             DefendDisplay();          //显示手自动模式,布撤防状态
  76.             break;
  77.         default:
  78.             break;
  79.         }
  80.         usleep(100000);
  81.     }
  82. }
复制代码

2、按键控制任务

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

  1. //显示界面枚举类型
  2. typedef enum
  3. {
  4.     TIMESCREEN=0,       //时间显示界面,开机后的界面
  5.     NOWSCREEN,          //现在天气情况的显示界面
  6.     TOSCREEN,           //明天天气情况的显示界面
  7.     ATOSCREEN,          //后天天气情况的显示界面
  8.     BCTIMESCREEN,       //布撤防时间调整的显示界面
  9.     BCADJUSTSCEEN,      //设置手自动模式、布撤防状态的界面
  10.     NOSCREEN,           //无界面
  11. } SCREEN_STATUS;
复制代码

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

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

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

任务代码如下

  1. //按键任务
  2. static void KeyTask(void *arg)
  3. {
  4.     (void)arg;
  5.     unsigned short data = 0;

  6.     //按键IO初始化
  7.     GpioInit();
  8.     IoSetFunc(BUTTON_GPIO, BUTTON_GPIO_FUNC);
  9.     GpioSetDir(BUTTON_GPIO, BUTTON_GPIO_DIR);
  10.     IoSetPull(BUTTON_GPIO,WIFI_IOT_IO_PULL_UP);     //设置为上拉

  11.     //按键按下标志,按下置1,松开置0
  12.     static bool keyflag = false;
  13.     static bool buttonflag =false;
  14.     while(1)
  15.     {
  16.         //获取模拟按键状态
  17.         AdcRead(analog_KEY_CHAN_NAME, &data, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0);
  18.         float voltage = ConvertToVoltage(data);

  19.         //显示板的左边按键按下
  20.         if((voltage>0.45 && voltage<0.65)&&(!keyflag))  //一直按下,不会重复操作,只有松开再按下,才能再次进入
  21.         {
  22.             keyflag = true;     
  23.             //在不同的显示界面上,按键按下的操作都不一样
  24.             switch (Now_Screen)
  25.             {
  26.             case TIMESCREEN:                        //在时间显示界面时,获取实时时间
  27.                 if(connect_status == CONNECTED)
  28.                     TcpDisconnect();                //需要先断开之前的网络连接
  29.                 Get_Status = GET_PROPRESS;
  30.                 if(getNtpTime())
  31.                 {
  32.                     Get_Status = GET_SUC;
  33.                 }
  34.                 else
  35.                 {
  36.                     Get_Status = GET_FAIL;
  37.                 }
  38.                 TcpConnect();                       //恢复之前的网络连接
  39.                 break;
  40.             case NOWSCREEN:                         //在现在天气显示界面、明天天气显示界面、后天天气显示界面,都是获取天气数据
  41.                 if(connect_status == CONNECTED)
  42.                     TcpDisconnect();
  43.                 Get_Status = GET_PROPRESS;
  44.                 if(getWeather())
  45.                     Get_Status = GET_SUC;
  46.                 else
  47.                 {
  48.                     Get_Status = GET_FAIL;
  49.                 }
  50.                 TcpConnect();
  51.                 break;
  52.             case TOSCREEN:                          //在现在天气显示界面、明天天气显示界面、后天天气显示界面,都是获取天气数据
  53.                 if(connect_status == CONNECTED)
  54.                     TcpDisconnect();
  55.                 Get_Status = GET_PROPRESS;
  56.                 if(getWeather())
  57.                     Get_Status = GET_SUC;
  58.                 else
  59.                 {
  60.                     Get_Status = GET_FAIL;
  61.                 }
  62.                 TcpConnect();
  63.                 break;
  64.             case ATOSCREEN:                         //在现在天气显示界面、明天天气显示界面、后天天气显示界面,都是获取天气数据
  65.                 if(connect_status == CONNECTED)
  66.                     TcpDisconnect();
  67.                 Get_Status = GET_PROPRESS;
  68.                 if(getWeather())
  69.                     Get_Status = GET_SUC;
  70.                 else
  71.                 {
  72.                     Get_Status = GET_FAIL;
  73.                 }
  74.                 TcpConnect();
  75.                 break;
  76.             case BCTIMESCREEN:                      //在时间调整界面,调整布防时间
  77.                 BfTimeAdjust();
  78.                 break;
  79.             case BCADJUSTSCEEN:                     //在模式设置界面,切换手自动模式
  80.                 ZdAdjust();
  81.                 break;
  82.             default:
  83.                 break;
  84.             }

  85.         }
  86.         else if((voltage>0.9 && voltage<1)&&(!keyflag))    //显示板右边按键按下,切换界面
  87.         {
  88.             keyflag = true;
  89.             Now_Screen ++;
  90.             if(Now_Screen >= NOSCREEN)
  91.             {
  92.                 Now_Screen = TIMESCREEN;
  93.             }
  94.         }
  95.         //按键松开
  96.         if((!(voltage>0.45 && voltage<0.65)) && (!(voltage>0.9 && voltage<1)))
  97.         {
  98.             keyflag = false;
  99.         }
  100.         
  101.         //红黄绿灯板按键状态
  102.         WifiIotGpioValue buttonValue;
  103.         GpioGetInputVal(BUTTON_GPIO,&buttonValue);
  104.         //按键按下
  105.         if((buttonValue == WIFI_IOT_GPIO_VALUE0)&&(!buttonflag))
  106.         {
  107.             switch (Now_Screen)
  108.             {
  109.             case TIMESCREEN:        //在时间显示界面,打开或关闭LED灯
  110.                 LedContrcl();
  111.                 break;
  112.             case NOWSCREEN:
  113.             case TOSCREEN:
  114.             case ATOSCREEN:
  115.                 break;
  116.             case BCTIMESCREEN:      //在时间设置界面,调整撤防时间
  117.                 CfTimeAdjust();
  118.                 break;
  119.             case BCADJUSTSCEEN:     //在模式设置界面,切换布撤防状态
  120.                 BcAdjust();
  121.                 break;
  122.             default:
  123.                 break;
  124.             }
  125.             buttonflag = true;
  126.         }
  127.         //按键松开
  128.         if(!(buttonValue == WIFI_IOT_GPIO_VALUE0))
  129.         {
  130.             buttonflag = false;
  131.         }
  132.         usleep(100000);
  133.     }
  134. }
复制代码

3、环境监测任务

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

任务代码如下

  1. static void EnvironmentTask(void *arg)
  2. {
  3.     (void)arg;
  4.     uint32_t retval = 0;

  5.     float gasSensorResistance = 0.0f;

  6.     /*I2C IO口初始化化*/
  7.     GpioInit();
  8.     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);
  9.     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);
  10.     I2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);

  11.     // 初始化AHT20
  12.     uint8_t i=0;
  13.     while (WIFI_IOT_SUCCESS != AHT20_Calibrate())
  14.     {
  15.         printf("AHT20 sensor init failed!\r\n");
  16.         usleep(1000);
  17.         i++;
  18.         if(i>10)
  19.             break;
  20.     }
  21.    
  22.     //初始化Led灯
  23.     Led_Init();
  24.     //初始化蜂鸣器
  25.     Beep_Init();

  26.     while(1)
  27.     {
  28.         //AHT20开始测量
  29.         retval = AHT20_StartMeasure();
  30.         if (retval != WIFI_IOT_SUCCESS)
  31.         {
  32.             printf("trigger measure failed!\r\n");
  33.         }

  34.         //获取AHT20的测量结果,包括温度和湿度
  35.         retval = AHT20_GetMeasureResult(&temperature, &humidity);
  36.         if (retval != WIFI_IOT_SUCCESS)
  37.         {
  38.             printf("get humidity data failed!\r\n");
  39.         }

  40.         //烟雾(火灾)检测
  41.         unsigned short data = 0;
  42.         if (AdcRead(GAS_SENSOR_CHAN_NAME, &data, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0)
  43.                 == WIFI_IOT_SUCCESS)
  44.         {
  45.             //数值转换
  46.             float Vx = ConvertToVoltage(data);
  47.             gasSensorResistance = 5 / Vx - 1;
  48.             
  49.             //检测到烟雾或者有毒气体
  50.             if((gasSensorResistance < 11) && (ywflag ==0))
  51.             {
  52.                 ywflag = 1;     //置位烟雾报警标志位
  53.                 Beep_Start();   //蜂鸣器发声报警
  54.             }
  55.             else if((gasSensorResistance >=11) && (ywflag ==1))     //恢复每检测到烟雾状态
  56.             {
  57.                 ywflag = 0;         //复位标志位
  58.                 if(rtflag==0)       //没有防盗报警时
  59.                     Beep_Stop();    //停止蜂鸣器发声
  60.             }

  61.         }

  62.         //防盗检测
  63.         unsigned short humandata = 0;
  64.         if(bcflag)      //在布防状态下,防盗检测功能才开启
  65.         {
  66.             if (AdcRead(HUMAN_SENSOR_CHAN_NAME, &humandata, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0)
  67.                     == WIFI_IOT_SUCCESS)
  68.             {
  69.                 //布防功能开启下,检测到人。
  70.                 //注意一旦触发防盗报警,就算恢复到没检测到人状态,也是会一直发声报警,只有切换到撤防状态,才能复位防盗报警标志位。
  71.                 if((humandata>1500)&&(rtflag==0))
  72.                 {
  73.                     rtflag = 1;     //置位防盗报警标志位
  74.                     Beep_Start();   //蜂鸣器发声报警
  75.                 }
  76.             }
  77.         }
  78.         else
  79.         {
  80.             //切换到撤防状态,复位防盗报警标志位
  81.             if((rtflag == 1) && (ywflag == 0))  //之前触发防盗报警,停止蜂鸣器发声。
  82.                 Beep_Stop();
  83.             rtflag = 0;
  84.         }

  85.         sleep(1);
  86.         Led_Set(GREEN,ON);      //系统心跳灯开
  87.         sleep(1);
  88.         Led_Set(GREEN,OFF);     //系统心跳灯关
  89.     }
  90. }
复制代码

4、灯控制任务

该任务主要任务是控制灯开关,灯随着环境亮度变化亮度。在灯开启情况下,会根据获得的光敏电阻ADC值来进行灯亮度的调节。使用PWM控制灯的亮度。根据标志ledflag来判断是需要开关还是关灯。ledflag值会在按键任务中进行设置。

任务代码如下

  1. //灯开关标志位,0为灯关,1为灯开
  2. uint8_t ledflag = 0;
  3. static void LightTask(void *arg)
  4. {
  5.     (void)arg;
  6.     //初始化IO
  7.     GpioInit();
  8.     IoSetFunc(RED_LED_PIN_NAME, WIFI_IOT_IO_FUNC_GPIO_1_PWM4_OUT);
  9.     IoSetFunc(GREEN_LED_PIN_NAME, WIFI_IOT_IO_FUNC_GPIO_0_PWM3_OUT);
  10.     IoSetFunc(BLUE_LED_PIN_NAME, WIFI_IOT_IO_FUNC_GPIO_8_PWM1_OUT);
  11.     GpioSetDir(RED_LED_PIN_NAME, WIFI_IOT_GPIO_DIR_OUT);
  12.     GpioSetDir(GREEN_LED_PIN_NAME, WIFI_IOT_GPIO_DIR_OUT);
  13.     GpioSetDir(BLUE_LED_PIN_NAME, WIFI_IOT_GPIO_DIR_OUT);
  14.     //初始化PWM
  15.     PwmInit(WIFI_IOT_PWM_PORT_PWM4); // R
  16.     PwmInit(WIFI_IOT_PWM_PORT_PWM1); // B
  17.     PwmInit(WIFI_IOT_PWM_PORT_PWM3); // G

  18.     while (1) {
  19.             unsigned short data = 0;
  20.             unsigned short duty = 0;
  21.             //获取光敏电阻的值
  22.             if (AdcRead(LIGHT_SENSOR_CHAN_NAME, &data, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0)
  23.                 == WIFI_IOT_SUCCESS) {
  24.                 //根据值调整PWM波
  25.                 duty = PWM_FREQ_DIVITION * (unsigned int)data/ MAX_ADCVALUE;
  26.             }
  27.             //灯为开启状态,开始PWM
  28.             if(ledflag)
  29.             {
  30.             Pwmstart(WIFI_IOT_PWM_PORT_PWM4, duty, PWM_FREQ_DIVITION);
  31.             PwmStart(WIFI_IOT_PWM_PORT_PWM1, duty, PWM_FREQ_DIVITION);
  32.             PwmStart(WIFI_IOT_PWM_PORT_PWM3, duty, PWM_FREQ_DIVITION);
  33.             }
  34.             else
  35.             {
  36.             //灯为关闭状态,停止PWM
  37.             PwmStart(WIFI_IOT_PWM_PORT_PWM4, 0, PWM_FREQ_DIVITION);
  38.             PwmStart(WIFI_IOT_PWM_PORT_PWM1, 0, PWM_FREQ_DIVITION);
  39.             PwmStart(WIFI_IOT_PWM_PORT_PWM3, 0, PWM_FREQ_DIVITION);
  40.             PwmStop(WIFI_IOT_PWM_PORT_PWM4);
  41.             PwmStop(WIFI_IOT_PWM_PORT_PWM1);
  42.             PwmStop(WIFI_IOT_PWM_PORT_PWM3);
  43.             }
  44.             usleep(10000);
  45.     }
  46. }
复制代码

5、RTC任务

RTC任务主要是为了达到时间更新的功能。任务中每隔一秒,时间戳timedata加1。时间戳timedata1在显示任务的时间显示界面中会使用。通过时间戳转换函数,把时间戳转化为北京时间,则得到我们需要的实时时间。

任务代码如下

  1. uint32_t timedata=1608362368;   //时间戳默认值
  2. static void RtcTask(void *arg)
  3. {
  4.     (void)arg;
  5.     while(1)
  6.     {
  7.         //每隔一秒,时间戳加1
  8.         timedata++;
  9.         sleep(1);
  10.     }
  11. }
复制代码

6、TCP数据发送任务

进入该任务后,先获取网络时间和网络天气数据,到达系统启动后获取时间和天气数据的功能。如果与TCP服务器连接为已连接状态下,发送数据到服务器端,服务器会把数据转发手机APP端。如果数据发送失败,则视为连接断开,在连接断开情况下,会尝试与服务器进行连接。上传到服务器的数据有温度、湿度、手自动模式、布撤防状态、火灾报警、防盗报警情况。

任务代码如下

  1. //数据发送任务
  2. static void TcpSendTask(void *arg)
  3. {
  4.     (void)arg;
  5.     sleep(3);
  6.     //先获取时间和天气数据
  7.     getNtpTime();
  8.     getWeather();
  9.     uint8_t i = 0;

  10.     //尝试与与远程服务器进行连接
  11.     while(1){
  12.         if(TcpConnect())
  13.         {
  14.             printf("Tcp Connect Suc\n");
  15.             break;
  16.         }
  17.         else{
  18.             i++;
  19.         }
  20.         if(i>10)    //超过十次则视为连接不成功,跳出
  21.         break;
  22.     }
  23.     if(i>10)
  24.         printf("Tcp Connect fail\n");

  25.     while(1)
  26.     {
  27.         
  28.         if(connect_status == CONNECTED)
  29.         {
  30.             //发送数据到远程服务器
  31.             sprintf(sendData,"T:%02dH:%02dZ:%01dB:%01dD:%01dY:%01d",
  32.             (uint32_t)temperature,(uint32_t)humidity,(uint32_t)zdflag,(uint32_t)bcflag,(uint32_t)rtflag,(uint32_t)ywflag);
  33.             //如果发送不成功,则视为连接已经断开
  34.             if(!TcpSend(sendData,sizeof(sendData)-1)){
  35.                 connect_status = DISCONNECTED;
  36.                 TcpDisconnect();    //主动断开与远程TCP服务器的连接
  37.             }
  38.         }
  39.         else{
  40.                 //在与远程服务器为未连接状态,重新建立连接
  41.                 if(Get_Status == GET_NORMAL){   //没有在获取时间或者天气数据,则重新尝试与远程服务器建立连接
  42.                     if(TcpConnect()){
  43.                         printf("Tcp Connect Suc\n");
  44.                     }
  45.                 }
  46.         }
  47.         sleep(2);
  48.     }
  49. }
复制代码

7、TCP数据接收任务

该任务中,如果与服务器连接为已连接状态情况下,则使用函数接收服务器下发的数据,数据接收函数使用超时机制,超过一定时间没接收到数据则退出,不会一直阻塞直到接收到数据。根据下发的数据设置手自动模式、布撤防状态。

任务代码如下

  1. //远程服务器数据接收任务
  2. static void TcpRevTask(void *arg){
  3.     (void)arg;
  4.     while(1)
  5.     {
  6.         //为已连接状态,接收数据
  7.         if(connect_status == CONNECTED)
  8.         {
  9.             if(TcpRev()){
  10.                 //成功接收到手机端发送的数据
  11.                 if(strcmp(revData,"s")==0)          //设置手动模式
  12.                 {
  13.                     zdflag = 0;
  14.                 }
  15.                 else if(strcmp(revData,"z")==0)     //设置自动模式
  16.                 {
  17.                     zdflag = 1;
  18.                 }
  19.                 else if(strcmp(revData,"b")==0)     //设置布防状态
  20.                 {
  21.                     bcflag =1;
  22.                 }
  23.                 else if(strcmp(revData,"c")==0)     //设置撤防状态
  24.                 {
  25.                     bcflag =0;
  26.                 }
  27.             }
  28.         }
  29.         usleep(10000);
  30.     }
  31. }
复制代码

五、总结

这一次HiSpark Wi-Fi IoT 套件试用暂时告一段落了,还是感谢电子发烧友和润和给的这次使用机会。我最后做的小DIY Demo,基本也全部使用完套件的板子,除NFC板没使用。主控板的IO口资源还是挺有限的,IO口基本使用完了。这次的demo还是有很多需要改进地方,例如操作改变连接网络,无法修改连接的服务器等。



评分

参与人数 1积分 +6 收起 理由
emitter + 6 原创技术先锋,加分鼓励!

查看全部评分

评论

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

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发文章
快速回复 返回顶部 返回列表