قالب وردپرس درنا توس
Home / Tips and Tricks / How to control electronics from a browser using MicroPython in Jupyter Notebook «Zero Byte :: WonderHowTo

How to control electronics from a browser using MicroPython in Jupyter Notebook «Zero Byte :: WonderHowTo



If you want to control electronic devices, e.g. a relay or motor, you can do it with MicroPython with an ESP8266 and browser. Normally you would program an ESP8266 with Arduino, but C ++, which Arduino uses, is not always the easiest programming language for beginners to learn.

MicroPython is much easier to program in. In addition, it is a great way to use Python code on a microcontroller, such as an ESP8266 or ESP32, to basically control all the electronic components you want from your computer running Jupyter Notebook in a browser. If you are new to MicroPython, check out our previous guides on how to use it with a microcontroller; one covers creating rogue access points, while the other talks about programming an MCU over Wi-Fi.

Our example scenario

To help you show how MicroPython, an MCU and Jupyter Notebook can be used together to control electronic components, we use an installation that is normally very difficult to do in Arduino but very simple in MicroPython.

On a board, we have our ESP8266 paired with a D1

Mini, which is connected to a relay switch. A relay is an electronic switch that is similar to the single-pole wall switches found in many of your rooms. When we send a power signal, it is turned on or off. There is a 9-volt battery connected, which will turn on the engine whenever we want it to.

What you need

Project parts:

These are the basics, but once you have your D1 Mini connected to the bread slice, with the relay connected, connect the relay to the GPIO pins and connect a 9V battery to the motor.

On your computer:

Step 1: Identify the correct serial port

Connect your ESP8266 to your computer and then run one of the commands below to see what serial address it is. If you disconnect the MCU to another USB port later, it may have a different serial address.

On a Linux computer:

~$ dmesg | grep tty

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.SOC
/dev/cu.wchusbserial14630
/dev/cu.MALS
/dev/cu.usbserial-14630

On a Mac:

~% ls /dev/cu.*

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.SOC
/dev/cu.wchusbserial14630
/dev/cu.MALS
/dev/cu.usbserial-14630

From my results from Linux and macOS it would be /dev/cu.wchusbserial14630. If you see two serial ports, always use the one with “wch” in it. To be sure if it is your ESP8266, you can disconnect it, restart the command, and then reconnect it to the same USB port and restart it.

To find the serial address in Windows, you need to open Device Manager and find the COM port under “Ports (COM & LPT).” We will not show any of the Windows steps below, so if you are using Windows and can not find out the process, look up the comments and we will try to steer you in the right direction.

Step 2: Download the latest MicroPython binary

If you already have MicroPython installed on your microcontroller, as if you were following one of our previous guides, you can skip down to step 4. Otherwise, you will need MicroPython on the MCU.

Download the latest firmware based on the card you are using. Visit the MicroPython download page, find your card and download the file. Below you will find quick links to the downloads for ESP8266 and ESP32. When selecting your board, select the .bin file for the latest stable release.

Step 3: Delete the board

Erase the card so that there are no problems when flashing MicroPython to it. Use the following command and replace my serial port with the serial on your ESP.

~$ esptool.py --port /dev/cu.wchusbserial14630 erase_flash

esptool.py v2.8
Serial port /dev/cu.wchusbserial14140
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 2c:f4:32:4b:07:83
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...

Step 4: Flash MicroPython

If you are now using an ESP8266 microcontroller, run the following to flash MicroPython to it. Replace the .bin file at the end with the MicroPython binary you downloaded.

~$ esptool.py --port /dev/cu.wchusbserial14630 --baud 460800 write_flash --flash_size=detect 0 /Users/kali/Downloads/esp8266-20191220-v1.12.bin

esptool.py v2.8
Serial port /dev/cu.wchusbserial14630
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 2c:f4:32:4b:07:83
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0040
Compressed 617880 bytes to 402086...
Wrote 617880 bytes (402086 compressed) at 0x00000000 in 9.6 seconds (effective 514.5 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

If you are using an ESP32, run the following instead. Replace the .bin file at the end with the MicroPython binary you downloaded.

~$ esptool.py --chip esp32 --port /dev/cu.wchusbserial14630 write_flash -z 0x1000 /Users/kali/Downloads/esp32-idf3-20191220-v1.12.bin

After flashing, confirm that it worked with the following command. If the outcome is similar, you’re fine. If you do not see anything, strike Get on a few more times to force it into action.

~$ screen /dev/cu.wchusbserial14630 115200

MicroPython v1.12 on 2019-12-20; ESP module with ESP8266
Type "help()" for more information.
>>>

Step 5: Install Jupyter Notebook

Now we need to have Jupyter Notebook on our computer, the web application we use to have direct control over motors, relays, sensors and other components. If you already have it installed, skip to step 6 to get the kernel. Otherwise, upgrade your pipe installation:

~$ python3 -m pip install --upgrade pip

Collecting pip
  Downloading pip-20.1.1-py2.py3-none-any.whl (1.5 MB)
     |████████████████████████████████| 1.5 MB 935 kB/s
Installing collected packages: pip
Successfully installed pip-20.1.1

Then install Jupyter Notebook with:

~$ python3 -m pip install jupyter

Collecting jupyter
  Using cached jupyter-1.0.0-py2.py3-none-any.whl (2.7 kB)
Collecting notebook
  Using cached notebook-6.0.3-py3-none-any.whl (9.7 MB)
Collecting qtconsole
  Downloading qtconsole-4.7.5-py2.py3-none-any.whl (118 kB)
     |████████████████████████████████| 118 kB 907 kB/s
Collecting ipykernel
  Downloading ipykernel-5.3.3-py3-none-any.whl (120 kB)
     |████████████████████████████████| 120 kB 11.7 MB/s
Collecting ipywidgets
  Using cached ipywidgets-7.5.1-py2.py3-none-any.whl (121 kB)
Collecting nbconvert
  Using cached nbconvert-5.6.1-py2.py3-none-any.whl (455 kB)
Collecting jupyter-console
  Using cached jupyter_console-6.1.0-py2.py3-none-any.whl (21 kB)
Requirement already satisfied: nbformat in /usr/lib/python3/dist-packages (from notebook->jupyter) (5.0.7)
Requirement already satisfied: tornado>=5.0 in /usr/lib/python3/dist-packages (from notebook->jupyter) (5.1.1)
Collecting Send2Trash
  Using cached Send2Trash-1.5.0-py3-none-any.whl (12 kB)
Requirement already satisfied: jupyter-core>=4.6.1 in /usr/lib/python3/dist-packages (from notebook->jupyter) (4.6.3)
Collecting jupyter-client>=5.3.4
  Downloading jupyter_client-6.1.6-py3-none-any.whl (108 kB)
     |████████████████████████████████| 108 kB 2.2 MB/s
Requirement already satisfied: traitlets>=4.2.1 in /usr/lib/python3/dist-packages (from notebook->jupyter) (4.3.3)
Collecting prometheus-client
  Downloading prometheus_client-0.8.0-py2.py3-none-any.whl (53 kB)
     |████████████████████████████████| 53 kB 1.9 MB/s
Requirement already satisfied: ipython-genutils in /usr/lib/python3/dist-packages (from notebook->jupyter) (0.2.0)
Collecting pyzmq>=17
  Downloading pyzmq-19.0.1-cp38-cp38-manylinux1_x86_64.whl (1.1 MB)
     |████████████████████████████████| 1.1 MB 9.9 MB/s
Requirement already satisfied: jinja2 in /usr/lib/python3/dist-packages (from notebook->jupyter) (2.10.1)
Collecting terminado>=0.8.1
  Using cached terminado-0.8.3-py2.py3-none-any.whl (33 kB)
Requirement already satisfied: pygments in /usr/lib/python3/dist-packages (from qtconsole->jupyter) (2.3.1)
Collecting qtpy
  Using cached QtPy-1.9.0-py2.py3-none-any.whl (54 kB)
Requirement already satisfied: ipython>=5.0.0 in /usr/lib/python3/dist-packages (from ipykernel->jupyter) (7.13.0)
Collecting widgetsnbextension~=3.5.0
  Using cached widgetsnbextension-3.5.1-py2.py3-none-any.whl (2.2 MB)
Collecting testpath
  Using cached testpath-0.4.4-py2.py3-none-any.whl (163 kB)
Requirement already satisfied: mistune<2,>=0.8.1 in /usr/lib/python3/dist-packages (from nbconvert->jupyter) (0.8.4)
Collecting pandocfilters>=1.4.1
  Using cached pandocfilters-1.4.2.tar.gz (14 kB)
Collecting bleach
  Downloading bleach-3.1.5-py2.py3-none-any.whl (151 kB)
     |████████████████████████████████| 151 kB 1.3 MB/s
Collecting entrypoints>=0.2.2
  Using cached entrypoints-0.3-py2.py3-none-any.whl (11 kB)
Collecting defusedxml
  Using cached defusedxml-0.6.0-py2.py3-none-any.whl (23 kB)
Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /usr/lib/python3/dist-packages (from jupyter-console->jupyter) (3.0.5)
Requirement already satisfied: python-dateutil>=2.1 in /usr/lib/python3/dist-packages (from jupyter-client>=5.3.4->notebook->jupyter) (2.8.1)
Collecting ptyprocess; os_name != "nt"
  Using cached ptyprocess-0.6.0-py2.py3-none-any.whl (39 kB)
Requirement already satisfied: pexpect in /usr/lib/python3/dist-packages (from ipython>=5.0.0->ipykernel->jupyter) (4.6.0)
Requirement already satisfied: webencodings in /usr/lib/python3/dist-packages (from bleach->nbconvert->jupyter) (0.5.1)
Requirement already satisfied: packaging in /usr/lib/python3/dist-packages (from bleach->nbconvert->jupyter) (20.3)
Requirement already satisfied: six>=1.9.0 in /usr/lib/python3/dist-packages (from bleach->nbconvert->jupyter) (1.14.0)
Building wheels for collected packages: pandocfilters
  Building wheel for pandocfilters (setup.py) ... done
  Created wheel for pandocfilters: filename=pandocfilters-1.4.2-py3-none-any.whl size=7856 sha256=d120576d72839490baf2013615ee01ad685c9e81b3a8f3068b4597432d8a6b36
  Stored in directory: /home/kali/.cache/pip/wheels/f6/08/65/e4636b703d0e870cd62692dafd6b47db27287fe80cea433722
Successfully built pandocfilters
Installing collected packages: pyzmq, jupyter-client, ipykernel, Send2Trash, testpath, pandocfilters, bleach, entrypoints, defusedxml, nbconvert, prometheus-client, ptyprocess, terminado, notebook, qtpy, qtconsole, widgetsnbextension, ipywidgets, jupyter-console, jupyter
Successfully installed Send2Trash-1.5.0 bleach-3.1.5 defusedxml-0.6.0 entrypoints-0.3 ipykernel-5.3.3 ipywidgets-7.5.1 jupyter-1.0.0 jupyter-client-6.1.6 jupyter-console-6.1.0 nbconvert-5.6.1 notebook-6.0.3 pandocfilters-1.4.2 prometheus-client-0.8.0 ptyprocess-0.6.0 pyzmq-19.0.1 qtconsole-4.7.5 qtpy-1.9.0 terminado-0.8.3 testpath-0.4.4 widgetsnbextension-3.5.1

And upgrade the Juypter client:

~$ pip3 install --upgrade jupyter_client

Requirement already up-to-date: jupyter_client in ./.local/lib/python3.8/site-packages (6.1.6)
Requirement already satisfied, skipping upgrade: jupyter-core>=4.6.0 in /usr/lib/python3/dist-packages (from jupyter_client) (4.6.3)
Requirement already satisfied, skipping upgrade: traitlets in /usr/lib/python3/dist-packages (from jupyter_client) (4.3.3)
Requirement already satisfied, skipping upgrade: python-dateutil>=2.1 in /usr/lib/python3/dist-packages (from jupyter_client) (2.8.1)
Requirement already satisfied, skipping upgrade: tornado>=4.1 in /usr/lib/python3/dist-packages (from jupyter_client) (5.1.1)
Requirement already satisfied, skipping upgrade: pyzmq>=13 in ./.local/lib/python3.8/site-packages (from jupyter_client) (19.0.1)

Step 6: Install Jupyter Notebook MicroPython Kernel

We need to install the MicroPython kernel for Jupyter Notebook now. We can download it from Jupyter MicroPython Kernel GitHub repo with:

~$ git clone https://github.com/goatchurchprime/jupyter_micropython_kernel.git

Cloning into 'jupyter_micropython_kernel'...
remote: Enumerating objects: 340, done.
remote: Total 340 (delta 0), reused 0 (delta 0), pack-reused 340
Receiving objects: 100% (340/340), 108.88 KiB | 1.25 MiB/s, done.
Resolving deltas: 100% (240/240), done.

Then install it on Python3 with (use sudo if something goes wrong):

~$ pip3 install -e jupyter_micropython_kernel

Obtaining file:///home/kali/jupyter_micropython_kernel
Requirement already satisfied: pyserial>=3.4 in /usr/lib/python3/dist-packages (from jupyter-micropython-kernel==0.1.3) (3.4)
Requirement already satisfied: websocket-client>=0.44 in /usr/lib/python3/dist-packages (from jupyter-micropython-kernel==0.1.3) (0.53.0)
Installing collected packages: jupyter-micropython-kernel
  Running setup.py develop for jupyter-micropython-kernel
Successfully installed jupyter-micropython-kernel

Now install the kernel in Jupyter:

~$ python3 -m jupyter_micropython_kernel.install

Installing IPython kernel spec of micropython
/home/kali/jupyter_micropython_kernel/jupyter_micropython_kernel/install.py:29: DeprecationWarning: replace is ignored. Installing a kernelspec always replaces an existing installation
  k.install_kernel_spec(td, 'Micropython', user=user, replace=True, prefix=prefix)
...into /home/kali/.local/share/jupyter/kernels/micropython

Jupytes should now be ready to work with MicroPython.

Step 7: Open Jupyter Notebook

To open the Jupyter Notebook web interface, use:

~$ jupyter notebook

If you installed Jupyter Notebook in your local, use this instead:

~$ ~/.local/bin/jupyter-notebook

Or add export PATH = $ PATH: ~ / .local / bin to your ~ / .bashrc file and try jupyter again.

You may need to enter your password before opening it. Afterwards, you should see an interface as below open in a browser.

Step 8: Open a MicroPython Jupyter Notebook

To create a MicroPython file, click “New” and select “MicroPython – USB” as the type of document to be created.

Now we should be in an empty Jupyter notebook. We can add cells to run with the plus (+) button and then run cells with the play button to see how our code runs. Before we can do that, however, we need to add a cell to connect.

Step 9: Check your engine from the web

In your Jupyter Notebook MicroPython file, use the following for the first block and make sure you use your serial port instead of mine. When it says “Done” when it starts connecting, you can continue.

%serialconnect to --port=/dev/cu.wchusbserial14630 --baud=115200

Now, in our second block, let’s create a little task to turn the engine on and off. First, make sure you are importing from the machine import pin and from the time import sleep. Then define the value of “engine” as 1 or TRUE to turn it on and 0 or Fake to turn it off. For “sleep” I use 0.2 seconds for how long it will run when activated. You can press “Run” to see it in action.

from machine import Pin
from time import sleep
motor = Pin(5, Pin.OUT)
motor.value(1)
sleep(0.2)
motor.value(0)
sleep(0.2)

You can also use .on() or .of() to control the pin:

motor.on()
sleep(0.2)
motor.off()
sleep(0.2)

If you want to loop things, we can start using different Python data structures that are really fun, short and simple, and that do not require any of what Arduino IDE does. So let’s see if we can just turn the engine on and off ten times in a row:

from time import sleep
for i in range(10):
    motor.on()
    sleep(0.5)
    motor.off()
    sleep(0.5)

If you want to stop your code, you can always press the stop icon, and if it just keeps going, you can press it to cancel it and be able to send in a new code

If you are a beginner or someone who already knows a little Python, MicroPython is probably the best way to get started with electronics from your laptop – spinning motors, glowing lasers and doing all sorts of other interesting things.

Want To Get Into The Gift Basket Business? Jump your career with hat hacking with our training package for premium ethical hacking 2020 from the new Null Byte store and get over 60 hours of training from professional ethical hacking.

Buy now (90% off)>

Cover image via Retia / Zero Replacement

Source link