Using Flask to Send Data to a Raspberry Pi

Pages
Contributors: SFUptownMaker
Favorited Favorite 7

Raspberry Pi Software

Let's get down to business and program the Raspberry Pi to serve a web app that we can use for data connection. This tutorial assumes that you have some familiarity with Linux and Python to follow along.

Installing Flask

The first step is adding support for Flask to the RasPi. Python is already installed and support for using GPIO through Python, so we don't need to worry about that.

All of these commands can be run either on a serial terminal opened on the Raspberry Pi directly with the Pi hooked up to a monitor, or remotely with a Pi via an SSH connection. However, we're not going to get into how to set up and run a Pi without a monitor.

The first thing you need to do is install the Flask framework. There are a lot of additional packages that can be used with Flask, but we only need the basic package for this tutorial.

sudo pip install flask

Next, we're going to create the directory within which the app will run. These commands will create the directory and ensure that you're working inside that directory.

mkdir FlaskTutorial
cd FlaskTutorial

The next step is to create a blank Python file in the directory called "app.py". This is the file that we're going to put our code into. Open that file in your favorite text editor (the Pi has vi, nano, and a textpad).

touch app.py

Then put the following code into it.

language:python
#!/usr/bin/python

from flask import Flask
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)  # Sets up the RPi lib to use the Broadcom pin mappings
                        #  for the pin names. This corresponds to the pin names
                        #  given in most documentation of the Pi header
GPIO.setwarnings(False) # Turn off warnings that may crop up if you have the
                        #  GPIO pins exported for use via command line
GPIO.setup(2, GPIO.OUT) # Set GPIO2 as an output

app = Flask(__name__)   # Create an instance of flask called "app"

@app.route("/")         # This is our default handler, if no path is given
def index():
    return "hello"

# The magic happens here. When some http request comes in with a path of
#  gpio/x/y, the Flask app will attempt to parse that as x=pin and y=level.
#  Note that there is no error handling here! Failure to properly specify the
#  route will result in a 404 error.
@app.route('/gpio/<string:id>/<string:level>')
def setPinLevel(id, level):
    GPIO.output(int(id), int(level))
    return "OK"

# If we're running this script directly, this portion executes. The Flask
#  instance runs with the given parameters. Note that the "host=0.0.0.0" part
#  is essential to telling the system that we want the app visible to the 
#  outside world.
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

There are comments in the code to cover most questions but I want to highlight three things:

  • First, there's no error checking here. The message is passed as the path requested via an HTTP request, and that request can contain just about anything. A request of the format GET /gpio/2/0 will set the pin low, for instance. However, GET /bats/are/bugs is equally valid, it just won't do anything and the app will return a "404 error."

  • Second, the parameter host='0.0.0.0' is required to let the app know that you want the application visible to external clients. If you omit this, you'll still be able to test the app by visiting localhost:5000 in a web browser on the Pi, it just won't be visible externally.

  • Third, the most commonly used port number is 5000, but you can use any port you want.