I like to keep an eye on the condition of my workspace. Is it hot or humid? This is important for me because my comfort is determined by the humidity level of the room.
I can turn the air conditioning on and off remotely, but I need to know the room's state. I have decided to write a program that will provide this information using the Arduino Opla IoT Kit. The device will display this information when I am close to it, and turn off the screen when I am not. It will also log the temperature and humidity to the Arduino IoT Cloud, and I can monitor this remotely. Follow along to recreate this project.
Project PlanningI want to know the condition of my study, both when I am in and when I am away. When I am in the room, I want to glance at a screen. When I am away, I want to know by looking at a dashboard on my phone. One more thing, I want the screen in the study to go off when there is nobody around. I have an Arduino Opla IoT Kit that contains everything I need. The MKR IoT Carrier comes with a temperature and humidity sensor, as well as an OLED screen. The specific components that I will be utilizing are:
- Arduino MKR WiFi 1010
- Arduino MKR IoT Carrier
- PIR Motion Sensor and Grove connector
- Micro-USB cable
Follow these steps to assemble your components:
- Attach the MKR board to the carrier, making sure to align the pins
- Place the carrier into the transparent housing, using the video on this page as a guide.
- Screw the carrier down in the housing
- Connect one end of the Grove cable to the A5 port of the carrier
- Connect the other end of the Grove cable to the PIR motion sensor
- Connect the MKR board to the Micro-USB cable
- Close the back of the case
- Connect the other end of the Micro-USB cable to the computer
If you don't have an account on the Arduino IoT Cloud, please go ahead and create one.
Next, go to the Devices tab and register your microcontroller. This could take up to five minutes so please be patient.
Connecting the MKR WiFi 1010 to Arduino IoT CloudBrowse to https://create.arduino.cc/iot/ to get started.
Begin by creating a new Thing. You can view a Thing as the equivalent of a project. You can give it any name you like. Mine is called MKR ENV.
Next, associate a device on the right of the screen. This will configure the device so that you can upload your sketch onto it. When this is done, configure your network by providing your WiFi credentials. If you have a device that lets you configure both a private and public (or guest) network, it's best to use the guest network for your IoT devices. That way, you avoid any security breaches.
Finally, add two Cloud Variables. These are what you are interested in tracking remotely on a dashboard. The two variables to add are:
- temperature, of type float, read only, 60s periodic update
- humidity, of type float, read only, 60s periodic update
Here is what the configuration screen for one of the variables looks like.
When you are done, you may proceed to the Sketch tab.
The Cloud CodeAt this point, you are ready to write code that updates the two Cloud Variables. To do this, I introduced a function. The code follows below.
void updateEnv() {
temperature = carrier.Env.readTemperature();
humidity = carrier.Env.readHumidity();
}
I only want this function to run once every minute, so I introduced a variable to keep track of the last time that I took the readings, and a constant that defines the interval between readings. These are shown below:
unsigned long lastRead = millis();
const int myDelay = 60000;
Then, within the loop() function, I call the updateEnv() function as needed. Here's the code below:
void loop() {
ArduinoCloud.update();
// Your code here
if (millis() - lastRead > myDelay) {
lastRead = millis();
updateEnv();
}
}
That is all that is required to send the readings up to the Arduino IoT Cloud. Next, Let's create a dashboard.
The DashboardTo create a dashboard, you can click on the Dashboard tab at the very top of the screen, or navigate to https://create.arduino.cc/iot/dashboards
Next, click on the Create button. On the next page, give your dashboard a name and then proceed to add widgets.
I like to use the Gauge and Percentage widgets to track the current state of temperature and pressure, while I use a chart to track historical states or trends. In the image below, you can see an example of adding a Gauge.
You can give the new widget a name. You will need to link it to a variable, and this is where you link it to the temperature variable. You can also set a minimum and maximum value for the gauge.
The following image is a screenshot of my working dashboard as seen from a computer. I can see both the current values, as well as the historicals.
I can also view the dashboard from my phone using the Arduino IoT Remote app.
The next set of codes is designed to let me see the temperature and humidity on the screen. The result looks like the following image.
At this point, you will need to go back to the Sketch editor, and then click on "Open full editor".
The icons on the screen need to be introduced as code. The easiest way of doing this is by converting images of the right size into a character array. You can do this at the following URL: https://javl.github.io/image2cpp/
You will then need to add a file called logos.h and then copy your character arrays into it. The following image illustrates what this file would look like.
Back in the.ino file, I defined a function that renders all of the information on the screen.
void displayReadings(String t, float temp, float humid) {
carrier.display.fillScreen(0x0000);
carrier.display.setCursor(60, 30);
carrier.display.setTextSize(3);
carrier.display.print(t);
carrier.display.setCursor(25, 60);
carrier.display.setTextSize(3);
carrier.display.drawBitmap(25, 70, m_thermostat, 48, 48, 0xDAC9);
carrier.display.setCursor(75, 80);
carrier.display.print(temp);
carrier.display.print(" C");
carrier.display.drawBitmap(25, 130, m_humidity, 48, 48, 0x0D14);
carrier.display.setCursor(75, 140);
carrier.display.print(humidity);
carrier.display.print(" %");
}
This function takes a few parameters: the current time, the temperature, and the pressure. Notice the carrier. This is the instance of the class that controls the MKR IoT Carrier. We declare this at the top of the sketch.
MKRIoTCarrier carrier;
The carrier needs to be initialized. The code for that appears in the setup() function.
//Initialize the MKR IoT Carrier
delay(1500);
CARRIER_CASE = false;
carrier.begin();
carrier.display.setRotation(0);
display("Starting ..");
Notice the display() function. This is also defined within the sketch. The implementation of display() follows:
void display(String text) {
carrier.display.fillScreen(0x0000);
carrier.display.setCursor(25, 100);
carrier.display.setTextSize(3);
carrier.display.print(text);
}
In order to get the current time I chose an approach that avoids reading from the cloud every time. Instead, I set up an instance of a real-time clock and set the time once by getting the Unix time from the Arduino Cloud. The variables are defined below.
unsigned long epochs;
RTCZero myRtc;
The RTC is initialized in the following code block.
//Initialize the clock
myRtc.begin();
epochs = ArduinoCloud.getLocalTime();
initializeClock(epochs, &myRtc);
The function initializeClock() updates the RTC instance with the desired time. The function is implemented as follows:
void initializeClock(unsigned long epochs, RTCZero* rtc) {
UnixTime t(0);
t.getDateTime(epochs);
uint8_t y = t.year - 2000;
rtc->setDate(t.day, t.month, y);;
rtc->setTime(t.hour, t.minute, t.second);
}
To read the time, the following functions are required:
String getRTCTime(RTCZero* rtc) {
String t = zeroPad(rtc->getHours());
t.concat(":");
t.concat(zeroPad(rtc->getMinutes()));
t.concat(":");
t.concat(zeroPad(rtc->getSeconds()));
return t;
}
String zeroPad(int n) {
if (n > 9) {
return String(n);
}
String s = String(0);
s.concat(n);
return s;
}
Finally, we can bring all these together to either display something on the screen or not depending on what the PIR sensor has observed. The sketch is available here: https://create.arduino.cc/editor/johnthas/399971c3-9ed7-48de-8cf9-a0955d60c08c/preview
Comments