MakerBingo 发表于 2016-12-26 13:39:30

氦氪云入门教程02-基于氦氪通用演示产品的温湿度计

本帖最后由 MakerBingo 于 2017-8-8 15:05 编辑

上一篇教程我们介绍了氦氪通用演示产品的功能,本篇教程我们来做一个具体的作品:一个带小夜灯的温湿度计。只做温湿度计功能可能不是很实用,所以我们增加了一个LED灯,作为小夜灯来使用。

作品功能:
APP端:
1.控制小夜灯的亮灭。
2.显示当前的温度和湿度。

设备端:
1.按钮控制小夜灯的亮灭。

所需硬件:
1.氦氪WiFi模块


氦氪WiFi模块的接线请参考文档 氦氪模块硬件说明文档

2.Arduino UNO
这里就不贴照片了,使用其他型号的Arduino板子也行,我自己用的是兼容Arduino UNO的板子。

3.DHT22温湿度传感器


4.RGB全彩LED


5.按钮


硬件接线说明:


在氦氪通用演示产品的编辑页面修改通信协议:

在编辑页面完成修改之后,我们得到的通信协议内容如下图所示:


将氦氪WiFi模块与USB转串口模块连接,然后在电脑上用串口助手来模拟下该协议的数据收发。
进入控制页面
串口助手收到:48 16 02 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62
所以当我们的Arduino收到的有效数据(即valid_data数组里的数据)为02 00时,我们需要上报当前的设备状态,即小夜灯的开关,当前温度和当前湿度,示例帧如下所示:
48 16 01 01 01 00 02 11 34 00 00 00 00 00 00 00 00 00 00 00 00 A8

在APP上点击小夜灯按键
串口助手收到:48 16 02 01 02 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 65
所以当我们的Arduino收到的有效数据(即valid_data数组里的数据)为02 01 01时,我们需要开小夜灯,然后再上报当前的设备状态,即小夜灯的开关,当前温度和当前湿度,示例帧如下所示:
48 16 01 02 01 00 01 11 34 00 00 00 00 00 00 00 00 00 00 00 00 A8

编写Arduino端的代码,代码源文件已打包放在本帖子的最后,代码如下:
#include <hekr_protocol.h>
#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
u8 temp;
u8 RecvBuffer;
u8 uLedStatus = 2;
int buttonPin = 4;
int buttonIsPressing = 0;
int redLedPin = 9;
int greenLedPin = 10;
int blueLedPin = 11;
float ftHumidity = 0.0;
float ftTemperature = 0.0;

void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(redLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(blueLedPin, OUTPUT);
dht.begin();
HekrInit(SendChar);
ledColor(0,0,0);
delay(2000);
getHumidityAndTemperature();
}

void loop() {
GetData();
DataHandle();

if(digitalRead(buttonPin) == LOW)
{
    delay(20);
    if(digitalRead(buttonPin) == LOW)
    {
      if(buttonIsPressing == 0)
      {
      if(uLedStatus == 2)
      {
          ledColor(255,255,255);
          uLedStatus = 1;
          getHumidityAndTemperature();
          valid_data = 1;
          valid_data = 0;
          valid_data = uLedStatus;
          valid_data = byte(int(ftTemperature));
          valid_data = byte(ftHumidity);
          for(int i=5; i<=16; i++)
          {
            valid_data = 0;
          }
          HekrValidDataUpload(17);   
          buttonIsPressing = 1;   
      }
      else
      {
          ledColor(0,0,0);
          uLedStatus = 2;
          getHumidityAndTemperature();
          valid_data = 1;
          valid_data = 0;
          valid_data = uLedStatus;
          valid_data = byte(int(ftTemperature));
          valid_data = byte(ftHumidity);
          for(int i=5; i<=16; i++)
          {
            valid_data = 0;
          }
          HekrValidDataUpload(17);   
          buttonIsPressing = 1;   
      }               
      }
    }
}
if(digitalRead(buttonPin) == HIGH)
{
    delay(100);
    if(digitalRead(buttonPin) == HIGH)
    {
      buttonIsPressing = 0;   
    }
}
}

void getHumidityAndTemperature()
{
float h = dht.readHumidity();
float t = dht.readTemperature();

if (isnan(h) || isnan(t)) {
    return;
}
else
{
    ftHumidity = h;
    ftTemperature = t;
}
}

void SendChar(unsigned char ch)
{
Serial.write(ch);
delay(2);
}

void GetData(void)
{
u8 i = 0;
while(Serial.available())
{
    RecvBuffer = Serial.read();
    if(RecvBuffer != 0x48)
      i = 0;
    delay(2);
}
}

void ledColor(int red, int green, int blue){
      analogWrite(redLedPin,constrain(red,0,255));
      analogWrite(greenLedPin,constrain(green,0,255));
      analogWrite(blueLedPin,constrain(blue,0,255));
}

void DataHandle(void)
{
if(RecvBuffer == HEKR_FRAME_HEADER)
{
    temp = HekrRecvDataHandle(RecvBuffer);
    RecvBuffer = 0x00;
    if(ValidDataUpdate == temp)
    {   
      if(valid_data == 2)
      {
      if(valid_data == 0) //收到状态查询命令
      {
          getHumidityAndTemperature();
          valid_data = 1;
          valid_data = 0;
          valid_data = uLedStatus;
          valid_data = byte(int(ftTemperature));
          valid_data = byte(ftHumidity);
          for(int i=5; i<=16; i++)
          {
            valid_data = 0;
          }
          HekrValidDataUpload(17);            
      }
      if(valid_data == 1) //收到控制小夜灯命令
      {
          if(valid_data == 1)
          {
            ledColor(255,255,255);
            uLedStatus = 1;
          }
          if(valid_data == 2)
          {
            ledColor(0,0,0);
            uLedStatus = 2;
          }
          getHumidityAndTemperature();
          valid_data = 1;
          valid_data = 0;
          valid_data = uLedStatus;
          valid_data = byte(int(ftTemperature));
          valid_data = byte(ftHumidity);
          for(int i=5; i<=16; i++)
          {
            valid_data = 0;
          }
          HekrValidDataUpload(17);                  
      }
      }
    }
}
}


我使用的Arduino IDE版本是1.6.5。
需要在Arduino IDE里的Library Manager中安装一下名字为"DHT sensor library"的DHT传感器的库,安装完毕之后,请将C:Users你的电脑用户名DocumentsArduinolibraries目录下的DHT文件夹改个名字或者删掉,因为这是安装Arduino IDE时预装的DHT传感器库,会和我们新安装的库文件名冲突。
附件中的Hekr.zip是我们的Arduino库文件,可以在Arduino IDE中使用Add .ZIP Library将该库导入,最新版本和说明文档可以在以下链接中获得:https://github.com/HEKR-Cloud/HEKR-MCU-SDK/tree/master/example/Arduino

将Arduino端的程序编译完毕并上传至Arduino UNO之后,将所有硬件模块按照前文中提到的硬件接线说明连接起来,这样我们的基于氦氪通用演示产品的带小夜灯的温湿度计就完成了,打开丛云APP,进入我们之前绑定的氦氪通用演示产品的设备控制页面,就可以对我们的小夜灯进行控制了,在该页面我们还可以看到当前的温湿度。



在调试页面我们可以看到APP和设备间的数据收发过程。



页: [1]
查看完整版本: 氦氪云入门教程02-基于氦氪通用演示产品的温湿度计