// Weather station works.
#include <WiFi.h>
#include <DHT.h>
#include <PubSubClient.h> // MQTT related
#include "ThingSpeak.h"
#define DHT_PIN 28 // the pin for DHT
#define DHT_TYPE DHT22 // DHT used
// wifi
const char* WIFI_NAME = "Wokwi-GUEST"; // wifi-ssid used? i dont know found it somewhere
const char* WIFI_PASS = ""; // define doesnt use = or ;
// thingspeak
const unsigned long CHANNEL_NUM = 3140359; // const char apparently better for c++
const char* APIKEY = "K3OSK6OCVNHLZQ0H"; // unsigned allows bigger nums by disallowing negative nums
const char* SERVER = "api.thingspeak.com";
// mqtt
const char* mqtt_server = "broker.hivemq.com"; // public mqtt server (it's free)
const int mqtt_port = 1883;
const char* mqtt_topic = "veera_weatherstation";
// * tells the compiler "this variable holds the memory address where the string begins"
// Without the *, you're trying to fit an entire string into a single character var
// i could have just used string... wait which one is more space efficient?
DHT dht(DHT_PIN, DHT_TYPE); // create sensor objectS
// DHT is class name
// dht is var name for instance
// pin and type are var para
WiFiClient CLIENT; // create wifi client object
// class handles network stuff for wifi letting arduino speak with wifi
// lib doesnt have a handler to we have to make a thing that goes
// use THIS to transfer data
PubSubClient mqttClient(CLIENT); // apparently you can also use client() here. aka same thing?
const char* clientId = "VeerasPicoWeatherStation"; // with this i can find my weather pico whenever with the given name
void SetUpMQTT(){ // start up
mqttClient.setServer(mqtt_server, mqtt_port);
}
void setup() {
// put your setup code here, to run once:
Serial1.begin(115200); // init. bits per second
dht.begin(); // dht init
// when you init Serial1 you cant use Serial later
SetUpMQTT(); // connect to MQTT and node.js
Serial1.println("Connecting to WiFi...");
WiFi.begin(WIFI_NAME, WIFI_PASS); // wifi begin, using given wifi
while (WiFi.status() != WL_CONNECTED) { // WL_CONNECTED is const from lib. says "connected to wifi"
delay(1000); // WL_NO_SHIELD: No WiFi shield found. aka no wifi hardware
Serial1.println("Connecting..."); // WL_IDLE_STATUS: Temporary status assigned when no changes
// WL_CONNECT_FAILED: Connection failed
} // gives connection status as num
// Wait for connection // compare the number to see if connected. if != 200 not connected
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial1.println("Connecting...");
}
Serial1.println("Connected to WiFi!");
Serial1.print("IP Address: ");
Serial1.println(WiFi.localIP()); // asks what is the device IP. used for debugging and advanced projects
ThingSpeak.begin(CLIENT); // INIT THINGSPEAK LIB
//
Serial1.println("Weather Station Initialized."); // arduino simplified c++, print line
Serial1.println("---"); // empty line
delay(20); // delay for 20ms
Serial1.println("Connected to WiFi!");
Serial1.print("IP Address: ");
Serial1.println(WiFi.localIP());
}
void reconnectMqtt(){ // reconnect if error
if (mqttClient.connect(clientId)){
Serial1.println("MQTT connected!");
}
else {
// print error msg
int errorCode = mqttClient.state();
Serial1.print("MQTT failed, error: ");
Serial1.println(errorCode);
}
delay(5000); // 5 seconds
}
// pubilsh data
void publishData(float temp, float humid){
char message[50]; // message while not str
snprintf(message, sizeof(message), // char limit set for str, rest as reads here // snprint() func: print the specified string till a specified length
"{\"temp\":%.1f,\"humid\":%.1f}", temp, humid); // message // THIS IS WHERE IT GOT THE THE t and h error from??? this is the JSON sent
// here i would encrypt the JSON data that goes to broker
// publish
if (mqttClient.publish(mqtt_topic, message)){
Serial1.print("Published: ");
Serial1.println(message);
} else {
Serial1.println("Publish failed!");
}
}
void loop() {
// mqtt stuff
if (!mqttClient.connected()){
reconnectMqtt();
}
mqttClient.loop();
float humid = dht.readHumidity(); // what it says, read humidity
float temp = dht.readTemperature(); // ditto for temp
if (isnan(humid) || isnan(temp)) { // isnan aka not a number and || or operator
Serial1.println("Failed to read from DHT sensor!");
return;
} else {
Serial1.print("Humidity: ");
Serial1.print(humid);
Serial1.println("%");
Serial1.print("Temperature: ");
Serial1.print(temp);
Serial1.println(" °C");
Serial1.println();
publishData(temp, humid); // sent to MQTT
sendToThingSpeak(temp, humid);
}
delay(20000); // this speeds up the simulation ms // thingspeak requires some 15-20s updates
}
// method
void sendToThingSpeak(float temp, float humid) {
// Set the fields for ThingSpeak
ThingSpeak.setField(1, temp); // to thingspeak field 1 send temperature
ThingSpeak.setField(2, humid);
// Send data to ThingSpeak
int responseCode = ThingSpeak.writeFields(CHANNEL_NUM, APIKEY); // writes and sends back how everything is going
// takes the fields, packages, sents to thingspeak, includes "address"
// setField() is like contents of letter and writeFields is mailing it
// Check the result
if (responseCode == 200) {
Serial1.println("Data sent to ThingSpeak!");
Serial1.println("And sent to Server.js");
Serial1.println("");
} else {
Serial1.print("Error sending to ThingSpeak. HTTP code: ");
Serial1.println(responseCode);
Serial1.println("Check your API key and channel number!");
Serial1.println("---");
}
}
// 10 mins is 600 000 ms