307 lines
8.5 KiB
Arduino
307 lines
8.5 KiB
Arduino
|
|
||
|
#include <ESP8266WiFi.h>
|
||
|
#include <MQTTClient.h>
|
||
|
#include <Wire.h>
|
||
|
#include <Adafruit_Sensor.h>
|
||
|
#include <Adafruit_BME280.h>
|
||
|
#include <RTClib.h>
|
||
|
#include <TimeLib.h>
|
||
|
#include <NtpClientLib.h>
|
||
|
|
||
|
/************************* WiFi Access Point *********************************/
|
||
|
|
||
|
#define WLAN_SSID "arowifi2"
|
||
|
#define WLAN_PASS "nAGjywhCQ4iUBcbmf0PBn_srrghpOur4-aIzcJ_8Uxm1b58dH1c4Vy-LEMLd"
|
||
|
|
||
|
/************************* MQTT broker Setup *********************************/
|
||
|
|
||
|
#define MQTT_SERVER "192.168.0.3"
|
||
|
#define MQTT_SERVERPORT 1883 // use 8883 for SSL
|
||
|
#define MQTT_USERNAME "arofarn"
|
||
|
#define MQTT_KEY "WaKaW9XMGUZ3rRJD"
|
||
|
#define MQTT_ID "huzzah0"
|
||
|
#define MQTT_PUB_INTERVAL 10000
|
||
|
|
||
|
/************************* Time and NTP Setup *********************************/
|
||
|
|
||
|
#define NTP_SERVER "fr.pool.ntp.org"
|
||
|
#define TIMEZONE 0 // UTC+0
|
||
|
#define DAYLIGHT false
|
||
|
#define NTP_REFRESH_INTERVAL 3600
|
||
|
|
||
|
/************************* Atmospheric Pressure Mode *********************************/
|
||
|
|
||
|
#define MODE_STATION true
|
||
|
#define DEFAULT_ALTITUDE 145.0
|
||
|
#define DEFAULT_APSL 1013.25 //Atmospheric Pressure at Sea-Level
|
||
|
|
||
|
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
|
||
|
WiFiClient wifi_client;
|
||
|
MQTTClient mqtt_client;
|
||
|
|
||
|
//Create a class for the sensor
|
||
|
Adafruit_BME280 bme; // I2C
|
||
|
|
||
|
bool mode_station = MODE_STATION;
|
||
|
float altitude = DEFAULT_ALTITUDE;
|
||
|
float atm_press_sea_level = DEFAULT_APSL;
|
||
|
|
||
|
bool led0_status = true ;
|
||
|
unsigned long previousPub = 0;
|
||
|
|
||
|
/*************************** Sketch Code ************************************/
|
||
|
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
|
||
|
// for some reason (only affects ESP8266, likely an arduino-builder bug).
|
||
|
void MQTT_connect();
|
||
|
|
||
|
void setup() {
|
||
|
bool wstatus=false;
|
||
|
|
||
|
Serial.begin(115200);
|
||
|
delay(10);
|
||
|
|
||
|
pinMode(LED_BUILTIN, OUTPUT);
|
||
|
pinMode(2, OUTPUT);
|
||
|
|
||
|
digitalWrite(2, wstatus);
|
||
|
digitalWrite(LED_BUILTIN, led0_status);
|
||
|
|
||
|
// Connect to WiFi access point.
|
||
|
Serial.println(); Serial.println();
|
||
|
Serial.print("Connecting to ");
|
||
|
Serial.println(WLAN_SSID);
|
||
|
|
||
|
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||
|
while (WiFi.status() != WL_CONNECTED) {
|
||
|
wstatus = !wstatus;
|
||
|
delay(500);
|
||
|
Serial.print(".");
|
||
|
digitalWrite(2, wstatus);
|
||
|
}
|
||
|
Serial.println();
|
||
|
|
||
|
digitalWrite(2, LOW);
|
||
|
Serial.println("WiFi connected");
|
||
|
Serial.println("IP address: "); Serial.println(WiFi.localIP());
|
||
|
|
||
|
delay(500);
|
||
|
|
||
|
NTP.begin(NTP_SERVER, TIMEZONE, DAYLIGHT); //Local french NTP server, timezone, summertime= false
|
||
|
NTP.setInterval(NTP_REFRESH_INTERVAL);
|
||
|
NTP.onNTPSyncEvent([](NTPSyncEvent_t error) {
|
||
|
if (error) {
|
||
|
Serial.print("Time Sync error: ");
|
||
|
if (error == noResponse)
|
||
|
Serial.println("NTP server not reachable");
|
||
|
else if (error == invalidAddress)
|
||
|
Serial.println("Invalid NTP server address");
|
||
|
}
|
||
|
else {
|
||
|
Serial.print("Got NTP time: ");
|
||
|
Serial.println(NTP.getTimeDateString(NTP.getLastNTPSync()));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
time_t nowNTP;
|
||
|
nowNTP = NTP.getTime();
|
||
|
Serial.println(nowNTP);
|
||
|
|
||
|
// default settings
|
||
|
bool status;
|
||
|
status = bme.begin();
|
||
|
if (!status) {
|
||
|
Serial.println("Could not find a valid BME280 sensor, check wiring!");
|
||
|
while (1);
|
||
|
}
|
||
|
|
||
|
mqtt_client.begin(MQTT_SERVER, MQTT_SERVERPORT, wifi_client); //MQTT_SERVERPORT, MQTT_USERNAME, MQTT_KEY);
|
||
|
//client.onMessage(messageReceived);
|
||
|
|
||
|
MQTT_connect();
|
||
|
mqtt_client.onMessage(messageReceived);
|
||
|
|
||
|
previousPub = millis();
|
||
|
}
|
||
|
|
||
|
uint32_t x=0;
|
||
|
|
||
|
void loop() {
|
||
|
mqtt_client.loop();
|
||
|
|
||
|
if (!mqtt_client.connected()) {
|
||
|
MQTT_connect();
|
||
|
}
|
||
|
|
||
|
unsigned long currentMillis = millis();
|
||
|
|
||
|
if(currentMillis - previousPub > MQTT_PUB_INTERVAL) {
|
||
|
// save the last time you blinked the LED
|
||
|
previousPub = currentMillis;
|
||
|
|
||
|
float pressure_val = -99.9;
|
||
|
float temperature_val = -99.9;
|
||
|
float humidity_val = -99.9;
|
||
|
String date_str = "";
|
||
|
char date_val[20] = "00:00:00 00-00-0000";
|
||
|
char tosend[120];
|
||
|
|
||
|
pressure_val = bme.readPressure() / 100.0F;
|
||
|
temperature_val = bme.readTemperature();
|
||
|
humidity_val = bme.readHumidity();
|
||
|
|
||
|
date_str = NTP.getTimeDateString();
|
||
|
date_str.toCharArray(date_val,20);
|
||
|
|
||
|
// Now we can publish stuff!
|
||
|
Serial.print(F("Sending date and time "));
|
||
|
Serial.print(date_val);
|
||
|
Serial.print("...");
|
||
|
if (! mqtt_client.publish("huzzah0/NTP/date", date_val, true, 2)) {
|
||
|
Serial.println(F("Failed"));
|
||
|
} else {
|
||
|
Serial.println(F("OK!"));
|
||
|
}
|
||
|
|
||
|
// Now we can publish stuff!
|
||
|
Serial.print(F("Sending pressure value "));
|
||
|
Serial.print(pressure_val);
|
||
|
Serial.print("...");
|
||
|
val2json(pressure_val, date_str, "hPa", "PA").toCharArray(tosend, 120);
|
||
|
if (! mqtt_client.publish("huzzah0/AdaBME280_1/pressure", tosend, true, 2) ) {
|
||
|
Serial.println(F("Failed"));
|
||
|
} else {
|
||
|
Serial.println(F("OK!"));
|
||
|
}
|
||
|
if(mode_station) {
|
||
|
//Sea-level atmospheric pressure calculus
|
||
|
atm_press_sea_level = bme.seaLevelForAltitude(altitude, pressure_val);
|
||
|
} else {
|
||
|
altitude = bme.readAltitude(atm_press_sea_level);
|
||
|
}
|
||
|
|
||
|
Serial.print(F("Sending sea-level pressure value "));
|
||
|
Serial.print(atm_press_sea_level);
|
||
|
Serial.print("...");
|
||
|
val2json(atm_press_sea_level, date_str, "hPa", "SLPA").toCharArray(tosend, 120);
|
||
|
if (! mqtt_client.publish("huzzah0/AdaBME280_1/sea_level_pressure", tosend, true, 2) ) {
|
||
|
Serial.println(F("Failed"));
|
||
|
} else {
|
||
|
Serial.println(F("OK!"));
|
||
|
}
|
||
|
Serial.print(F("Sending altitude value "));
|
||
|
Serial.print(altitude);
|
||
|
Serial.print("...");
|
||
|
val2json(altitude, date_str, "m", "ALTI").toCharArray(tosend, 120);
|
||
|
if (! mqtt_client.publish("huzzah0/AdaBME280_1/altitude", tosend, true, 2) ) {
|
||
|
Serial.println(F("Failed"));
|
||
|
} else {
|
||
|
Serial.println(F("OK!"));
|
||
|
}
|
||
|
|
||
|
// Now we can publish stuff!
|
||
|
Serial.print(F("Sending humity value "));
|
||
|
Serial.print(humidity_val);
|
||
|
Serial.print("...");
|
||
|
val2json(humidity_val, date_str, "%", "HR").toCharArray(tosend, 120);
|
||
|
if (! mqtt_client.publish("huzzah0/AdaBME280_1/humidity", tosend, true, 2)) {
|
||
|
Serial.println(F("Failed"));
|
||
|
} else {
|
||
|
Serial.println(F("OK!"));
|
||
|
}
|
||
|
|
||
|
// Now we can publish stuff!
|
||
|
Serial.print(F("Sending temperature value "));
|
||
|
Serial.print(temperature_val);
|
||
|
Serial.print("...");
|
||
|
val2json(temperature_val, date_str, "degC", "TA").toCharArray(tosend, 120);
|
||
|
if (! mqtt_client.publish("huzzah0/AdaBME280_1/temperature", tosend, true, 2)) {
|
||
|
Serial.println(F("Failed"));
|
||
|
} else {
|
||
|
Serial.println(F("OK!"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delay(10);
|
||
|
}
|
||
|
|
||
|
void MQTT_connect() {
|
||
|
Serial.print("checking wifi...");
|
||
|
while (WiFi.status() != WL_CONNECTED) {
|
||
|
Serial.print(".");
|
||
|
delay(1000);
|
||
|
}
|
||
|
|
||
|
Serial.print("\nconnecting...");
|
||
|
while (!mqtt_client.connect(MQTT_ID, MQTT_USERNAME, MQTT_KEY)) {
|
||
|
Serial.print(".");
|
||
|
delay(1000);
|
||
|
}
|
||
|
|
||
|
Serial.println("\nconnected!");
|
||
|
|
||
|
mqtt_client.subscribe("huzzah0/led0", 1);
|
||
|
mqtt_client.subscribe("huzzah0/mode_station", 1);
|
||
|
if(mode_station) {
|
||
|
mqtt_client.unsubscribe("huzzah0/sea_level_pressure");
|
||
|
mqtt_client.subscribe("huzzah0/altitude", 2);
|
||
|
}
|
||
|
else {
|
||
|
mqtt_client.unsubscribe("huzzah0/altitude");
|
||
|
mqtt_client.subscribe("huzzah0/sea_level_pressure", 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void messageReceived(String &topic, String &payload) {
|
||
|
Serial.println("incoming: " + topic + " - " + payload);
|
||
|
|
||
|
if(topic == "huzzah0/led0") {
|
||
|
if(payload == "0") led0_status = HIGH;
|
||
|
if(payload == "1") led0_status = LOW;
|
||
|
digitalWrite(LED_BUILTIN, led0_status);
|
||
|
}
|
||
|
if(topic == "huzzah0/mode_station") {
|
||
|
if(payload == "0") {
|
||
|
mode_station = false;
|
||
|
mqtt_client.unsubscribe("huzzah0/altitude");
|
||
|
mqtt_client.subscribe("huzzah0/sea_level_pressure", 1);
|
||
|
}
|
||
|
if(payload == "1") {
|
||
|
mode_station = true;
|
||
|
mqtt_client.unsubscribe("huzzah0/sea_level_pressure");
|
||
|
mqtt_client.subscribe("huzzah0/altitude", 1);
|
||
|
}
|
||
|
}
|
||
|
if(topic == "huzzah0/altitude") {
|
||
|
String pl = payload;
|
||
|
altitude = pl.toFloat();
|
||
|
Serial.print("New altitude :");
|
||
|
Serial.println(altitude);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
String int2str(int a) {
|
||
|
String ret = "";
|
||
|
if (a < 10) {
|
||
|
ret +="0";
|
||
|
}
|
||
|
if (a > 99)
|
||
|
a = 99;
|
||
|
ret += a;
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
String val2json (float val, String date, String unit, String type) {
|
||
|
String json = "{\"date\": \"";
|
||
|
json += date;
|
||
|
json += "\", \"value\": \"";
|
||
|
json += val;
|
||
|
json += "\", \"unit\": \"";
|
||
|
json += unit;
|
||
|
json += "\", \"type\": \"";
|
||
|
json += type;
|
||
|
json += "\" }";
|
||
|
//Serial.println(json);
|
||
|
return json;
|
||
|
}
|
||
|
|