2015年10月22日 星期四

Arduino IDE 1.6.5 + BH1750 + CD74HC4067 多工器

Arduino Uno 上的 I2C 通道非常方便去串聯很多感應器,但有時會碰到一次會要接許多相同的感應器如 BH1750 ,受人之託是要作一個 如同該網友所作的 Multiple BH1750 on i2c bus Digital Light Sensor + Arduino (16xBH1750),剛好我也有2組 CD74HC4067,CD74HC4067在露天上可以買到,我買的是這一塊:

CD74HC4067
因為 I2C 有 SCL及 SDA 所以需要2片  CD74HC4067, BH1750 上還有另一條  ADDR 就選擇用 LOW,也就是不接。
BH1750

先看一張亂接圖:

Arduino CD 74HC4067
手工接的,真怕短路。但是可以執行喔。 最重要的是 CD74HC4067 上 S0 S1 S2 S3 這是用來選擇要讀取的BH1750,SCL及 SDA 分別接到不同板子上的 Cx 上。

完程圖



#include <Wire.h>
#include <BH1750FVI.h>
BH1750FVI LightSensor;
//Mux control pins
int s0 = 8;
int s1 = 9;
int s2 = 10;
int s3 = 11;

void setup() {  
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  Serial.begin(57600);
  LightSensor.begin();
  LightSensor.SetAddress(Device_Address_L);
  /*
   set the Working Mode for this sensor
   Select the following Mode:
    Continuous_H_resolution_Mode
    Continuous_H_resolution_Mode2
    Continuous_L_resolution_Mode
    OneTime_H_resolution_Mode
    OneTime_H_resolution_Mode2
    OneTime_L_resolution_Mode

    The data sheet recommanded To use Continuous_H_resolution_Mode
  */

  LightSensor.SetMode(Continuous_H_resolution_Mode);

  Serial.println("Running...");
}

void loop() {
  for (int i = 0; i < 12; i ++) {
    readMux(i);
    LightSensor.begin();
    LightSensor.SetAddress(Device_Address_L);
    LightSensor.SetMode(Continuous_H_resolution_Mode);
    uint16_t lux = LightSensor.GetLightIntensity();// Get Lux value
    Serial.print("L");
    Serial.print(i + 1);
    Serial.print(": ");
    Serial.print(lux);
    Serial.print("   ");
    delay(1000);
  }
  Serial.println(" lux");
}

//用來選擇讀取
int readMux(int channel) {

  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4] = {
    {0, 0, 0, 0}, //channel 0
    {1, 0, 0, 0}, //channel 1
    {0, 1, 0, 0}, //channel 2
    {1, 1, 0, 0}, //channel 3
    {0, 0, 1, 0}, //channel 4
    {1, 0, 1, 0}, //channel 5
    {0, 1, 1, 0}, //channel 6
    {1, 1, 1, 0}, //channel 7
    {0, 0, 0, 1}, //channel 8
    {1, 0, 0, 1}, //channel 9
    {0, 1, 0, 1}, //channel 10
    {1, 1, 0, 1}, //channel 11
    {0, 0, 1, 1}, //channel 12
    {1, 0, 1, 1}, //channel 13
    {0, 1, 1, 1}, //channel 14
    {1, 1, 1, 1} //channel 15
  };

  for (int i = 0; i < 4; i ++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
}

2015年10月21日 星期三

ESP8266 + Arduino IDE 1.6.5 + BH1750 光度感應器 快速測試

為了能快速測試 BH1750 加在 ESP8266 上 ,盡量使用 Arduino 原始程式上的腳位,我下載的BH1750 程式庫的腳位如下:

/*
  This is a simple code to test BH1750FVI Light senosr
  communicate using I2C Protocol
  this library enable 2 slave device address
  Main address  0x23
  secondary address 0x5C
  connect this sensor as following :
  VCC >>> 3.3V
  SDA >>> A4
  SCL >>> A5
  addr >> A3
  Gnd >>>Gnd

  Written By : Mohannad Rawashdeh

 */

程式是由 Mohannad Rawashdeh 撰寫 。

NodeMCU+BH1750
測試的輸出如下:

NodeMcu+BH1750
NodeMcu+BH1750

同樣的程式也可用 BH1750 與 Arduino UNO 來測 ,聯接圖如下:

Arduino UNO + BH1750


2015年10月19日 星期一

ESP8266 + Arduino IDE 1.6.5 + DHT22 + SHT20 溫濕度感應器

寫到這主要是作記錄了, 因為合併程式很快就測成功了, 整個程式如下:

#include <Wire.h>
#include <DHT.h>
#include "SparkFunHTU21D.h"
#include <ESP8266WiFi.h>
#define DHTPIN 4
#define DHTTYPE DHT22
// Wifi definition
const char* ssid     = "Buffalo9F-2";
const char* password = "0227057373";
const char* server = "184.106.153.149";
String apiKey = "P1UO6DM0KA8X79SQ";

WiFiClient client;
//Create an instance of the object
HTU21D myHumidity;
DHT dht(DHTPIN, DHTTYPE);

void reConnectAP()
{
  int i = 0;
  WiFi.begin(ssid, password);
  while ((WiFi.status() != WL_CONNECTED) && (i < 100)) {
    delay(500);
    Serial.print(".");
    i = i++;
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    myHumidity.begin();
    dht.begin();
  }
}
void setup()
{
  int i;
  Serial.begin(9600);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  reConnectAP();
}
void loop()
{
  if (WiFi.status() != WL_CONNECTED) {
    reConnectAP();
    return;
  }
  // SHT20
  float humd = myHumidity.readHumidity();
  float temp = myHumidity.readTemperature();
  // dht22
  float dhth = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float dhtt = dht.readTemperature();

  if (isnan(humd) || isnan(temp) || isnan(dhth) || isnan(dhtt)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  Serial.print("Sending sht20 data to thingspeak.com\n");
  if (client.connect(server, 80)) { //   "184.106.153.149" or api.thingspeak.com
    String postStr = apiKey;
    postStr += "&field1=";
    postStr += String(temp);
    postStr += "&field2=";
    postStr += String(humd);
    postStr += "&field3=";
    postStr += String(dhtt);
    postStr += "&field4=";
    postStr += String(dhth);
    postStr += "\r\n\r\n";
    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(postStr.length());
    client.print("\n\n");
    client.print(postStr);
    Serial.print(postStr);
    Serial.print("\n");
    Serial.print("SHT20 Temperature:");
    Serial.print(temp, 1);
    Serial.print("C");
    Serial.print("SHT20  Humidity:");
    Serial.print(humd, 1);
    Serial.print("%");
    Serial.println();
    Serial.print("DHT22 Temperature:");
    Serial.print(dhtt, 1);
    Serial.print("C");
    Serial.print("DHT22  Humidity:");
    Serial.print(dhth, 1);
    Serial.print("%");
    Serial.println();
    client.stop();
  }
  delay(20000);
}

雖然還有一個設備沒接上,先用我的角蛙缸測試一下 :

躲在土中的角蛙
養殖缸的底部用過濾網加高土,避免積水在土中
下方為土壤濕度計 SHT20 上方為環境溫濕度計 DHT22

數據顯示在Thinkspeak

看了 Thingspeak 數據之後,突然發現 SHT20 傳回的相對濕度超過 100%,看來又要除錯了。

ESP8266 + Arduino IDE 1.6.5 + DHT22 溫濕度感應器

原本 DHT22 和 ESP8266 已用 Nodemcu 的 LUA 很輕易的連上過,但是這次要使用的開環境是 Arduino IDE 1.6.5,原本想應該花個10幾分鐘就好了,結果 - 殘念 ,網路上下載 DHT-sensor-library,想說 測試一下就 OK了,但是一直出現 Error - In function__ieee754_asin ,Error的內容有一長串,最後發現網路上的網友有很多也有相同問題,詳系請看討論區 - 解決方法的討論區

解決的方法是 https://github.com/esp8266/Arduino/issues/612#issuecomment-129148582 這個內容是 下載新的 libm.a 取代原有 C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\lib 下的 libm.a。 置換過 libm.a 後 ,一切就正常了。

我用的 DHT22 如下圖 :

DHT22
執行測試的結果如下:

DHT22 測試

再來就是要把 DHT22 及 SHT20 併在同一顆 ESP8266 上。


2015年10月18日 星期日

ESP8266 + Arduino IDE 1.6.5 + SHT20 溫濕度感應器 - 連上 ThingSpeak

ESP8266 要連上ThingSpeak 網路上的文章應該很多了,當然首先是要註冊一個 ThingSpeak 帳號,申請帳號請前往 https://thingspeak.com/ 。

接著要 New Channel:

ThingSpeak
ThingSpeak New Channel

設定 Name 及 Field1 及 Field2,在我的測試中 Field1 是 "Tempature" 及 Field2 是 "Humidity",接著在 Arduino IDE include library "ESP8266WiFi",首先當然是要先連上區域網路上的 AP。

 WiFi.begin(ssid, password);

其中 SSID 及 Password 是區域網路AP 的 ID 及 Password, 並記錄下 Thingspeak 所產生的 API key,程式碼大概如下:

Serial.print("Sending data to thingspeak.com");
  if (client.connect(server, 80)) { //   "184.106.153.149" or api.thingspeak.com
    String postStr = apiKey;
    postStr += "&field1=";
    postStr += String(temp);
    postStr += "&field2=";
    postStr += String(humd);
    postStr += "\r\n\r\n";

    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(postStr.length());
    client.print("\n\n");
    client.print(postStr);

    Serial.print(" Temperature:");
    Serial.print(temp, 1);
    Serial.print("C");
    Serial.print(" Humidity:");
    Serial.print(humd, 1);
    Serial.print("%");
    Serial.println();
  }
  client.stop();
 
在 Thingspeak 顯示如下:

Thingspeak Channel

ESP8266 + Arduino IDE 1.6.5 + SHT20 溫濕度感應器 - 讀到正確資料

原本認為是一個輕鬆的連線測試,結果測了3個晚上。

朋友的需求是在ESP8266 開發板上使用SHT20 溫濕度感應器連線到 Thingspeak,應該是很簡單,一開始是用 Nodemcu LUA 來開發,因為 Nodemcu LUA 上有現成 I2C 的程式庫,但是使用 I2C 的程式庫可以用 掃瞄的方式,掃瞄到 SHT20 的代碼 0x40 但是在讀取溫濕度時都只能讀到錯誤的數字,從網路ESP8266 Community Forum 的討論區發現,很多人都有同樣的問題,使用 Nodemcu LUA 的 i2c 似乎是無法讀取 SHT20 的資料,須改用 Arduino 的 開發環境來作。

幫原有 Arduio 1.6.5 IDE 加上 ESP8266 的環境可從 Github esp8266 / Arduino 上取得,也在網路上找到 SHT2x 的 程式庫,但是一樣無法讀取,應該是與 ESP8266並不完全相容,最後從討論區發現可用的是 SPARKFN HTU21D Humidity Sensor Hookup Guide,這個 程式庫不是我寫的,所以請自行前往下載。

根據討論區的文章,直接使用程式庫還是不行,請看這一篇討論區說明 http://www.esp8266.com/viewtopic.php?f=32&t=4078&start=15#p24173,要把 原來SparkFunHTU21D.cpp 程式庫中 delay(55) 改程 delay(85) 及 wire.begin 改成 wire.begin(0,2),總算成功抓到溫度及相對濕度。

ESP8266 接 SHT20
我的防水sensor 是從 淘寶網上購買的:

SHT20 溫濕度傳感器
執行結果: