…生活與工作…個人的生活雜記….

NODEMCU+BME280建立氣象收集站並傳送到WunderGround

這個就在google上可以找到很多資料了,我只針對初次體驗Arduino的一些注意事項寫一些類似備忘錄的東西。

初次使用

電源可以使用USB,開發初期很方便,接上電腦把驅動程式安裝好就可以直接有終端機可以看。

軟體使用ARDUINO IDE編輯器,選擇它的原因只是因為簡單,可免安裝,有中文XD

IDE下載後並無法直接使用,必需要安裝Nodemcu的Driver

安裝完成才能找到com port

環境設定

之後進入IDE並增加開發版

在檔案 /偏好設定 => 額外的開發板管理員網址,加入

http://arduino.esp8266.com/versions/2.5.0/package_esp8266com_index.json

按下確定後再到工具 / 開發板,選擇開發板 “NodeMCU 1.0(ESP-12E Module)”。

這樣就完成環境的設定了。

安裝函式庫

gitHub的第3方函式庫可以透過.zip的方式加入,若是標準函式庫則由”管理程式庫”這邊搜尋並添加。

**通常安裝最新版本即可

建立氣象站

使用BME280感測IC,價格一般,功能強,準確度OK。

規格如下:

接線的方式就請參考下面的麵包板,電源供應就使用USB的5VDC,經由內建的穩壓IC提供3.3V給BME280(3V3-VIN 與 GND-GND)。

IIC的訊號則是NodeMCU的D3到BME280的SDA、NodeMCU的D4到BME280的SCL連接起來。

只需要4條線即可。

我這一次因為只有故障戶外溫度的部分所以我只用到了2個I/O,至於NodeMCU的腳位定義網路上有很多介紹,請自行Google。

程式撰寫

一樣,網路上很多,可以挑你喜歡的。

我選擇 http://embedded-lab.com/blog/making-simple-weather-web-server-using-esp8266-bme280/

宣告:

#include <Wire.h>
#include <ESP8266WiFi.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <ESP8266HTTPClient.h>
#include <Timer.h>

Timer WUtcb; //定時呼叫
Adafruit_BME280 bme; // BME280

其中的Timer.h、ESP8266HTTPClient.h、Adafruit_Sensor.h都必須從額外的函式庫新增。

Adafruit-BME280-Library-master

Adafruit-Sensor-master

Timer-master

ESP8266 core for Arduino

啟動氣溫感測器的方式,BME280有2種款式,函是預設的通常啟動都是0x77,如果是不同的位址則須在begin內註明0x76

Serial.println(F("BME280 test"));
if (!bme.begin(0x76)) {
  Serial.println("Could not find a valid BME280 sensor, check wiring!");
  while (1);
}
Serial.println(F("Weather Server OK!"));

露點計算公式則是參考NOAA所提供的演算法

double dewPoint(double celsius, double humidity)
{
  double A0= 373.15/(273.15 + celsius);
  double SUM = -7.90298 * (A0-1);
  SUM += 5.02808 * log10(A0);
  SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
  SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
  SUM += log10(1013.246);
  double VP = pow(10, SUM-3) * humidity;
  double T = log(VP/0.61078); // temp var
  return (241.88 * T) / (17.558-T);
}

因應無線網路斷線時重新連結的小功能

void CheckWifiStatus(){
  Serial.print("Wireless reconnection.");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    WiFi.begin(ssid, password);
    Serial.print(".");
  }
}

使用Timer以觸發的方式執行上傳與網頁更新

WUtcb.every(30000,wunderground); 
WUtcb.every(15000,Webpage);



void loop() {
  WUtcb.update();
}

上傳給WunderGround

if (client.connect(WUserver, 80)) {
  char c = client.read();
  WU_PRESTR = String("") + WEBPAGE + "ID=" + WUID;
  WU_PRESTR = WU_PRESTR + "&PASSWORD=" + WUPASSWORD;
  WU_PRESTR = WU_PRESTR + "&dateutc=now";
  WU_PRESTR = WU_PRESTR + "&tempf="+temperatureFString;
  WU_PRESTR = WU_PRESTR + "&baromin="+pressureInchString;
  WU_PRESTR = WU_PRESTR + "&dewptf="+dpFString;
  WU_PRESTR = WU_PRESTR + "&humidity="+humidityString;
  WU_PRESTR = WU_PRESTR + WUpayload;
  client.print(String("GET ") + WU_PRESTR + " HTTP/1.1\r\n" +
    "Host: " + WUserver + "\r\n" +
    "User-Agent: ESP8266\r\n" +
    "Connection: close\r\n\r\n"); 
  Serial.println(F("... Server Response:"));
  while(client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.write(c);
    }
  }
  client.flush();
  client.stop(); 
}else {
  Serial.println(F("WunderGround連線失敗!!!!!!!"));
  char c = client.read();
  Serial.write(c);
  client.flush();
  client.stop();
}

燒錄

NodeMCU在燒錄時,必須把D0接地,才能正確燒錄。

測試都沒問題之後就能直接上板了