[IOT]使用Raspberry + Arduino,來讀取 DHT22 的溫濕度資訊

環境: Windows 10 Iot Core, Arduino UNO, Visual Studio 2015

在Windows 10 IoT Core 的範例,可以讀取到 DHT11 的溫濕度資訊,但是它是 C++ 的範例。

本文依 Arduino I2C communication with Raspi 2 WIOT  這篇來修改實作的,

再透過 I2C 傳給 Raspberry 來接收資訊。如下圖,

本文依 Arduino I2C communication with Raspi 2 WIOT 這篇來修改實作的,

而 Arduino 的 DHT 程式庫可以從 Github Arduino/libraries/DHTlib/ Download,

請在 C:\Users\user\Documents\Arduino\libraries 目錄下建立 DHT 的目錄,

並將 dht.cpp 及 dht.h 放在該目錄中。

啟動 Arduino IDE 後,就可以使用 DHT 的程式庫了,如下,

加入 DHT 程式庫後,就可以呼叫它來取得 溫濕度資訊 。

因為要將資料透過 I2C 傳給 Raspberry 所以要引用 Wire 程式庫及定位 Address 為 0x40,

程式可以參考 Github 的 chrisfaig/Windows-IOT-i2C-Arduino

Arduino I2C communication with Raspi 2 WIOT 這篇只傳 溫度,

但我想要傳送溫濕度,所以我就模仿 Home Automation using Raspberry Pi 2 and Windows 10 IoT 這篇。

將這些資料分別放在傳送的 Byte Array之中,

Byte 0 表示溫度是否為負, Byte 1 表示溫度, Byte 2 表示濕度,(當然,這樣數值就只到整數位)

Arduino 程式如下,

#include <Wire.h>
#define SLAVE_ADDRESS 0x40   // Define the i2c address
#include <dht.h>

dht DHT;

#define DHT_PIN 4
byte sendInfo[3];
void setup(){
  Serial.begin(9600);
  Wire.begin(SLAVE_ADDRESS); 
}

void loop(){
  // read data
  int chk = DHT.read22(DHT_PIN);
  switch(chk){
    case DHTLIB_OK:
      Serial.print("OK,\t");
      break;
     case DHTLIB_ERROR_CHECKSUM:
      Serial.print("Checksum error,\t");
      break;
     case DHTLIB_ERROR_TIMEOUT:
      Serial.print("Time out error,\t");
      break;
    case DHTLIB_ERROR_CONNECT:
      Serial.print("Connect error,\t");
      break;
    case DHTLIB_ERROR_ACK_L:
      Serial.print("Ack Low error,\t");
      break;
    case DHTLIB_ERROR_ACK_H:
      Serial.print("Ack High error,\t");
      break;
    default:
      Serial.print("Unknown error,\t");
      break;
    }
    Serial.print("temperature,:");
    Serial.print(DHT.temperature);
    Serial.print(",humidity:");
    Serial.println(DHT.humidity);
    Wire.onRequest(sendData);
    delay(1000);
}
  
void sendData(){
  sendInfo[0] = (byte)((DHT.temperature < 0) ? 1 : 0);
  sendInfo[1] = (byte)((DHT.temperature < 0) ? (DHT.temperature*(-1)) : DHT.temperature);
  sendInfo[2] = (byte)(DHT.humidity);
  Wire.write(sendInfo, 3);
}

執行的畫面如下,

而在 Raspberry 上的 UWP 程式,我簡單在 MainPage 上拉了2個 TextBlock,分別來呈現 溫度及濕度,如下,

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
	<TextBlock x:Name="temperature" Text="temperature" Margin="0,20,0,0"  />
	<TextBlock x:Name="humidity" Text="humidity" Margin="0,40,0,0"  />
</Grid> 

而在程式中,要加入 Windows IoT Extensions for the UWP 參考,

然後在 MainPage.xaml.cs 就可以開始透過 I2C 跟 Arduino 要資料,如下,

private I2cDevice _device;
private Timer _periodTimer;
public MainPage()
{
	this.InitializeComponent();
	//初始設定
	initCommuication();
}

private async void initCommuication()
{
	// Arduino address SLAVE_ADDRESS
	var settings = new I2cConnectionSettings(0x40);
	settings.BusSpeed = I2cBusSpeed.StandardMode;
	string aqs = I2cDevice.GetDeviceSelector("I2C1");
	var dis = await DeviceInformation.FindAllAsync(aqs);
	if(dis.Count > 0)
	{
		_device = await I2cDevice.FromIdAsync(dis[0].Id, settings);
		_periodTimer = new Timer(this.TimerCallback, null, 0, 1000);
	}
	else
	{
		temperature.Text = humidity.Text = "找不到設備...";
	}

}

private async void TimerCallback(object state)
{
	byte[] readBuffer = new byte[3];
	try
	{
		_device.Read(readBuffer);
		byte flag = readBuffer[0];
		byte t = readBuffer[1];
		byte h = readBuffer[2];
		string temperatureValue = (readBuffer[0] == 0)? t.ToString() : (t*(-1)).ToString(); 
		string humidityValue = h.ToString(); //new string(humidityArray);
		Debug.WriteLine($"{temperatureValue}:{humidityValue}");
		//update screen
		var task = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
			   { temperature.Text = string.Format($"Temperature:{temperatureValue} \u00B0C");
				humidity.Text = string.Format($"Humidity:{humidityValue}% RH"); });
	}
	catch(Exception ex)
	{
		Debug.WriteLine(ex.Message);
	}
	 
}

執行畫面如下,

一切都打通後,再來就可以將資料送到 Azure IoT Hub 上面了。

參考資料

GpioOneWire Sample (DHT11)

DHT11 /DHT22 Temperature Sensor

Arduino I2C communication with Raspi 2 WIOT

chrisfaig/Windows-IOT-i2C-Arduino

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^