Implementing the Weather Station with Alerts project

The STM32 instances come with support for Platform IO Core (CLI). We will be using it for working on our projects. To know more about Platform IO Core (CLI) and the different commands go to the Platform IO documentation.

First, we need to initialise a new project using Platform IO. Let's create a new folder called Weather-Notif which will hold all our code related to the project and then open the newly created folder in the terminal. Use the following commands:

mkdir /workspace/Weather-Notif/
cd /workspace/Weather-Notif/

Now we will initialise a new project using Platform IO. Type the following command in the terminal:

pio project init --board nucleo_f411re

The pio project init command is used to initialise the project. Then we need to specify the board which we want to use with the --board flag.

Once the project init command has run successfully, we will see some new folders inside the Smart-Home folder. We will store the files related to the project in the src folder.

After running the project init command, if you can't see the new files, you may have to reload the project files by clicking on PROJECT in the File Explorer pane.

Create a new file called main.cpp inside the src folder. This file will hold the code for the Smart Home Control program. Click on the main.cpp file to open it up in our code editor. Now, paste the following code inside the main.cpp file.

#include <Arduino.h>

#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#include <Ethernet.h>
#include <EthernetClient.h>

#include <Wire.h>
#include <Sodaq_SHT2x.h>

int alertState = 0;        
int lastAlertState = 0; 
int threshold = 40;  //You can change the threshold for the notification
/************************* Ethernet Client Setup *****************************/
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(172, 17, 0, 2);
IPAddress myDns(8, 8, 8, 8);

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME  "yourusername"       //Replace this with your username
#define AIO_KEY       "youradafruitiokey"  //Replace this with your Adafruit IO key

/************ Global State (you don't need to change this!) ******************/

//Set up the ethernet client
EthernetClient client;

Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

// You don't need to change anything below this line!
#define halt(s) { Serial.println(F( s )); while(1);  }

/****************************** Feeds ***************************************/

// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt,  AIO_USERNAME "/feeds/Temperature");
Adafruit_MQTT_Publish humidity = Adafruit_MQTT_Publish(&mqtt,  AIO_USERNAME "/feeds/Humidity");
Adafruit_MQTT_Publish alert = Adafruit_MQTT_Publish(&mqtt,  AIO_USERNAME "/feeds/Alert");

/*************************** Sketch Code ************************************/

void setup() {
  Wire.begin();
  Serial.begin(115200);

  Serial.println(F("MQTT with Adafruit IO"));

  // Initialise the Client
  Serial.print(F("\nInit the Client..."));
  Ethernet.begin(mac, ip, myDns);
  delay(1000); //give the ethernet a second to initialize
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT Connected!");
}

void loop() {
  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();
  
  //Get Temperature and Humidity values from SHT21
  float h=SHT2x.GetHumidity();
  float t=SHT2x.GetTemperature();
  
  // Now we can publish stuff!
  Serial.print(F("\nSending temperature "));
  Serial.print(t);
  Serial.print(" and humidity ");
  Serial.print(h);
  Serial.print("...");
  if (! temperature.publish(t++)) {
    Serial.println("Temperature Failed");
  } else {
    Serial.println("Temperature OK!");
  }
  if (! humidity.publish(h++)) {
    Serial.println("Humidity Failed");
  } else {
    Serial.println("Humidity OK!");
  }

  if (t > threshold) {
    alertState = 1;
  }
  else {
    alertState = 0;
  }

  if (alertState != lastAlertState) {
    if (alertState == 1) {
      alert.publish("1");
      Serial.println("Temperature is high");
    } else {
      alert.publish("0");
      Serial.println("Temperature is normal");
    }
  }
  delay(50);
  lastAlertState = alertState;
  
  // ping the server to keep the mqtt connection alive
  if(! mqtt.ping()) {
    mqtt.disconnect();
  }
  delay(6000);
}

In the above code, replace "yourusername" with your Adafruit IO username and "youradafruitiokey" with your Adafruit IO key which is present under My Key in Adafruit IO.

Before we can compile our code, we need to install a few libraries. First, let's search for the Adafruit MQTT library. Go to your terminal and type:

pio lib search Adafruit MQTT

Platform IO will now search for the relevant libraries and provide us with the results. Here we can see that we got the library we were looking for. We can see the Library ID at the top, in this case, it is 1092. We will use this ID to install the library.

Type the following command in the terminal to install the Adafruit MQTT library:

pio lib install 1092

This will install the Adafruit MQTT Library along with all of its dependencies. Now we need to install the Ethernet library. The ID for the Ethernet library is 872, which we will use to install the library. Follow the same steps as before to install it via Platform IO.

pio lib search Ethernet #This is optional
pio lib install 872

Finally, we need to install the Sodaq_SHT2x library. The ID for this library is 803, which we will use to install the library. Follow the same steps as before to install.

pio lib search Sodaq_SHT2x #This is optional
pio lib install 803

Now we are ready to compile our code. Save the main.cpp file. We will again use Platform IO to compile our code. Go to your terminal and type the following command.

pio run

The first time this command is run, Platform IO will download and install the relevant framework and toolchains required for the STM32. This process will take a few seconds.

Now Platform IO will compile our code and output a firmware.bin file. We need to copy this firmware file from the .pio/build/nucleo_f411re to /workspace. Usually you would need to use the cp command, but we have created a custom command called load-firmware for ease of use. Just write the following command and the firmware.bin file will be copied to the workspace folder.

load-firmware

Once we have copied the firmware.bin file, all we need to do is to reset the STM32 by pressing the red button above the STM32. After the reset, the STM32 will load the new firmware.

Now you have alerts set up for your weather station and you will receive notifications whenever the temperature crosses the threshold.

You can also create a dashboard for receiving the real-time Temperature and Humidity Data on your phone by using the MQTT Dashboard app. Refer to our guide for setting up the app.

pageConfiguring the MQTT Dashboard app

You need to create 2 tiles of the Progress type (like the Lux Value tile in the above guide) and connect them to the respective feeds.

You have completed the Weather Station with Alerts project. Now you can configure the project in any way you want and try to make something new.

Last updated