Electronics Software Development

Arduino Cloud: Connecting Your Raspberry Pi To The Outside World

Arduino Cloud And Raspberry Pi Graphic
Written by John Woolsey

Skill Level: Intermediate

Table Of Contents


This tutorial will teach you how to use the Arduino Cloud service to connect your Raspberry Pi to the outside world and interact with its connected electronics. We will attach and control an LED and read a button over the web.

A basic understanding of electronics and programming is expected along with some familiarity with the Raspberry Pi platform. If you are new to Raspberry Pi, or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On A Raspberry Pi tutorial before proceeding with this one. This tutorial uses a solderless breadboard to build a circuit from a schematic diagram. The All About Circuit’s Understanding Schematics, SparkFun’s How to Read a Schematic, Core Electronics’ How to Use Breadboards, and Science Buddies’ How to Use a Breadboard 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.

This tutorial is provided as a free service to our valued readers. Please help us continue this endeavor by considering a GitHub sponsorship or a PayPal donation.

What Is Needed

Background Information

In a previous article, Controlling A Raspberry Pi From A Web Browser With Vapor 3, I described how to create and run a web server on your Raspberry Pi. This worked well for accessing your Raspberry Pi over a local network, but it was not visible over the internet. In order to extend this approach and allow your Raspberry Pi based server to be accessed over the internet, techniques such as port forwarding, external hosting, static IP addressing, or the 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 Raspberry Pis over the internet.

This tutorial will instead utilize the Arduino Cloud service to connect a Raspberry Pi to the outside world. Arduino Cloud is free, secure, compatible across many development boards, and allows your device to be accessed privately or shared with others if you so choose. Plan upgrades are available, but the free tier gives us a lot to work with and may be all you will ever need. Please see the How It Works guide and the general Arduino Cloud documentation for additional information on using the Arduino Cloud service.

I am using a Raspberry Pi 3 Model B running the Raspberry Pi OS operating system for this tutorial. If you are using a different Raspberry Pi model or a different OS that is similar to Raspberry Pi OS, 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.

Building The Circuit

Before connecting any circuitry to your Raspberry Pi, shut it down and disconnect it from power. This avoids accidental damage during wiring.

Construct the button and LED circuit on a breadboard and connect it to your Raspberry Pi’s GPIO pins according to the schematic shown below.

Raspberry Pi LED And Button Schematic
Schematic Diagram Of LED And Button Circuit Connected To A Raspberry Pi

Keep in mind that the anode (positive terminal) of an LED is longer than the cathode (negative terminal) when constructing your circuit. The circuit should look similar to the one shown below once completed.

Completed LED And Button Circuit
Completed LED And Button Circuit Connected To A Raspberry Pi

Once the circuit is built, connect power to your Raspberry Pi and boot it up.

Creating An Arduino Account

To use the Arduino Cloud, you will need an Arduino account. The same Arduino account is used for the online store, forums, and cloud services. Go to the Arduino website and sign in, or create a new account if you don’t already have one, by clicking the SIGN IN button in the top right corner of the home page.

Creating A Thing

In Arduino Cloud nomenclature, Things are the logical representations of physical devices. A Thing is comprised of the associated physical device (such as an Arduino board, a Raspberry Pi, or a smart lamp), network credentials, and one or more cloud variables. For supported boards, it also contains an associated sketch that is generated and updated automatically based on your configuration. A Thing uses a friendly name, e.g. Raspberry Pi or Living Room Lamp, for your actual physical device.

To create a Thing, we first need to go to the Arduino Cloud website. You can also access the Arduino Cloud site by clicking the cloud icon in the top right corner of most Arduino website pages. The home page should look like the following.

Arduino Cloud Home Page
Arduino Cloud Home Page

From there, select Things from the navigation panel on the left side of the page. If you have not created any Things yet, click the CREATE THING button at the bottom of the page. Otherwise, click the CREATE THING button in the top right corner of the page if a Thing already exists. If you are on the free Arduino Cloud plan, keep in mind that you are limited to two Things, so if you already have two, you will need to delete one first.

Rename the Untitled Thing (by clicking on the name and selecting the Rename option) to something that makes sense for your device. I chose Raspberry Pi Thing for the name of my Thing.

Associating A Device

Now we will associate a physical device, our Raspberry Pi board, with the logical Thing.

Select the Thing’s Setup tab, if it is not already selected, and then click the Select Device button within the Associated Device area.

If we had an existing device, we could select it here within the Associate device pop-up window that appears. Since we don’t, click the SET UP NEW DEVICE button to open the Setup Device pop-up window instead.

Next, choose the board type for your board. Since we are using a Raspberry Pi board in this tutorial, choose the Any Device type under the MANUAL section. This will allow us to connect and interact with the Arduino Cloud using a Python based program. Once the device type is selected, you will see a message letting you know that the sketch/program and network details will need to be handled outside of the Arduino Cloud since we are setting up a manual device. Click the CONTINUE button.

On the next page, name your device. I chose Raspberry Pi 3B for the name of my device. Click the NEXT button when you are done.

You will be presented with a secret key for your particular device that you need to save for later use. Save the generated PDF file and copy the Device ID and Secret Key values to a safe location. Click the I saved my device ID and Secret Key option and then click the CONTINUE button. Click the GOT IT button on the next page to close the window.

Details for the new device will be shown in the Associated Device area of the new Thing. The new device will also be listed on the Arduino Cloud’s Devices page.

Creating Cloud Variables

Cloud variables provide the communication links between your Thing and the Arduino Cloud service. They are synced using the MQTT protocol over a network connection. If a cloud variable is updated on your board (like reading a sensor), the service will also receive this value. We can then view this value from within an Arduino Cloud dashboard. Similarly, if you update a cloud variable from a dashboard, it also updates on your board. Cloud variables are attached to a specific Thing and a Thing can have one or more variables.

For our Thing, we will need cloud variables for the LED and button connected to our Raspberry Pi.

To create a new cloud variable for the LED, click the ADD button within the Cloud Variables area of your Thing. A new Add variable pop-up window will appear.

Enter the friendly cloud variable name of LEDState in the Name field.

We will ignore the Sync with other Things button at this time as it is used to sync a variable of one Thing with the variable of another Thing.

Select Boolean in the Select variable type field. This is the variable’s datatype that will be used within the associated program. Disable the Basic types button if you want to see all the datatypes available.

Change the name of the variable in the Declaration field to led_state. This is the name of the variable that will be used within the associated program.

Leave the Variable Permission field as Read & Write since we want to be able to control the LED from a dashboard. A Read & Write variable can work both as an input and an output; the data can be sent from the device to the cloud and vice versa. A Read Only variable can work only as an output; the data can be sent only from the device to the cloud.

Leave the Variable Update Policy as On change since we want to immediately update the board’s physical LED after turning on the logical LED in a dashboard. An On Change variable will be updated whenever the variable’s change in value is greater than or equal to a set threshold, if applicable. A Periodically variable will be updated each time a certain number of seconds has elapsed.

Your cloud variable’s configuration for the LED should look like that shown below.

Raspberry Pi Thing LEDState Cloud Variable Details
Raspberry Pi Thing LEDState Cloud Variable Details

Click the ADD VARIABLE button to add this cloud variable to your Thing.

The new variable will now be shown within the Cloud Variables section of your Thing.

Now let’s create a cloud variable for the button. Click the ADD button above the new Cloud Variables list to add the new variable. Use a friendly name of ButtonState, a datatype of Boolean, a declaration name of button_state, a permission of Read Only, and an update policy of On change.

Raspberry Pi Thing ButtonState Cloud Variable Details
Raspberry Pi Thing ButtonState Cloud Variable Details

Click the ADD VARIABLE button to add this variable.

If you tend to read my tutorials, you know I like to create a DEBUG flag within my programs that will print debugging messages when enabled. Although not required, let’s create a new cloud variable that will display those debugging messages within the dashboard as well. Create a new cloud variable with the following attributes: DebugMessage friendly name, Character String datatype, debug_message declaration name, Read Only permissions, and On change update policy.

Raspberry Pi Thing DebugMessage Cloud Variable Details
Raspberry Pi Thing DebugMessage Cloud Variable Details

Now that your Thing is created and configured, the completed Raspberry Pi Thing should look like the following.

Completed Raspberry Pi Thing
Completed Raspberry Pi Thing

Installing The Libraries

In the Arduino board version of this tutorial, Arduino Cloud: Connecting Your Arduino To The Outside World, the Arduino Cloud created a sketch template for us to use with the Arduino Cloud connection and cloud variables already configured for us. Since the Raspberry Pi Thing was manually configured, we need to create the associated program from scratch. But before we do, we first need to install the libraries required by the program.

Before installing the libraries, make sure you are running a recent stable OS release on the Raspberry Pi.

We will use a Python virtual environment to manage our libraries for our project. Begin by opening a terminal window on your Raspberry Pi, creating the project directory, and then going into that directory.

$ mkdir arduino_cloud_led_button
$ cd arduino_cloud_led_button

Next, create the virtual environment for the project.

$ python3 -m venv --system-site-packages .venv

Typically, you would not need to include the ‐‐system-site-packages option. However, since I could not get the GPIO Zero library to install properly within the local environment, I included this option to utilize the GPIO Zero library installed in the global environment.

Once the virtual environment is created, activate it.

$ source .venv/bin/activate

If you are using a C shell or equivalent command line interface, you will need to source the csh version instead.

$ source .venv/bin/activate.csh

Now that our virtual environment is active, including the use of global libraries, we can install the remaining Arduino IoT Cloud Python Client library. This library was written by Arduino to allow us to connect and interact with the Arduino Cloud using a Python based program.

$ pip3 install arduino-iot-cloud

Writing The Program

Before we create the program, we first need to create a secrets module that will hold our Arduino Cloud secrets, i.e. Device ID and Secret Key. Open your favorite code editor and create a new file named secrets.py with the code shown below.

The commented secrets.py module is available on GitHub.

cloud: dict[str, str] = {
    "device_id": "your_device_id",
    "secret_key": "your_secret_key",

Update the placeholders with the Device ID and Secret Key values we saved previously while creating our Raspberry Pi Thing.

Save the secrets.py file in the project directory when you are done adding your secrets.

Now let’s move on to the main program. Create a new program file named arduino_cloud_led_button.py with the code shown below.

The commented arduino_cloud_led_button.py program is available on GitHub.

import logging
from arduino_iot_cloud import ArduinoCloudClient
from gpiozero import Button, LED

    import secrets
except ImportError:
    print("Secrets are stored in secrets.py.")

DEBUG: bool = True

button: Button = Button(5)
led: LED = LED(21)
cloud_client: ArduinoCloudClient = None

def configure_cloud_client() -> None:
    global cloud_client
    cloud_client = ArduinoCloudClient(
    cloud_client.register("button_state", value=button.is_pressed)
    cloud_client.register("debug_message", value=None)
    cloud_client.register("led_state", value=None, on_write=led_state_changed)

def configure_logging() -> None:
    if DEBUG:
            format="%(asctime)s.%(msecs)03d %(message)s",

def button_pressed() -> None:
    cloud_client["button_state"] = True
    if DEBUG:
        print_debug_message("Button pressed.")

def button_released() -> None:
    cloud_client["button_state"] = False
    if DEBUG:
        print_debug_message("Button released.")

def led_state_changed(client: ArduinoCloudClient, value: bool) -> None:
    led.on() if value else led.off()
    if DEBUG:
        print_debug_message(f"Turned {'on' if value else 'off'} LED.")

def print_debug_message(message: str) -> None:
    cloud_client["debug_message"] = message

def main() -> None:
    button.when_pressed = button_pressed
    button.when_released = button_released
    if DEBUG:
        print_debug_message("DEBUG mode is enabled.")
        print_debug_message("DEBUG mode is disabled.")
    print("Press CTRL-C to exit.")

if __name__ == "__main__":

The program begins by importing the necessary libraries (lines 1-9), enabling DEBUG mode (line 11), and defining our global class instances (lines 13-15).

The configure_cloud_client() function configures the ArduinoCloudClient instance with the essential Arduino Cloud connection credentials along with registering the appropriate cloud variables for use with the service. The button_state variable is initialized with the current reading of the physical button’s state. The led_state variable is registered to call the led_state_changed() callback function each time the led_state variable changes. This function, defined beginning on line 46, turns on or off the LED as appropriate and prints the corresponding debug message if enabled.

The configure_logging() function configures the logging facility used by the arduino_iot_cloud library to convey debugging information to the user. The facility is only enabled if the DEBUG constant is set to True. The logging level may be adjusted to see more (DEBUG) or less (WARNING) information as desired.

button_pressed() and button_released() are the callback functions defined by the GPIO Zero library’s button instance (lines 58-59) to be called each time the button is either pressed or released respectively. These functions set the state of the button_state cloud variable, triggering a sync with the Arduino Cloud, and then print the button’s state to the screen if debugging is enabled.

The print_debug_message() function sets the debug_message cloud variable, so the message can be displayed on an Arduino Cloud dashboard, and then prints the message to the terminal screen. This function is called by other functions whenever local debugging messages are desired.

The main() function is the entry point of the program. Once configurations are done, the program calls the ArduinoCloudClient‘s start() method which enters an endless loop constantly keeping all of the cloud variables in sync.

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

Save your program when you are done editing.

Creating The Dashboard

To interact with our new Thing, we need to create a dashboard.

Go to the Dashboards page within the Arduino Cloud by clicking the navigation icon in the top left corner of the page and selecting Dashboards. Then click the CREATE DASHBOARD button to create a new dashboard. Click the Untitled dashboard name and select Rename to rename your dashboard to something that makes sense for your project. I chose Raspberry Pi Dashboard for mine.

Click the ADD button within the toolbar and select Switch from the pop-up menu to add a Switch widget that we will use to control our LED. Change the name of the switch within the Name field to LED Switch to reflect the purpose of the switch. Click the Link Variable button, select the LEDState cloud variable (associated with the Raspberry Pi Thing), and then click the LINK VARIABLE button to link the LEDState variable to this widget. The widget’s details should look like the following.

Raspberry Pi Dashboard LED Switch Widget Details
Raspberry Pi Dashboard LED Switch Widget Details

Click the DONE button to finish creating your LED Switch widget and add it to the dashboard.

Next, click the ADD button again to add the Status widget for use with the button. This time, name the status as Button Status and link the ButtonState cloud variable.

Raspberry Pi Dashboard Button Status Widget Details
Raspberry Pi Dashboard Button Status Widget Details

Click the DONE button to finish creating your status widget.

Finally, let’s add a way to view the debug messages. Click the ADD button once more and select the Messenger widget this time. Name it Debug Messages and link the DebugMessage cloud variable.

Raspberry Pi Dashboard Debug Messages Widget Details
Raspberry Pi Dashboard Debug Messages Widget Details

Click the DONE button to add the widget.

All the widgets are now added to the dashboard. If you need to modify a widget, hover over the widget and select the vertical ellipsis menu that appears at the top right corner of the widget. From there you can edit, remove, or duplicate the widget.

If you want to modify the layout of the widgets, click the Arrange widgets (directional arrows) button in the toolbar next to the ADD button and then drag around and resize the widgets as desired. Click the DONE button when finished.

When you are happy with your dashboard, select the view mode (eyeball in the toolbar selector switch).

My Raspberry Pi Dashboard looks like the following.

Completed Raspberry Pi Dashboard
Completed Raspberry Pi Dashboard

Running The Program

So now we have a Thing, an associated program, and a Dashboard to communicate with the Thing. Let’s run the program and see how this all works.

From within your project directory, run your program.

$ python3 arduino_cloud_led_button.py

Once the program is running, you will see status messages printed to the screen from the Arduino Cloud service along with our own debugging messages that were added to the program.

Interacting With Your Thing

Go back to your dashboard. Hopefully, you should see messages already being printed to the Debug Messages widget, such as Running in DEBUG mode. and Turned off LED. (the initial cloud variable sync).

Toggle ON and OFF the switch within the LED Switch widget and watch the LED connected to the Raspberry Pi turn on and off. You should also see the appropriate LED based debugging messages being printed to the Debug Messages widget within the dashboard and the program’s terminal window each time you do so.

Press and release the button connected to your Raspberry Pi several times and watch the Button Status widget change on the dashboard. You should also see the appropriate debugging messages being printed.

Press CTRL-C to exit the program when you are done and then deactivate the project’s Python virtual environment.

$ deactivate

The Arduino IoT Cloud Remote App

The web based dashboard is not the only place where we can interact with our Thing.

The Arduino IoT Cloud Remote app is the official companion app for the Arduino Cloud. It provides the ability to view your dashboards and interact with your Things via an app on your mobile phone.

Download and install the app from either the Apple App Store or the Google Play Store. Once installed, open the app, complete the onboarding process (if presented), and then log into your Arduino account. When finished, you should land on the Dashboards screen and see a list of your available dashboards. Click on your dashboard and then interact with your Thing just like you did from the webpage.

A very cool feature of the Arduino IoT Cloud Remote app is the ability to provide access to your phone’s internal sensors, e.g. GPS, IMU, etc., as cloud variables. These variables can then be used to view the sensor data within your dashboards. You can also synchronize the variables with the cloud variables of other Things so that they have access to the data provided by your phone’s sensors.

To access your phone’s sensors, click Devices in the tab bar at the bottom of the app, tap TRY PHONE AS DEVICE located at the top of the screen, and then follow the configuration process. If this option is not available, you can also click on your profile icon in the top right corner of the app, and then select Phone as device under Settings. Note that only a select group of sensors are available (and automatically selected) with the free Arduino Cloud plan; more sensors are available with a paid plan. Your phone will ask if the app can have access to your phone’s sensor data. Once complete, the configuration process will automatically create a new Thing (named iPhone Thing for my phone) and a new dashboard (named iPhone Dashboard for my phone) with default widgets to view your phone’s sensors’ real time data, and then open the new dashboard. The new dashboard will even be available on your Dashboards page on the web.

On my phone, the dashboard shows values for the Accelerometer X, Accelerometer Y, and Accelerometer Z values, a Linear accelerometer graph, and a GPS map showing the location of my phone. Move your phone around to different orientations and watch the accelerometer data change in the dashboard. For the adventurous, move around your yard or neighborhood and watch as your location changes on the map; it is good exercise for us nerds anyway.

By default, your phone’s sensor data will only be available while the app is open. If you want to enable access to the sensors in the background, click on your profile icon in the top right corner of the app, select the Phone as Device menu option under Settings, and then enable the Background data stream option. Note that this feature is only available with paid plans. Exit out of your profile and select the Dashboards tab to get back to your list of dashboards.

Close the Arduino IoT Cloud Remote app when you are done.

Additional Resources

The following is a list of additional resources you may find helpful.


In this tutorial, we learned how to use the Arduino Cloud service to connect your Raspberry Pi to the outside world.

Specifically, we

  • connected an LED and a button to our Raspberry Pi.
  • created a new Arduino account, or signed in to an existing one, to access the Arduino Cloud service.
  • created and configured a logical Arduino Cloud Thing consisting of a Raspberry Pi as the physical device along with the LEDState (connected LED), ButtonState (connected button), and DebugMessage cloud variables.
  • created a dashboard using the Switch (LED Switch), Status (Button Status), and Messenger (Debug Messages) widgets.
  • wrote and executed a Python based program to communicate with our Arduino Cloud Thing.
  • interacted with the logical Thing from the dashboard, both from the Arduino Cloud website and the Arduino IoT Cloud Remote app.
  • used the Arduino IoT Cloud Remote app to access and view data from our mobile phone’s internal sensors.

Hopefully, this tutorial taught and inspired you how to use the Arduino Cloud service to connect and control your own devices. By attaching external sensors, actuators, etc. to your board, you can use the service to control elements in your smart home, monitor environmental conditions from far away locations, or a myriad of other uses.

I only covered a subset of the Arduino Cloud features available to get you started. To learn more, check out the Arduino Cloud documentation and tutorials pages.

The final source code and schematic used for this tutorial are available on GitHub. The GitHub version of the code is fully commented to include additional information, such as the program’s description, circuit connections, code clarifications, and other details. The comments are also Sphinx compatible in case you want to generate the code documentation yourself.

As a reminder, this tutorial was provided as a free service to our valued readers. Please help us continue this endeavor by considering a GitHub sponsorship or a PayPal donation.

Thank you for joining me on this journey and I hope you enjoyed the experience. Please feel free to share your thoughts or questions 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 electronics 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 (The University of Texas at Austin) by working at Motorola where he worked for many years afterward in the Semiconductor Products Sector 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.

Leave a Comment

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