Koblingsskjema:
Kode:
/**
Værstasjon
*/
#define DEBUG_WIFI_WEBSERVER_PORT Serial
#define _WIFI_LOGLEVEL_ 0
#define _WIFININA_LOGLEVEL_ 0
#define USE_WIFI_NINA true
#include <WiFiHttpClient.h>
#include <WiFiWebServer.h>
#include <elapsedMillis.h>
#include <ArduinoJson.h>
#include <Adafruit_MAX31865.h>
#include <Adafruit_BME280.h>
#include <Adafruit_TSL2591.h>
const uint8_t
WIFI_RETRY = 3,
BUTTON_LED = 9,
DATA_LED = LED_BUILTIN,
SPI_CS_MAX31865 = 5;
uint8_t
wifi_do = 0,
trigger_wifi_reconnect = 0;
uint16_t
counterReconnect = 0;
uint32_t
wifi_status = WL_IDLE_STATUS,
MILLIS_DATA_UPDATE_CURRENT,
MILLIS_DATA_UPDATE = 60000,
MILLIS_LED_BLINK = 5000,
MILLIS_WIFI_TEST = 300000;
elapsedMillis blinkLightSystem; // Status blink
elapsedMillis getDataTest; // Hent ny sensordata
elapsedMillis wifiTest; // Test wifi-tilkobling
/* JSON. Hver måling er ca 250 i lengde */
StaticJsonDocument<512> json_doc;
JsonObject json_root;
char jsonLog[512];
/* Wifi */
const char WIFI_SSID[] = "ssid";
const char WIFI_PASS[] = "pw";
const char WIFI_TEST_ADDR[] = "192.1.1.1";
const char WIFI_PATH_TEST[] = "/";
IPAddress LOCAL_IP(192, 1, 1, 2);
WiFiWebServer server(80);
WiFiClient client;
WiFiHttpClient httpClient(client, WIFI_TEST_ADDR, 80);
/**
SENSOR MAX31865 - PT100 element, SPI, 5V, 5/3V logic safe
RREF=430.0 for PT100 og 4300.0 for PT1000
RNOMINAL=0-grad motstand for sensoren. 100.0 for PT100, 1000.0 for PT1000
*/
Adafruit_MAX31865 thermo = Adafruit_MAX31865(SPI_CS_MAX31865, 2, 3, 4); // CS,DI,DO,SCK
#define RREF 430.0
#define RNOMINAL 100.0
char *maxErrors[] = {
"RTD High Threshold",
"RTD Low Threshold",
"REFIN- > 0.85 x Bias",
"REFIN- < 0.85 x Bias FORCE-open",
"RTDIN- < 0.85 x Bias FORCE-open",
"Under/Over voltage",
"NULL"
};
/* SENSOR BME280 - Trykk, temperatur, fuktighet, gass - I2C, 0x77, 5V, 5/3V logic safe */
Adafruit_BME280 bme;
/**
SENSOR TSL2591 - Lys - I2C, 0x29, 5V/3V logic safe
1 broadband photodiode (visible + infrared),
1 infrared-responding photodiode
Gain har ingen effekt på lux
*/
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);
void setup()
{
Serial.begin(9600);
delay(3000); // Vent litt så serial får med seg all output
pinMode(DATA_LED, OUTPUT);
pinMode(BUTTON_LED, OUTPUT);
digitalWrite(BUTTON_LED, HIGH);
if(WiFi.status() == WL_NO_MODULE) {
while(1);
}
begin_max();
begin_bme();
begin_tsl();
getSensorData();
setupWifi();
digitalWrite(BUTTON_LED, LOW);
}
void loop()
{
/* Blink system led, bare for å sjekke om hele driten har hengt seg */
if(blinkLightSystem >= MILLIS_LED_BLINK) {
blinkLightSystem = 0;
digitalWrite(DATA_LED, !digitalRead(DATA_LED));
}
/* Hent ny sensordata */
if(getDataTest >= MILLIS_DATA_UPDATE) {
getDataTest = 0;
getSensorData();
MILLIS_DATA_UPDATE_CURRENT = millis();
}
/* Sjekk wifi status */
wifi_status = WiFi.status();
/* Koble til wifi på nytt */
if(wifi_status != WL_CONNECTED || trigger_wifi_reconnect != 0) {
digitalWrite(BUTTON_LED, HIGH);
reconnectWifi();
return;
} else {
digitalWrite(BUTTON_LED, LOW);
}
/* Test wifi tilkobling */
if(wifiTest >= MILLIS_WIFI_TEST && wifi_do == 1) {
wifiTest = 0;
int werr = 0;
werr = httpClient.get(WIFI_PATH_TEST);
if(werr != 0) {
trigger_wifi_reconnect = 1;
}
httpClient.stop();
}
if(wifi_do != 1) return;
server.handleClient();
}
void begin_max()
{
thermo.begin(MAX31865_4WIRE);
thermo.enable50Hz(true);
}
void begin_bme()
{
if(bme.begin()) {
bme.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // temperatur
Adafruit_BME280::SAMPLING_X1, // trykk
Adafruit_BME280::SAMPLING_X1, // fuktighet
Adafruit_BME280::FILTER_OFF);
}
}
void begin_tsl()
{
if(tsl.begin()) {
tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
tsl.setGain(TSL2591_GAIN_LOW);
}
}
void getSensorData()
{
// Lag en tom array, kaller clear internt
json_root = json_doc.to<JsonObject>();
get_max_data();
get_bme_data();
get_tsl_data();
serializeJson(json_doc, jsonLog);
Serial.println(F("JSON-data:"));
Serial.println(jsonLog);
}
void get_max_data()
{
float max_ra, max_re, max_t;
uint8_t max_fault;
uint16_t max_rtd;
max_rtd = thermo.readRTD();
max_ra = max_rtd;
max_ra /= 32768;
max_re = (RREF * max_ra);
max_t = thermo.temperature(RNOMINAL, RREF);
max_fault = thermo.readFault();
JsonObject json_max = json_root.createNestedObject("MAX");
json_max["ratio"] = max_ra;
json_max["resistance"] = max_re;
json_max["temperature"] = max_t;
json_max["error"] = max_fault;
if(max_fault) {
if(max_fault & MAX31865_FAULT_HIGHTHRESH) {
json_max["errorText"] = maxErrors[0];
}
if(max_fault & MAX31865_FAULT_LOWTHRESH) {
json_max["errorText"] = maxErrors[1];
}
if(max_fault & MAX31865_FAULT_REFINLOW) {
json_max["errorText"] = maxErrors[2];
}
if(max_fault & MAX31865_FAULT_REFINHIGH) {
json_max["errorText"] = maxErrors[3];
}
if(max_fault & MAX31865_FAULT_RTDINLOW) {
json_max["errorText"] = maxErrors[4];
}
if(max_fault & MAX31865_FAULT_OVUV) {
json_max["errorText"] = maxErrors[5];
}
thermo.clearFault();
} else {
json_max["errorText"] = maxErrors[6];
}
}
void get_bme_data()
{
float temperature, humidity, pressure;
bme.takeForcedMeasurement();
temperature = bme.readTemperature();
humidity = bme.readHumidity();
pressure = (bme.readPressure() / 100.0F);
JsonObject json_bme = json_root.createNestedObject("BME");
json_bme["temperature"] = temperature;
json_bme["humidity"] = humidity;
json_bme["pressure"] = pressure;
}
void get_tsl_data()
{
float lux;
uint16_t ir, full;
uint32_t visible, lum;
lum = tsl.getFullLuminosity();
ir = lum >> 16;
full = lum & 0xFFFF;
lux = tsl.calculateLux(full, ir);
visible = (full - ir);
JsonObject json_tsl = json_root.createNestedObject("TSL");
json_tsl["ir"] = ir; // μm
json_tsl["visible"] = visible;
json_tsl["full"] = full;
json_tsl["lux"] = lux;
}
uint16_t get_tsl_timing(tsl2591IntegrationTime_t timing)
{
return (timing + 1) * 100;
}
uint8_t MStoMin(uint32_t ms)
{
return (ms / 1000 / 60);
}
void setupWifi()
{
uint8_t i = 0;
WiFi.config(LOCAL_IP);
while(wifi_status != WL_CONNECTED) {
if(i >= WIFI_RETRY) {
return;
}
wifi_status = WiFi.begin(WIFI_SSID, WIFI_PASS);
delay(15000);
i++;
}
wifi_do = 1;
trigger_wifi_reconnect = 0;
counterReconnect++;
server.on(F("/"), wifiHandle_root);
server.on(F("/getSensorData"), wifiHandle_getSensorData);
server.on(F("/setTslGain/low"), wifiHandle_tslSetGainLow);
server.on(F("/setTslGain/med"), wifiHandle_tslSetGainMed);
server.on(F("/setTslGain/high"), wifiHandle_tslSetGainHigh);
server.on(F("/setTslGain/max"), wifiHandle_tslSetGainMax);
server.on(F("/setTslTiming/100"), wifiHandle_tslSetTiming100);
server.on(F("/setTslTiming/200"), wifiHandle_tslSetTiming200);
server.on(F("/setTslTiming/300"), wifiHandle_tslSetTiming300);
server.on(F("/setTslTiming/400"), wifiHandle_tslSetTiming400);
server.on(F("/setTslTiming/500"), wifiHandle_tslSetTiming500);
server.on(F("/setTslTiming/600"), wifiHandle_tslSetTiming600);
server.on(F("/setUpdateTime/1"), wifiHandle_updateFrequency1);
server.on(F("/setUpdateTime/3"), wifiHandle_updateFrequency3);
server.on(F("/setUpdateTime/5"), wifiHandle_updateFrequency5);
server.onNotFound([]() {
server.send(404, F("text/plain"), F("404: Fant ikke siden.."));
});
server.begin();
}
void reconnectWifi()
{
wifi_do = 0;
httpClient.stop();
server.stop();
WiFi.end();
setupWifi();
}
void wifiHandle_root()
{
#define BUFFER_SIZE 1500
char ret[BUFFER_SIZE];
snprintf(
ret,
BUFFER_SIZE-1,
"<!DOCTYPE html>\
<html lang=\"en\">\
<head>\
<meta charset=\"utf-8\">\
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\
<title>Værstasjon</title>\
</head>\
<body style=\"font-family: monospace; font-size: 130\%%;\">\
<h1>Værstasjon</h1>\
<p><strong>Wi-Fi tilkobling:</strong><br>%d dBm (%s)</p>\
<p><strong>Wi-Fi reconnect teller:</strong><br>%d</p>\
<p><a href=\"/getSensorData\">Se oppdatert sensordata</a></p>\
<p><strong>Oppdateringsfrekvens:</strong><br> Hvert %d minutt</p>\
<p><strong>Siste oppdatering:</strong><br> På %d ms<br>millis() nå: %d ms</p>\
<p><strong>TSL gain og timing:</strong><br> %d og %d ms</p>\
<p>Sett TSL gain: \
<a href=\"/setTslGain/low\">LAV</a> (x0, standard), \
<a href=\"/setTslGain/med\">MEDIUM</a> (x16), \
<a href=\"/setTslGain/high\">HØY</a> (x32), \
<a href=\"/setTslGain/max\">MAKS</a> (x48)\
</p>\
<p>Sett TSL timing: \
<a href=\"/setTslTiming/100\">100 ms</a>, \
<a href=\"/setTslTiming/200\">200 ms</a>, \
<a href=\"/setTslTiming/300\">300 ms</a>, \
<a href=\"/setTslTiming/400\">400 ms</a>, \
<a href=\"/setTslTiming/500\">500 ms</a> (standard), \
<a href=\"/setTslTiming/600\">600 ms</a>\
</p>\
<p>Sett oppdateringsfrekvens: \
<a href=\"/setUpdateTime/1\">1 minutt</a> (standard), \
<a href=\"/setUpdateTime/3\">3 minutt</a>, \
<a href=\"/setUpdateTime/5\">5 minutt</a>\
</p>\
</body>\
</html>",
WiFi.RSSI(),
WiFi.SSID(),
counterReconnect,
MStoMin(MILLIS_DATA_UPDATE),
MILLIS_DATA_UPDATE_CURRENT,
millis(),
tsl.getGain(),
get_tsl_timing(tsl.getTiming())
);
server.send(200, F("text/html"), ret);
}
void wifiHandle_getSensorData()
{
server.send(200, F("application/json"), jsonLog);
}
void wifiHandle_tslSetGainLow()
{
tsl.setGain(TSL2591_GAIN_LOW);
server.send(200, F("text/html"), F("Oppdaterte TSL gain (x0). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetGainMed()
{
tsl.setGain(TSL2591_GAIN_MED);
server.send(200, F("text/html"), F("Oppdaterte TSL gain (x16). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetGainHigh()
{
tsl.setGain(TSL2591_GAIN_HIGH);
server.send(200, F("text/html"), F("Oppdaterte TSL gain (x32). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetGainMax()
{
tsl.setGain(TSL2591_GAIN_MAX);
server.send(200, F("text/html"), F("Oppdaterte TSL gain (x48). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetTiming100()
{
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
server.send(200, F("text/html"), F("Oppdaterte TSL timing (100). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetTiming200()
{
tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
server.send(200, F("text/html"), F("Oppdaterte TSL timing (200). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetTiming300()
{
tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
server.send(200, F("text/html"), F("Oppdaterte TSL timing (300). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetTiming400()
{
tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
server.send(200, F("text/html"), F("Oppdaterte TSL timing (400). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetTiming500()
{
tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
server.send(200, F("text/html"), F("Oppdaterte TSL timing (500). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_tslSetTiming600()
{
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
server.send(200, F("text/html"), F("Oppdaterte TSL timing (600). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_updateFrequency1()
{
MILLIS_DATA_UPDATE = 60000;
server.send(200, F("text/html"), F("Endret oppdateringsfrekvens (1 minutt). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_updateFrequency3()
{
MILLIS_DATA_UPDATE = 180000;
server.send(200, F("text/html"), F("Endret oppdateringsfrekvens (3 minutt). <a href=\"/\">Tilbake</a>"));
}
void wifiHandle_updateFrequency5()
{
MILLIS_DATA_UPDATE = 300000;
server.send(200, F("text/html"), F("Endret oppdateringsfrekvens (5 minutt). <a href=\"/\">Tilbake</a>"));
}