2018-02-27 07:47:00 +00:00
|
|
|
# Hello MicroPython
|
2018-02-22 07:48:17 +00:00
|
|
|
|
2018-02-27 07:47:00 +00:00
|
|
|
## Getting started
|
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
This howto assumes Ubuntu 18.04+ is used on the computer and several tools have been installed:
|
2018-02-27 07:47:00 +00:00
|
|
|
|
|
|
|
```
|
2018-02-27 09:44:08 +00:00
|
|
|
sudo apt install picocom make python3-pip
|
2018-02-28 16:16:00 +00:00
|
|
|
sudo pip3 install esptool adafruit-ampy
|
2018-02-27 09:44:08 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Clone the Git repository and run makefiles:
|
|
|
|
|
|
|
|
```
|
2022-04-27 15:43:14 +00:00
|
|
|
git clone https://git.k-space.ee/k-space/micropython-skeleton
|
2018-02-27 07:47:00 +00:00
|
|
|
cd micropython-skeleton
|
|
|
|
make
|
|
|
|
```
|
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
In order to access the serial port you likely need to add yourself to the
|
|
|
|
`dialout` group after which you need to
|
|
|
|
log out from your desktop session and log in again
|
|
|
|
|
|
|
|
```
|
|
|
|
sudo gpasswd -a $USER dialout
|
|
|
|
```
|
|
|
|
|
|
|
|
**If you're using one of the computers prepared for the workshop all the steps
|
|
|
|
above have been performed already for you**
|
|
|
|
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
To open serial to the microcontroller:
|
|
|
|
|
|
|
|
```
|
|
|
|
make console
|
|
|
|
```
|
|
|
|
|
|
|
|
To upload `main.py`:
|
|
|
|
|
|
|
|
```
|
|
|
|
make upload
|
|
|
|
```
|
|
|
|
|
|
|
|
**Note that serial connection is used by both so you can't upload scripts while
|
|
|
|
serial console is open in another window**
|
|
|
|
|
|
|
|
|
2018-02-27 09:44:08 +00:00
|
|
|
## Blinking LED-s
|
|
|
|
|
2018-02-27 07:47:00 +00:00
|
|
|
First let's some LED-s blinking.
|
|
|
|
Press Ctrl-E for paste mode, otherwise spaces get mangled.
|
|
|
|
Press Ctrl-Shift-V for pasting.
|
|
|
|
Press Ctrl-D to exit paste mode and evaluate the code.
|
|
|
|
|
|
|
|
```
|
|
|
|
from time import sleep
|
|
|
|
from machine import Pin
|
|
|
|
|
|
|
|
# RGB LED is connected to programmable pins 12, 13, 15
|
|
|
|
led_red = Pin(12, Pin.OUT)
|
|
|
|
led_green = Pin(13, Pin.OUT)
|
|
|
|
led_blue = Pin(15, Pin.OUT)
|
|
|
|
|
|
|
|
# The values are inverted because 3.3v is common pin
|
|
|
|
led_red.value(1)
|
|
|
|
led_green.value(1)
|
|
|
|
led_blue.value(1)
|
|
|
|
|
|
|
|
for j in range(0, 5):
|
|
|
|
led_red.value(0)
|
|
|
|
sleep(1)
|
|
|
|
led_red.value(1)
|
|
|
|
led_green.value(0)
|
|
|
|
sleep(1)
|
|
|
|
led_green.value(1)
|
|
|
|
led_blue.value(0)
|
|
|
|
sleep(1)
|
|
|
|
led_blue.value(1)
|
|
|
|
```
|
|
|
|
|
|
|
|
Tasks:
|
|
|
|
|
|
|
|
1. Modify the code so yellow, cyan, magenda and white would be included.
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-02-27 09:44:08 +00:00
|
|
|
## Button presses
|
2018-02-27 07:47:00 +00:00
|
|
|
|
|
|
|
On the board there is button labelled "Boot", this is hooked up to pin 2.
|
2022-04-26 19:17:21 +00:00
|
|
|
By default there is a resistor which pulls the voltage on the pin to 3.3v,
|
|
|
|
but when button is pressed the pin is shorted to ground so the voltage goes to 0v.
|
2018-02-27 07:47:00 +00:00
|
|
|
Most modern solutions use interrupts to detect voltage change on the pin:
|
|
|
|
|
|
|
|
```
|
|
|
|
from machine import Pin
|
|
|
|
from time import sleep
|
|
|
|
|
|
|
|
Pin(12, Pin.OUT).value(1)
|
|
|
|
Pin(13, Pin.OUT).value(1)
|
|
|
|
led_blue = Pin(15, Pin.OUT)
|
|
|
|
button = Pin(0)
|
|
|
|
|
|
|
|
turned_off = False
|
|
|
|
|
|
|
|
def callback(p):
|
|
|
|
global turned_off
|
|
|
|
turned_off = not turned_off
|
|
|
|
led_blue.value(turned_off)
|
|
|
|
|
|
|
|
# Execute function 'callback' when voltage goes from 3.3v to 0v on pin 0
|
|
|
|
button.irq(trigger=Pin.IRQ_FALLING, handler=callback)
|
|
|
|
```
|
|
|
|
|
|
|
|
Tasks:
|
|
|
|
|
|
|
|
1. Modify the code so pressing button shuffles between off, red, green, blue, yellow, cyan, magenta and white
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-02-27 09:44:08 +00:00
|
|
|
## Driving OLED screens
|
2018-02-27 07:47:00 +00:00
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
Let's get some pixels on the screen!
|
2018-02-27 07:47:00 +00:00
|
|
|
There's 128x64 pixels monochrome OLED screen connected via I2C bus on the pins 4 and 5.
|
|
|
|
|
|
|
|
```
|
2022-04-26 19:17:21 +00:00
|
|
|
from machine import Pin, SoftI2C
|
2018-02-27 07:47:00 +00:00
|
|
|
from ssd1306 import SSD1306_I2C
|
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
i2c = SoftI2C(Pin(4),Pin(5), freq=400000) # Bitbanged I2C bus
|
2018-02-27 07:47:00 +00:00
|
|
|
oled = SSD1306_I2C(128, 64, i2c)
|
|
|
|
oled.invert(0) # White text on black background
|
|
|
|
oled.contrast(255) # Maximum contrast
|
|
|
|
|
|
|
|
oled.fill(0)
|
2022-04-26 19:17:21 +00:00
|
|
|
name = "Hello MicroPython!"
|
|
|
|
oled.text(" %s" % name, 10, 10)
|
2018-02-27 07:47:00 +00:00
|
|
|
oled.show()
|
|
|
|
```
|
|
|
|
|
|
|
|
Tasks:
|
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
1. What IP address was assigned to the board by the wireless network?
|
|
|
|
Hint: Check out `wlan.ifconfig()`
|
|
|
|
2. Show button press counter on the screen
|
|
|
|
3. Show on the screen which color is the RGB LED shining
|
|
|
|
|
|
|
|
## Clock synchronization
|
|
|
|
|
|
|
|
Most boards to do not have battery backed time keep track of the time.
|
|
|
|
Once you have the microcontroller connected to the Internet you can query
|
|
|
|
time from one of the NTP servers.
|
|
|
|
|
|
|
|
The Internet connectivity is established using `boot.py` script that is
|
|
|
|
already included in this repo. It by default connects to `k-space.ee legacy`
|
|
|
|
wireless network.
|
|
|
|
|
2018-02-27 07:47:00 +00:00
|
|
|
|
|
|
|
## Temperature & humidity
|
|
|
|
|
|
|
|
Next let's hook up DHT11 sensor to the board and measure the temperature.
|
|
|
|
|
2018-02-27 09:44:08 +00:00
|
|
|
* Sensor's Vcc is connected to 3.3v on the board
|
|
|
|
* Ground pins (GND) are connected
|
|
|
|
* Sensor's data pin is connected to board pin 4
|
|
|
|
|
|
|
|
Some code to get you going:
|
|
|
|
|
2018-02-27 07:47:00 +00:00
|
|
|
```
|
|
|
|
from time import sleep
|
|
|
|
from machine import Pin
|
|
|
|
from dht import DHT11
|
|
|
|
|
|
|
|
d = DHT11(Pin(4))
|
|
|
|
|
|
|
|
try:
|
2018-02-27 09:44:08 +00:00
|
|
|
d.measure()
|
2018-02-27 07:47:00 +00:00
|
|
|
except OSError:
|
2018-02-27 09:44:08 +00:00
|
|
|
print("Sensor not connected")
|
2018-02-27 07:47:00 +00:00
|
|
|
else:
|
2018-02-27 09:44:08 +00:00
|
|
|
print("Temperature %sC" % d.temperature())
|
|
|
|
print("Humidity %s%%" % d.humidity())
|
2018-02-27 07:47:00 +00:00
|
|
|
finally:
|
2018-02-27 09:44:08 +00:00
|
|
|
sleep(1)
|
2018-02-27 07:47:00 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Tasks:
|
|
|
|
|
|
|
|
1. Get temperature and humidity displayed on the screen
|
|
|
|
|
2018-02-27 09:44:08 +00:00
|
|
|
|
|
|
|
## Distance with sonar
|
|
|
|
|
|
|
|
In this case HC-SR04 is hooked up:
|
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
* Trigger is connected to pin 12
|
|
|
|
* Echo is connected to pin 14
|
2018-02-27 09:44:08 +00:00
|
|
|
* GND pins are connected
|
|
|
|
* Sonar's Vcc is connected to 3.3V on the board
|
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
This is exactly the case with the sumorobots. Feel free to try it out!
|
|
|
|
|
2018-02-27 09:44:08 +00:00
|
|
|
Code to measure distance:
|
|
|
|
|
|
|
|
```
|
|
|
|
from time import sleep_us, sleep_ms
|
|
|
|
from machine import Pin, time_pulse_us
|
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
trigger = Pin(12, Pin.OUT)
|
|
|
|
echo = Pin(14, Pin.IN)
|
2018-02-27 09:44:08 +00:00
|
|
|
|
|
|
|
def measure():
|
|
|
|
trigger.value(0)
|
|
|
|
sleep_us(5)
|
|
|
|
trigger.value(1)
|
|
|
|
sleep_us(10)
|
|
|
|
trigger.value(0)
|
|
|
|
|
|
|
|
duration = time_pulse_us(echo, 1, 29000)
|
|
|
|
distance = (duration / 2.0) / 29
|
|
|
|
return distance
|
|
|
|
|
|
|
|
while True:
|
|
|
|
print("Distance is: %s cm" % measure())
|
|
|
|
sleep_ms(200)
|
|
|
|
```
|
|
|
|
|
|
|
|
Tasks:
|
|
|
|
|
|
|
|
1. Get distance shown on OLED display
|
2022-04-26 19:17:21 +00:00
|
|
|
2. How were the constants for converting `duration` to `distance` figured out?
|
2018-02-27 07:47:00 +00:00
|
|
|
|
|
|
|
|
2018-02-27 09:44:08 +00:00
|
|
|
## Summary
|
2018-02-27 07:47:00 +00:00
|
|
|
|
2022-04-26 19:17:21 +00:00
|
|
|
ESP32 microcontroller with MicroPython is a really cheap way to get started
|
|
|
|
with the IoT stuff. See more detailed information
|
|
|
|
[here](https://lauri.xn--vsandi-pxa.com/2017/06/espressif.html).
|
2018-02-27 07:47:00 +00:00
|
|
|
|
|
|
|
Other interesting projects with ESP8266 and ESP32 microcontrollers:
|
|
|
|
|
|
|
|
* [Nixie clock](https://github.com/k-space-ee/nixiesp12) with ESP8266
|
2018-02-27 09:44:08 +00:00
|
|
|
* [Sumorobot](http://robot.itcollege.ee/sumorobot/2017/08/25/sumesp-prototype/) with ESP32
|
|
|
|
|
2018-02-28 16:16:00 +00:00
|
|
|
Come and visit [k-space.ee](https://k-space.ee) on Wednesdays 18:00 for more of MicroPython
|