Electronics Software Development

Adafruit IO: Connecting Your Arduino To The Outside World

Arduino And AdafruitIO Graphic
Written by John Woolsey

Skill Level: Intermediate

Introduction

This tutorial will teach you how to use the Adafruit IO service to connect your Arduino Uno WiFi Rev2 to the outside world. A basic understanding of electronics and programming is expected along with some familiarity with the Arduino platform. If you are new to Arduino or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On An Arduino Uno tutorial before proceeding with this one. In addition, this tutorial will use a solderless breadboard to build a simple circuit from a schematic diagram. The Core Electronics’ How to Use Breadboards, Science Buddies’ How to Use a Breadboard, and SparkFun’s How to Read a Schematic guides are good resources for learning how to translate a schematic to a breadboard.

The resources created for this tutorial are available on GitHub for your reference.

What Is Needed

Background Information

In a previous article, Controlling An Arduino Uno WiFi Rev2 Or Arduino Uno With WiFi Shield From A Web Browser, I described how to create and run a web server on your Arduino Uno. This worked well for accessing your Arduino over a local network, but it was not visible over the internet. In order to extend this approach and allow your Arduino based server to be accessed over the internet, techniques such as port forwarding, external hosting, static IP addressing, or use of a Dynamic DNS service are required. Although doable, these techniques can be complicated, costly, or not very secure. For these reasons, they are not usually the best fit for hobbyists to access their Arduino devices over the internet.

This tutorial will instead utilize Adafruit’s Adafruit IO service to connect an Arduino to the outside world. Adafruit IO is free, secure, compatible across many development boards, and allows your device to be accessed privately or shared to others if you so choose. Upgrades are available, but the free tier gives us a lot to work with and may be all that you will ever need. Also note that the Adafruit IO service is still in beta so some changes are expected over time. Please see the Internet of Things for Everyone and Adafruit IO Basics learning guides for additional information on using the Adafruit IO service. There is even a general category listing that contains all kinds of Adafruit IO based projects.

My development system consists of the Arduino Uno WiFi Rev2 development board connected to a macOS based computer running the desktop Arduino IDE. If you are using a different Arduino board or computer setup, the vast majority of this tutorial should still apply, however, some minor changes may be necessary.

If you need assistance with your particular setup, post a question in the comments section below and I, or someone else, can try to help you.

Adafruit IO Setup

This project will connect an LED and a potentiometer to an Arduino that we will then associate with the Adafruit IO service for access and control. But before we do that, we need to configure our intentions on Adafruit IO.

If you don’t already have an Adafruit account, go to their website and sign up for one now. Please note that the Adafruit IO service does not require a separate account. Once your account is created, head over to the Adafruit IO site.

Now, let’s create our feeds. Feeds hold the meta data and values associated with a particular component or sensor. They are unique to each individual source of data you send to the system. In our case, we need two feeds, one for a potentiometer and one for an LED.

Click Feeds in the left hand panel of the Adafruit IO site. Click the Actions drop down and select Create a New Feed. In the Create a new Feed window that pops up, enter Potentiometer in the Name field along with an optional Description such as Potentiometer value. Click the Create button when done. Then create a Red LED feed in the same fashion. The Key column in the Feeds listing displays the identifiers that we will use in our program. The keys of potentiometer and red-led are shown for the feeds we just created.

If you click on the individual feeds, you will be provided additional information and settings specific to that feed. The main area presents recent data in both visual and listing formats. Clicking the gear icons along the right allows you to change settings for your feed such as privacy and sharing controls.

Now we need a way to visualize and communicate with the feeds. Dashboards are used for this purpose. Widgets such as indicators, sliders, buttons, and charts are available.

Let’s create a dashboard for our project. Click Dashboards in the left hand panel. Click the Actions drop down and select Create a New Dashboard. In the Create a new Dashboard window that pops up, enter Arduino in the Name field along with an optional Description such as Arduino based project. Feel free to name the dashboard something that has meaning to you. Click the Create button when done.

Now it is time to add our blocks (widgets) to visually interact with our feeds (data).

Click the Arduino dashboard we just created and you will be presented with a blank canvas. Click the + icon in the upper right corner of the page and a Create a new block pop-up window will appear with a table of available blocks we can choose. Hovering over the blocks will provide the name of the block. Select the Toggle block. In the next Choose feed window, select the Red LED feed and then click the Next step button. In the Block settings window, enter Red LED Control in the Block Title field and leave the Button On Text and Button Off Text fields as ON and OFF respectively.

You can test the values that will be produced by clicking on the toggle switch on the right side of the window. Click the Create block button to finish. Your block should now be displayed on the screen.

Next, create a Gauge block for the potentiometer and choose the Potentiometer feed. In the Block settings window, enter Potentiometer for the Block Title field, 0 for Gauge Min Value, 1023 for Gauge Max Value, 102 for Low Warning Value, and 921 for High Warning Value. The high and low values correspond to the top and bottom 10% of possible values. Leave the rest of the fields with their default values and click the Create block button. The Potentiometer will be displayed below the Red LED Control bock.

The dashboard’s gear icon can be used to adjust your display settings such as size, location, and even change each block’s fields we initially set when an individual block’s gear icon is clicked. If you make any changes, make sure to click the Save button when finished.

Adafruit IO is now ready to interact with our program. Before we leave, we need to retrieve our account credentials that will be required for our program to access the system. Click the Dashboards link at the top of the page to bring you back a level. Then click the View AIO Key link in the left panel and the YOUR AIO KEY popup window will appear. Copy the Username and Active Key values shown for your account and save them for later use.

Building The Circuit

Before connecting any circuitry to your Arduino board, disconnect it from power and your computer. This avoids accidental damage during wiring.

Place the components and wire up the circuit on a breadboard according to the schematic diagram shown below and then connect it to your Arduino Uno.

Arduino LED And Potentiometer Schematic
Schematic Diagram Of LED And Potentiometer Circuit

The circuit should look similar to the one shown below once completed.

Arduino LED And Potentiometer Circuit
Completed LED And Potentiometer Circuit

Once the circuit is built, you can connect your Arduino to your computer with the USB cable.

Writing The Software

Adafruit IO does not yet officially support the Arduino Uno WiFi Rev2, but with assistance from the Adafruit team, I was able to get it working with a few work-arounds. These will be mentioned as they are needed.

Let’s first install the required libraries. The first work-around we need to apply is to use Adafruit’s modified version of the standard WiFiNINA library. Uninstall Arduino’s official WiFiNINA library if it is installed. This simply entails closing the Arduino IDE if it is open and then deleting the WiFiNINA library from the default library location, typically located in the ~/Documents/Arduino/libraries directory. Once deleted, go to Adafruit’s GitHub repository for the modified WiFiNINA library and then download the library as a zip file. This is available by clicking on the green Clone or download button within GitHub and then selecting Download ZIP. Next, open the Arduino IDE, select Sketch > Include Library > Add .ZIP Library… from the main menu and then Choose your zip file from the pop-up window to install the library. Note, I am told that Adafruit plans to name this library differently in order to avoid these naming conflicts in the future.

Next, we need to install a few more libraries. These are standard libraries and can be installed in the traditional way through the Library Manager. Install the Adafruit IO Arduino, Adafruit MQTT Library, and ArduinoHttpClient libraries.

Now, create a sketch named AIO_LED_Pot with the code shown below.

// AIO_LED_Pot - AIO_LED_Pot.ino
//
// Description:
// Interfaces an LED and a potentiometer on an Arduino Uno WiFi Rev2 with the
// Adafruit IO service.
// Note: Must use Adafruit's modified version of the WiFiNINA library
// (https://github.com/adafruit/WiFiNINA), define USE_AIRLIFT, and instantiate
// AdafruitIO_WiFi with pin connections for Arduino Uno WiFi Rev2 compatability.
// NOTE: The sketch sometimes gets stuck initially connecting to the service and
// needs to be reuploaded.
//
// Circuit:
// Red LED connected to pin D2.
// 10K potentiometer connected to pin A0.
//
// Created by John Woolsey on 05/29/2019.
// Copyright © 2019 Woolsey Workshop.  All rights reserved.


// Defines
#define AIO_USERNAME    "your_aio_username"
#define AIO_KEY         "your_aio_key"
#define AIO_POT_FEED    "potentiometer"
#define AIO_REDLED_FEED "red-led"
#define WIFI_SSID       "your_wifi_ssid"
#define WIFI_PASS       "your_wifi_password"
#define USE_AIRLIFT     // required for Arduino Uno WiFi R2 board compatability


// Libraries
#include <AdafruitIO_WiFi.h>


// Pin Mapping
const byte RedLED =  2;
const byte Pot    = A0;


// Constructors
AdafruitIO_WiFi aio(AIO_USERNAME, AIO_KEY, WIFI_SSID, WIFI_PASS, SPIWIFI_SS, SPIWIFI_ACK, SPIWIFI_RESET, NINA_GPIO0, &SPI);
AdafruitIO_Feed *potFeed = aio.feed(AIO_POT_FEED);
AdafruitIO_Feed *redLEDFeed = aio.feed(AIO_REDLED_FEED);


void setup() {
   // Pin configuration
   pinMode(RedLED, OUTPUT);

   // Serial bus initialization (Serial Monitor)
   Serial.begin(9600);
   while(!Serial);  // wait for serial connection

   // Adafruit IO connection and configuration
   Serial.print("Connecting to Adafruit IO");
   aio.connect();  // connect to Adafruit IO service
   while(aio.status() < AIO_CONNECTED) {
      Serial.print(".");
      delay(1000);  // wait 1 second between checks
   }
   Serial.println();
   Serial.println(aio.statusText());  // print AIO connection status
   // Set up message handler that calls function when messages are received
   redLEDFeed->onMessage(redLEDMessageHandler);

   // Synchronize current state
   redLEDFeed->get();  // request feed value (message) from AIO
}


void loop() {
   aio.run();  // keep client connected to AIO service
   int potValue = analogRead(Pot);
   potFeed->save(potValue);  // send potentiometer value to AIO
   Serial.print("Potentiometer feed sent <- ");  Serial.println(potValue);
   delay(5000);  // limit AIO updates (30 per minute on free tier)
}


// Handles Red LED feed message received from AIO
void redLEDMessageHandler(AdafruitIO_Data *data) {
   String value = data->toString();  // capture feed value from AIO
   Serial.print("Red LED feed received -> ");  Serial.println(value);
   digitalWrite(RedLED, value == "ON" ? HIGH : LOW);
}

Let’s take a look at some of the more interesting parts of the code.

Lines 21 and 22 hold your Adafruit IO credentials. Change these values to those representing your account.

Lines 23 and 24 are the feed keys (identifiers) we previously set up on the Adafruit IO site.

Lines 25 and 26 hold your WiFi network credentials. Change these values to those for your network.

Line 27 is the next required work-around. It simply defines USE_AIRLIFT which is then checked internally by the Adafruit IO library for ESP32 module based WiFi configuration that is also used by our Uno.

Line 31 imports what we need from the Adafruit IO Arduino library. Note, the modified WiFiNINA library along with the other libraries are imported automatically and do not need to be explicitly imported separately.

Line 40 begins our configuration for connecting to the Adafruit IO service. We first initialize the service instance with the required account credentials and WiFi module pin settings using a name of aio. This is the last work-around necessary to make our Arduino Uno WiFi Rev2 compatible with the Adafruit IO service. Typically, only the Adafruit IO credentials are necessary, i.e. AdafruitIO_WiFi aio(AIO_USERNAME, AIO_KEY). The next two lines then set up pointers to our feeds.

Lines 54-61 go through the process of connecting to the Adafruit IO service, aio.connect() and aio.status(), and then prints the status, aio.statusText(), once connected.

Line 63 uses the onMessage() function to set up a message handler that calls the redLEDMessageHandler() function whenever a new message is received for the Red LED feed.

Line 66 uses the get() function to request a feed update from the service for the Red LED feed. When the update is received, the redLEDMessageHandler() function, defined in lines 80-84, is called that physically turns on or off the LED based on the current Red LED state as stored within the service. Specifically, line 81 captures the feed’s incoming data and then converts that data to a string with the toString() function. Other data type helpers, such as isTrue(), toBool(), toInt(), toFloat(), toPinLevel(), etc., are also available.

Line 71 executes the aio.run() function on each iteration of the loop in order to keep us connected to the Adafruit IO service.

Line 73 sends our potentiometer value to the AIO service using the save() function.

Line 75 delays execution for 5 seconds for each loop iteration. A delay is required so as not to flood the Adafruit IO service with requests. The free tier only allows 30 updates per minute, but I am being conservative by using 5 instead of the minimum 2 second delay.

If there is something that needs further explanation, please let me know in the comment section and I will try to answer your question.

Running And Testing The System

Now that our circuit is built and our software is written, it is time to run and test our project.

Open the Serial Monitor window (Tools > Serial Monitor) so that we can see the program’s output. Upload (Sketch > Upload) the sketch to the board and you should see Connecting to Adafruit IO printed to the screen followed shortly by Adafruit IO connected.

I don’t know if it is the modified WiFiNINA library or my implementation, but sometimes the sketch gets stuck and needs to be reuploaded to the board. This occurs when you initially see Connecting to Adafruit IO………. (dots continuing) without Adafruit IO connected. ever being printed.

Once the sketch is running, go back to the Adafruit IO website and open the Arduino dashboard. Click the Red LED Control switch (Toggle) and you should see the red LED light up on your breadboard. Yipee! Turn it on and off a few times to verify everything is working properly.

Next, slowly turn the potentiometer on your breadboard back and forth. You should see the Potentiometer Gauge on Adafruit IO displaying the new values. If you turn it to the extremes (values below 102 or above 921), you will see the gauge color change from blue to yellow alerting you that the value is either below the Low Warning Value or above the High Warning Value settings we set earlier. Keep in mind the values will only update every 5 seconds due to the delay we added to the end of the loop() function in the sketch.

Now that our project has data we created during testing, go back and look at the feed data on Adafruit IO. Click Feeds in the left panel then click the Potentiometer feed. If you do not see the left panel, click either your username or Dashboards links at the the top of the screen and it will become visible. You will see your recent data points along with when they were created. Do the same for the Red LED feed.

Before we end, now would be a good time to upload the BareMinimum sketch (File > Examples > 01.Basics > BareMinimum) to reset all pins back to their default states.

Keep in mind we are still using Adafruit’s modified version of the WiFiNINA library. You may want to reinstall Arduino’s official WiFiNINA library at this time to get you back to the standard library setup.

Summary

In this tutorial, we learned how to use the Adafruit IO service to connect your Arduino Uno WiFi Rev2 to the outside world. We configured feeds for each of our connected electrical components and created a dashboard for interacting with those components on the Adafruit IO website. We wrote a sketch that communicates the states of our components with the Adafruit IO service and then used the service to interact with our components.

The final source code and schematic used for this tutorial are available on GitHub.

Don’t forget to check out all of the Adafruit IO based learning guides available by Adafruit.

Thank you for joining me in this journey and I hope you enjoyed the experience. Please feel free to share your thoughts in the comments section below.

About the author

John Woolsey

John is an electrical engineer who loves science, math, and technology and teaching it to others even more.
 
He knew he wanted to work with technology from an early age, building his first robot when he was in 8th grade. His first computer was a Timex/Sinclair 2068 followed by the Tandy 1000 TL (aka really old stuff).
 
He put himself through college (University of Texas at Austin) by working at Motorola where he worked for many years after that in Research and Development.
 
John started developing mobile app software in 2010 for himself and for other companies. He has also taught programming to kids for summer school and enjoyed years of judging kids science projects at the Austin Energy Regional Science Festival.
 
Electronics, software, and teaching all culminate in his new venture to learn, make, and teach others via the Woolsey Workshop website.

2 Comments

Leave a Comment