This commit is contained in:
Lauri Võsandi 2022-04-26 22:17:21 +03:00
parent 7ef2d2ecfb
commit 23074cbf43
6 changed files with 116 additions and 90 deletions

1
.gitignore vendored
View File

@ -58,3 +58,4 @@ docs/_build/
# PyBuilder
target/
bin

View File

@ -1,15 +1,20 @@
# Makefile for the board
NAME=esp32-20220117-v1.18.bin
NAME=esp32-20180222-v1.9.3-347-g6e675c1b.bin
all: flash upload console
all: flash console
bin/${NAME}:
mkdir -p bin
wget https://micropython.org/resources/firmware/${NAME} -O bin/${NAME}
flash:
esptool.py -p /dev/ttyUSB0 -b 921600 erase_flash
flash: bin/${NAME}
esptool.py -p /dev/ttyUSB0 -b 921600 write_flash --flash_mode dio 0x1000 bin/${NAME}
sleep 5
ampy -p /dev/ttyUSB0 put ssd1306.py
upload:
ampy -p /dev/ttyUSB0 put boot.py
ampy -p /dev/ttyUSB0 put main.py
console:
echo "Ctrl-A + Ctrl-Q to close Picocom"
picocom -b115200 /dev/ttyUSB0

132
README.md
View File

@ -2,7 +2,7 @@
## Getting started
This howto assumes Ubuntu 16.04 is used on the computer and several tools have been installed:
This howto assumes Ubuntu 18.04+ is used on the computer and several tools have been installed:
```
sudo apt install picocom make python3-pip
@ -17,6 +17,36 @@ cd micropython-skeleton
make
```
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**
## Blinking LED-s
First let's some LED-s blinking.
@ -59,7 +89,8 @@ Tasks:
## Button presses
On the board there is button labelled "Boot", this is hooked up to pin 2.
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.
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.
Most modern solutions use interrupts to detect voltage change on the pin:
```
@ -90,27 +121,41 @@ Tasks:
## Driving OLED screens
Let's get some pixels on the screen.
Let's get some pixels on the screen!
There's 128x64 pixels monochrome OLED screen connected via I2C bus on the pins 4 and 5.
```
from machine import Pin, I2C
from machine import Pin, SoftI2C
from ssd1306 import SSD1306_I2C
i2c = I2C(-1, Pin(4),Pin(5), freq=400000) # Bitbanged I2C bus
i2c = SoftI2C(Pin(4),Pin(5), freq=400000) # Bitbanged I2C bus
oled = SSD1306_I2C(128, 64, i2c)
oled.invert(0) # White text on black background
oled.contrast(255) # Maximum contrast
oled.fill(0)
name = "Lauri"
oled.text("Hi %s" % name, 10, 10)
name = "Hello MicroPython!"
oled.text(" %s" % name, 10, 10)
oled.show()
```
Tasks:
1. When button is pressed show a corresponding message on the screen - lights turned on/off or the name of the color shown
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.
## Temperature & humidity
@ -122,7 +167,6 @@ Next let's hook up DHT11 sensor to the board and measure the temperature.
Some code to get you going:
```
from time import sleep
from machine import Pin
@ -150,19 +194,21 @@ Tasks:
In this case HC-SR04 is hooked up:
* Trigger is connected to pin 25
* Echo is connected to pin 26
* Trigger is connected to pin 12
* Echo is connected to pin 14
* GND pins are connected
* Sonar's Vcc is connected to 3.3V on the board
This is exactly the case with the sumorobots. Feel free to try it out!
Code to measure distance:
```
from time import sleep_us, sleep_ms
from machine import Pin, time_pulse_us
trigger = Pin(25, Pin.OUT)
echo = Pin(26, Pin.IN)
trigger = Pin(12, Pin.OUT)
echo = Pin(14, Pin.IN)
def measure():
trigger.value(0)
@ -183,66 +229,14 @@ while True:
Tasks:
1. Get distance shown on OLED display
## Connecting to internet
Exit the serial console by pressing Ctrl-A and then Ctrl-Q.
Upload module to handle WebSockets and return to Python prompt:
```
ampy -p /dev/ttyUSB0 put uwebsockets.py
ampy -p /dev/ttyUSB0 put boot.py # Script that connects to itcollege network
make console
```
Press EN button on the board to reset the board.
Paste following:
```
import sys
import uwebsockets
from machine import Pin
Pin(12, Pin.OUT).value(1)
Pin(13, Pin.OUT).value(1)
led_blue = Pin(15, Pin.OUT)
channel = "living-room-of-lauri"
uri = "ws://iot.koodur.com:80/ws/" + channel
print("Connecting to:", uri)
conn = uwebsockets.connect(uri)
conn.send("alive")
turned_off = False
while True:
print("Reading message...")
fin, opcode, data = conn.read_frame()
if data == "toggle":
turned_off = not turned_off
led_blue.value(turned_off)
else:
print("Got unknown command:", data)
```
Using web browser navigate [here](http://iot.koodur.com/demo2.html#living-room-of-lauri)
1. Move to another channel to prevent flipping lights in my living room
2. Improve the code so the "Boot" button and button in the web interface both work simultaneously
3. Download the HTML file and add buttons to select different colors, adjust Python code to handle new commands
4. Add code to send sensor readings to the webserver
2. How were the constants for converting `duration` to `distance` figured out?
## Summary
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).
Some more tricks to try:
* Add dimming of LED-s with PWM
* Add [colorpicker](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color)
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).
Other interesting projects with ESP8266 and ESP32 microcontrollers:

10
boot.py
View File

@ -1,5 +1,13 @@
# Give time to cancel this boot script
import time
print("Press Ctrl-C to stop boot script...")
time.sleep(2)
# Connect to wireless network as client
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("k-space.ee guest")
wlan.connect("k-space.ee legacy")
while not wlan.isconnected():
pass

48
main.py
View File

@ -1,18 +1,36 @@
from time import sleep_ms
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import ntptime
ntptime.settime()
i2c = I2C(-1, Pin(4),Pin(5),freq=400000) # Bitbanged I2C bus
assert 60 in i2c.scan(), "No OLED display detected!"
oled = SSD1306_I2C(128, 64, i2c)
buf = "wubba lubba dub dub "
oled.invert(0) # White text on black background
oled.contrast(255) # Maximum contrast
j = 0
from flipdisc import DisplayBuffer, Font
from time import sleep, localtime
from machine import UART
TIMEZONE = 3
weekdays = "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
port = UART(2, baudrate=4800, tx=17, rx=16)
disp = DisplayBuffer(0x06, 128, 16)
while True:
oled.fill(0)
oled.text(buf[j%len(buf):]+buf, 10, 10)
oled.show()
sleep_ms(20)
j += 1
for j in range(0,10):
year, month, day, hour, minute, second, dow, _ = localtime()
hour = (hour + TIMEZONE) % 24
i = " %02d:%02d:%02d" % (hour, minute, second)
j = " %04d-%02d-%02d %s" % (year, month, day, weekdays[dow])
disp.put_text(i.encode("ascii"),0, 0, Font.F6)
disp.put_text(j.encode("ascii"),0, 15, Font.F6)
buf = disp.finalize_buffer()
port.write(buf)
sleep(1)
for j in range(0, 2):
disp.put_text(b"MicroPython",0, 0, Font.F13_F)
buf = disp.finalize_buffer()
port.write(buf)
sleep(2)
disp.put_text(b"... is awesome",0, 0, Font.F13_F)
buf = disp.finalize_buffer()
port.write(buf)
sleep(2)
port.close()