{"id":18516,"date":"2016-03-06T14:15:48","date_gmt":"2016-03-06T14:15:48","guid":{"rendered":"http:\/\/randomnerdtutorials.com\/?p=18516"},"modified":"2019-04-02T10:23:33","modified_gmt":"2019-04-02T10:23:33","slug":"raspberry-pi-web-server-using-flask-to-control-gpios","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/raspberry-pi-web-server-using-flask-to-control-gpios\/","title":{"rendered":"Raspberry Pi Web Server using Flask to Control GPIOs"},"content":{"rendered":"<p>In this project you\u2019ll create a standalone web server with a Raspberry Pi\u00a0that can toggle two LEDs. You can\u00a0replace those LEDs with any output (like a relay or a transistor).<\/p>\n<p>In order to create the web server you will be using a Python microframework called Flask.<!--more--><\/p>\n<p><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter wp-image-18549\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/featured-image.jpg?resize=701%2C394&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" width=\"701\" height=\"394\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/featured-image.jpg?w=850&amp;quality=100&amp;strip=all&amp;ssl=1 850w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/featured-image.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/featured-image.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 701px) 100vw, 701px\" \/><\/p>\n<h2>Parts Required<\/h2>\n<p>Here\u2019s the hardware that you need to complete\u00a0this project:<\/p>\n<ul>\n<li><a href=\"https:\/\/makeradvisor.com\/raspberry-pi-board\/\" target=\"_blank\" rel=\"noopener noreferrer\">Raspberry Pi <\/a>(any Pi\u00a0should work, I recommend using<a href=\"https:\/\/makeradvisor.com\/raspberry-pi-board\/\" target=\"_blank\" rel=\"noopener noreferrer\"> Raspberry Pi 3<\/a>) &#8211; read <a href=\"https:\/\/makeradvisor.com\/best-raspberry-pi-3-starter-kits\/\" target=\"_blank\" rel=\"noopener noreferrer\">Best Raspberry Pi Starter Kits<\/a><\/li>\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/microsd-card-raspberry-pi-16gb-class-10\/\" target=\"_blank\" rel=\"noopener noreferrer\">SD Card (minimum size 8Gb and class 10)\u00a0<\/a><\/li>\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/raspberry-pi-power-supply\/\" target=\"_blank\" rel=\"noopener noreferrer\">Micro USB Power Supply<\/a><\/li>\n<li>Ethernet cable or WiFi dongle<\/li>\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noopener noreferrer\">Breadboard\u00a0<\/a><\/li>\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/3mm-5mm-leds-kit-storage-box\/\" target=\"_blank\" rel=\"noopener noreferrer\">2x LEDs<\/a><\/li>\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/resistors-kits\/\" target=\"_blank\" rel=\"noopener noreferrer\">2x 470\u03a9 Resistors<\/a><\/li>\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noopener noreferrer\">Jumper wires<\/a><\/li>\n<\/ul>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-18437 aligncenter\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/RPi3.jpg?resize=299%2C254&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi 3\" width=\"299\" height=\"254\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/RPi3.jpg?w=472&amp;quality=100&amp;strip=all&amp;ssl=1 472w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/RPi3.jpg?resize=300%2C255&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 299px) 100vw, 299px\" \/><\/p>\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n<h2>Basic Raspberry Pi Setup<\/h2>\n<p>Before you continue reading this project, please\u00a0make sure you have Raspbian Operating System installed in your Raspberry Pi.<\/p>\n<p>You can read my <strong><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-with-raspberry-pi\/\">Getting Started with the Raspberry Pi Guide<\/a><\/strong>\u00a0to install Raspbian and complete the basic setup.<\/p>\n<h2>Installing Flask<\/h2>\n<p>We&#8217;re going to use a Python microframework called <a href=\"http:\/\/flask.pocoo.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Flask<\/a> to turn the Raspberry Pi into web server.<\/p>\n<p>To\u00a0install Flask, you&#8217;ll need to have pip installed. Run the following commands to update your Pi and install pip:<\/p>\n<pre class=\"\">pi@raspberrypi ~ $ sudo apt-get update\r\npi@raspberrypi ~ $ sudo apt-get upgrade\r\npi@raspberrypi ~ $ sudo apt-get install python-pip python-flask<\/pre>\n<p>Then, you use pip to install Flask and its dependencies:<\/p>\n<pre><code>pi@raspberrypi ~ $ sudo pip install flask<\/code><\/pre>\n<h2>Schematics<\/h2>\n<p>The schematics for this project are fairly straightforward.\u00a0Simply connect two LEDs to pins GPIO 23 and GPIO 24, as the figure below illustrates.<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" class=\"aligncenter size-full wp-image-18526\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/RPi-Web-Server-outputs_bb.jpg?resize=572%2C624&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RPi Web Server outputs_bb\" width=\"572\" height=\"624\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/RPi-Web-Server-outputs_bb.jpg?w=572&amp;quality=100&amp;strip=all&amp;ssl=1 572w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/RPi-Web-Server-outputs_bb.jpg?resize=275%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 275w\" sizes=\"(max-width: 572px) 100vw, 572px\" \/><\/p>\n<h2>Creating the Python\u00a0Script<\/h2>\n<p>This is the core script of our application. It sets up the web server and actually interacts with the Raspberry Pi GPIOs.<\/p>\n<p>To keep everything organized, start by creating a new folder:<\/p>\n<pre><code>pi@raspberrypi ~ $ mkdir web-server\r\npi@raspberrypi ~ $ cd web-server\r\npi@raspberrypi:~\/web-server $\r\n<\/code><\/pre>\n<p>Create a new file called <em>app.py<\/em>.<\/p>\n<pre><code>pi@raspberrypi:~\/web-server $ nano app.py<\/code><\/pre>\n<p>Copy and paste\u00a0the following script to your Raspberry Pi (this code is based on Matt Richardson great <a href=\"http:\/\/mattrichardson.com\/Raspberry-Pi-Flask\/\" target=\"_blank\" rel=\"noopener noreferrer\">example<\/a>).<br \/>\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">'''\n\nAdapted excerpt from Getting Started with Raspberry Pi by Matt Richardson\n\nModified by Rui Santos\nComplete project details: http:\/\/randomnerdtutorials.com\n\n'''\n\nimport RPi.GPIO as GPIO\nfrom flask import Flask, render_template, request\napp = Flask(__name__)\n\nGPIO.setmode(GPIO.BCM)\n\n# Create a dictionary called pins to store the pin number, name, and pin state:\npins = {\n   23 : {'name' : 'GPIO 23', 'state' : GPIO.LOW},\n   24 : {'name' : 'GPIO 24', 'state' : GPIO.LOW}\n   }\n\n# Set each pin as an output and make it low:\nfor pin in pins:\n   GPIO.setup(pin, GPIO.OUT)\n   GPIO.output(pin, GPIO.LOW)\n\n@app.route(&quot;\/&quot;)\ndef main():\n   # For each pin, read the pin state and store it in the pins dictionary:\n   for pin in pins:\n      pins[pin]['state'] = GPIO.input(pin)\n   # Put the pin dictionary into the template data dictionary:\n   templateData = {\n      'pins' : pins\n      }\n   # Pass the template data into the template main.html and return it to the user\n   return render_template('main.html', **templateData)\n\n# The function below is executed when someone requests a URL with the pin number and action in it:\n@app.route(&quot;\/&lt;changePin&gt;\/&lt;action&gt;&quot;)\ndef action(changePin, action):\n   # Convert the pin from the URL into an integer:\n   changePin = int(changePin)\n   # Get the device name for the pin being changed:\n   deviceName = pins[changePin]['name']\n   # If the action part of the URL is &quot;on,&quot; execute the code indented below:\n   if action == &quot;on&quot;:\n      # Set the pin high:\n      GPIO.output(changePin, GPIO.HIGH)\n      # Save the status message to be passed into the template:\n      message = &quot;Turned &quot; + deviceName + &quot; on.&quot;\n   if action == &quot;off&quot;:\n      GPIO.output(changePin, GPIO.LOW)\n      message = &quot;Turned &quot; + deviceName + &quot; off.&quot;\n\n   # For each pin, read the pin state and store it in the pins dictionary:\n   for pin in pins:\n      pins[pin]['state'] = GPIO.input(pin)\n\n   # Along with the pin dictionary, put the message into the template data dictionary:\n   templateData = {\n      'pins' : pins\n   }\n\n   return render_template('main.html', **templateData)\n\nif __name__ == &quot;__main__&quot;:\n   app.run(host='0.0.0.0', port=80, debug=True)\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/RPi-Web-Server\/app_outputs.py\" target=\"_blank\">View raw code<\/a><\/p><\/p>\n<h2>Creating the HTML File<\/h2>\n<p>Keeping HTML tags separated from your\u00a0Python script is how you\u00a0keep your project organized.<\/p>\n<p>Flask uses a template engine called <a href=\"http:\/\/jinja.pocoo.org\/docs\/templates\/\" target=\"_blank\" rel=\"noopener noreferrer\">Jinja2<\/a>\u00a0that you can use to send dynamic data from your Python script to your HTML file.<\/p>\n<p>Create a new folder called templates:<\/p>\n<pre class=\"\">pi@raspberrypi:~\/web-server $ mkdir templates\r\npi@raspberrypi:~\/web-server $ cd templates\r\npi@raspberrypi:~\/web-server\/templates $<\/pre>\n<p>Create a new file called <em>main.html<\/em>.<\/p>\n<pre class=\"\">pi@raspberrypi:~\/web-server\/templates $ nano main.html<\/pre>\n<p>Copy and paste\u00a0the following template\u00a0to your Pi:<br \/>\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">&lt;!DOCTYPE html&gt;\n&lt;head&gt;\n   &lt;title&gt;RPi Web Server&lt;\/title&gt;\n   &lt;!-- Latest compiled and minified CSS --&gt;\n   &lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.6\/css\/bootstrap.min.css&quot; integrity=&quot;sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7&quot; crossorigin=&quot;anonymous&quot;&gt;\n   &lt;!-- Optional theme --&gt;\n   &lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.6\/css\/bootstrap-theme.min.css&quot; integrity=&quot;sha384-fLW2N01lMqjakBkx3l\/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r&quot; crossorigin=&quot;anonymous&quot;&gt;\n   &lt;!-- Latest compiled and minified JavaScript --&gt;\n   &lt;script src=&quot;https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.6\/js\/bootstrap.min.js&quot; integrity=&quot;sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n\n&lt;body&gt;\n   &lt;h1&gt;RPi Web Server&lt;\/h1&gt;\n   {% for pin in pins %}\n   &lt;h2&gt;{{ pins[pin].name }}\n   {% if pins[pin].state == true %}\n      is currently &lt;strong&gt;on&lt;\/strong&gt;&lt;\/h2&gt;&lt;div class=&quot;row&quot;&gt;&lt;div class=&quot;col-md-2&quot;&gt;\n      &lt;a href=&quot;\/{{pin}}\/off&quot; class=&quot;btn btn-block btn-lg btn-default&quot; role=&quot;button&quot;&gt;Turn off&lt;\/a&gt;&lt;\/div&gt;&lt;\/div&gt;\n   {% else %}\n      is currently &lt;strong&gt;off&lt;\/strong&gt;&lt;\/h2&gt;&lt;div class=&quot;row&quot;&gt;&lt;div class=&quot;col-md-2&quot;&gt;\n      &lt;a href=&quot;\/{{pin}}\/on&quot; class=&quot;btn btn-block btn-lg btn-primary&quot; role=&quot;button&quot;&gt;Turn on&lt;\/a&gt;&lt;\/div&gt;&lt;\/div&gt;\n   {% endif %}\n   {% endfor %}\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/RPi-Web-Server\/main_outputs.html\" target=\"_blank\">View raw code<\/a><\/p><\/p>\n<h2>Launching the Web Server<\/h2>\n<p>To launch your Raspberry Pi web server move to the folder that contains the file <em>app.py<\/em>:<\/p>\n<pre class=\"\">pi@raspberrypi:~\/web-server\/templates $ cd ..<\/pre>\n<p>Then run the following command:<\/p>\n<pre class=\"\">pi@raspberrypi:~\/web-server $ sudo python app.py<\/pre>\n<p>Your web server should start immediately!<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18537\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/python-launch-web-server.png?resize=668%2C281&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"python launch web server\" width=\"668\" height=\"281\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/python-launch-web-server.png?w=737&amp;quality=100&amp;strip=all&amp;ssl=1 737w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/python-launch-web-server.png?resize=300%2C126&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><\/p>\n<h2>Demonstration<\/h2>\n<p>Open your Raspberry Pi address in your browser by entering its IP address, in my case:\u00a0<span style=\"text-decoration: underline;\">http:\/\/192.168.1.98\/.<\/span><\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-18541\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/rpi-web-server-browser.png?resize=384%2C397&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"rpi web server browser\" width=\"384\" height=\"397\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/rpi-web-server-browser.png?w=384&amp;quality=100&amp;strip=all&amp;ssl=1 384w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/rpi-web-server-browser.png?resize=290%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 290w\" sizes=\"(max-width: 384px) 100vw, 384px\" \/><\/p>\n<p>Here\u2019s a video demo of the web server in action.<\/p>\n<p style=\"text-align:center\"><iframe width=\"720\" height=\"405\" src=\"https:\/\/www.youtube.com\/embed\/aACyWd4FJWs?rel=0\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p>I hope you&#8217;ve found this tutorial useful.<\/p>\n<p><strong>Share this post<\/strong> with a friend that also likes electronics!<\/p>\n<p>You can contact me by leaving a comment. If you like this post probably you might like my next ones, so please support me by <a href=\"https:\/\/randomnerdtutorials.com\/download\">subscribing my blog<\/a>.<\/p>\n<p>Thanks for reading,<\/p>\n<p>-Rui Santos<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this project you\u2019ll create a standalone web server with a Raspberry Pi\u00a0that can toggle two LEDs. You can\u00a0replace those LEDs with any output (like a relay or a transistor). &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Raspberry Pi Web Server using Flask to Control GPIOs\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-web-server-using-flask-to-control-gpios\/#more-18516\" aria-label=\"Read more about Raspberry Pi Web Server using Flask to Control GPIOs\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":18549,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[301,214,258,225,264,190,268,192,257],"tags":[],"class_list":["post-18516","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-0-raspberrypi","category-esp8266","category-flask","category-home-automation","category-project","category-raspberry-pi","category-raspberry-pi-project","category-r-tutorials","category-web-server-2"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/03\/featured-image.jpg?fit=850%2C478&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/18516","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=18516"}],"version-history":[{"count":0,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/18516\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/18549"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=18516"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=18516"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=18516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}