First project with Adafruit.IO

For a while now, I’ve been interested in exploring Internet-of-Things (IoT) sensors with the hopes of developing some type of platform that can be used for remote chemical education. I’ve also been making a lot of purchases at Adafruit because the pandemic, the state of our country, and the pile of grading on my desk have left me feeling depressed and in need of some comfort making.

This project is far from complete, but I know that I’ll get swamped with end-of-semester craziness and need to have some documentation of what I’ve done to date. Ideally, I’d put it into my maker logbook, but the piles on my desk (both ungraded papers AND unfinished electronics projects) have made it all but impossible to find that notebook. Thankfully, the keyboard is clear of debris.

So I’ve got a Huzzah32 microcontroller connected to a BMP180 temperature/pressure sensor. The Huzzah has built-in wifi and I’m using the Adafruit IO Arduino library to allow the microcontroller to send data to Adafruit.IO. Nothing I’ve done here is different from what one can find in the instructions for setting up that Arduino library or configuring an Adafruit.IO account. The code I’m running on the microcontroller is:

/*** For sensor ***/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>

/*** For JSON ***/
#include <ArduinoJson.h>

/*** For Adafruit.IO ***/
#include "config.h"


// Sensor
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
// Data stored here
StaticJsonDocument<200> doc;
// Control update
#define IO_LOOP_DELAY 30000
unsigned long lastUpdate;
// Set up the feed.  Create the feed if it does not exist.  Will not destroy data 
//   in existing feed
AdafruitIO_Feed *feed = io.feed("bmp180");

// TODO: Make logging to Serial optional
#define LOG

void setup() {
  sensor_t sensor; // For the sensor name
  // start the serial connection
  Serial.begin(115200);

  // wait for serial monitor to open
  while(! Serial);

  // Initialize sensor
  if(!bmp.begin())
  {
    Serial.print("No sensor detected");
    while(1);
  }
  // Print sensor name
  bmp.getSensor(&sensor);
  Serial.print ("Sensor:");
  Serial.println(sensor.name);
  
  Serial.print("Connecting to Adafruit IO");

  // connect to io.adafruit.com
  io.connect();

  // set up a message handler for the location feed.
  feed->onMessage(handleMessage);

  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  // we are connected
  Serial.println();
  Serial.println(io.statusText());
  feed->get(); // get last value on feed
}

void loop() {

  // process messages and keep connection alive
  io.run();

  // Send sensor data periodically
  if (millis() > (lastUpdate + IO_LOOP_DELAY)) {
    Serial.println("----- sending -----");
    sensors_event_t event;
    bmp.getEvent(&event);
    float temperature;
    float pressure;
    bmp.getTemperature(&temperature);
    bmp.getPressure(&pressure);


    // Create JSON with sensor data
    doc["temperature"] = temperature;
    doc["pressure"] = pressure;
    String output;
    output = "";
    serializeJson(doc,output);
    
    // WHY? Adafruit.IO doesn't like quotation marks in strings
    output.replace("\"","'");
    Serial.print("Sending: "); Serial.println(output);
    // Send faux JSON string to Adafruit.IO
    feed->save(output);
    
    lastUpdate = millis();
  }

}

void handleMessage(AdafruitIO_Data *data) {

  String received_value = data->toString();

  // print out the received values
  Serial.println("----- received -----");
  Serial.print("value: ");
  Serial.println(received_value);
}

One tricky thing here is that I’m trying to send both the temperature and pressure in a JSON-formatted string. However, for reasons that aren’t clear to me, Adafruit.IO isn’t allowing me to publish strings with double quotation marks in them. I’ve replaced the double quotation marks with singles, allowing the data to be published. I just have to remember to reverse the process when I grab the data. Speaking of grabbing…

Google sheets has some neat features that allow me to grab IoT sensor data and store it in a spreadsheet. Following these instructions, I was able to get the Adafruit.IO –> Google Sheets connection set up quite nicely. Below is the code I’m using on the Google Sheets side, and I’ve set a trigger to execute every minute.

function callAIO() {
  // Call Adafruit.IO
  var response = UrlFetchApp.fetch("https://io.adafruit.com/api/v2/bobthechemist/feeds/bmp180");
  
  // Parse the JSON reply
  var json = response.getContentText();
  var data = JSON.parse(json);
  var values = JSON.parse(data["last_value"].replace(/'/g,'"'));
  
  var sheet = SpreadsheetApp.getActiveSheet();
  var row = sheet.getLastRow();
  sheet.getRange(row + 1,1).setValue([data["updated_at"]]);
  sheet.getRange(row + 1,2).setValue([data["last_value"]]);
  sheet.getRange(row + 1,3).setValue([values["temperature"]]);
  sheet.getRange(row + 1,4).setValue([values["pressure"]]);
  
}

So when the Huzzah32 is connected to my home network, it is publishing sensor data to Adafruit.IO every 30 seconds. Google sheets is grabbing the latest value every minute (the fastest I apparently get trigger). I’m clearly losing 50% of the data, but for now, I don’t know if I really care. I don’t know if I would be using this setup to grab data faster than once per minute. I’d rather explore how to get the historical data that is stored in the Adafruit.IO feed or learn how to set up the webhooks so that Adafruit.IO notifies Google Sheets that data is available. The latter would be of interest in cases where data are not being collected at regular time intervals, but rather when the microcontroller user signals that data should be sent to the cloud.

Before signing off, I have to mention that this work is inspired by these instructions over at Libre Texts. Bob Belford has been putting a lot of work into figuring out IoT Chemistry instruction and has been very generous with sharing his ideas.

One thought on “First project with Adafruit.IO

  1. Piles of ungraded papers…I’m glad I’m not alone. Actually, for me, it’s piles of ungraded electronic papers…or something like that.
    Thank you for the heads up on Bob Belford’s work.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.