Some updates

master
Valentin Ochs 2019-11-26 00:18:10 +01:00
parent 010215055c
commit b1a6f38203
1 changed files with 94 additions and 19 deletions

113
README.md
View File

@ -4,11 +4,22 @@ MicroPython Workshop
Getting started
---------------
### Operating systems, drivers...
You might need drivers for the CP210x USB-to-serial converter, which you can
get from [the Silicon Labs site][silabs].
On Windows, the device should show up as some COM port (e.g. COM3), on Linux as
e.g. /dev/ttyUSB0, and on OSX as /dev/tty.SLAB_USBtoUART (not as
/dev/tty.usbserial!)
[silabs]: https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
### Installing MicroPython
Get a recent build of Pycopy, a fork of MicroPython that we will be using for this workshop. A build of the current state as of 2019-11-24 is [here](firmware.bin).
Afterwards, get `esptool` and use it to flash your board:
Afterwards, get `esptool` and use it to flash your board, using the correct port:
``` sh
pip install esptool
@ -23,6 +34,9 @@ You can now connect to your board's REPL with e.g. `screen` or `putty`:
screen /dev/ttyUSB0 115200
```
In Putty, select "Serial" as connection type and use your COM port as port and
115200 as speed.
You'll get a command prompt and be able to execute the first commands
``` python
@ -30,7 +44,8 @@ help()
print("Hello, world")
```
A reference of all the default libraries can be found on [readthedocs.io](https://pycopy.readthedocs.io/en/latest/)
A reference of all the default libraries can be found on
[readthedocs.io](https://pycopy.readthedocs.io/en/latest/)
### File upload using `ampy`
@ -53,7 +68,7 @@ ampy get boot.py boot.py
# Create some example file
echo "print('hello, world')" > hello.py
# Run a local file
# Run a local file, without uploading or saving it
ampy run hello.py
# Save it to the board
@ -63,7 +78,9 @@ ampy put hello.py
ampy rm hello.py
```
The contents of `boot.py` are run each time the controller resets. It may contain instructions for setting up your network connection, local time, peripherals, etc.
The contents of `boot.py` are run each time the controller resets. It may
contain instructions for setting up your network connection, local time,
peripherals, etc. Make sure not to put an infinite loop in your `boot.py`.
Hello, LED
----------
@ -74,27 +91,42 @@ You can control the builtin LED, which is on pin 5:
from machine import Pin
led = Pin(5, Pin.OUT)
# The values are inverted, so this turns
# the LED on:
# The LED is connected between GPIO 5 and 3.3 V, so
# to allow current to flow and turn the LED on, you
# need a lower voltage on your pin:
led.value(0)
# This is (in this case somewhat confusingly) equivalent to
led.off()
# and this turns it off:
# or
led(0)
# These will all turn it off:
led.value(1)
led(1)
led.on()
# You can also use numbers or booleans:
# You can also use booleans:
led.value(False)
led.value(1)
led.value(True)
```
### Brightness control with PWM
To control the brightness, we will be using [Pulse-Width Modulation][pwm],
which quickly toggles the LED between on and off at some frequency, while
varying the time it is on:
``` python
from machine import PWM
pwm = PWM(led)
# Read the frequency
pwm.freq()
# Set it
pwm.freq(20000)
pwm.freq(1000)
# Read and set the duty cycle
pwm.duty()
pwm.duty(1023)
@ -102,15 +134,31 @@ pwm.duty(512)
pwm.duty(0)
```
Contrary to what some people with previous embedded programming experience
might expect, the frequency here is not the frequency of the counter, but
how often the LED toggles per second.
The maximum duty cycle is normally 1023 (which applies 3.3 volts for 1023 out
of 1024 cycles). For high frequencies this might change.
Frequencies as low as 1 Hz are possible - you can not use floating point
numbers as your PWM frequency.
[pwm]: https://en.wikipedia.org/wiki/Pulse-width_modulation
### Reserved pins
- UART: Pins 1 and 3 are TX/RX
Some of the GPIOs are reserved for certain functions. Most of their numbers are
not visible on the TTGO-T8 board:
- UART: Pins 1 and 3 are TX/RX - visible as TXD and RXD
- Flash: 6, 7, 8, 11, 16, 17. Messing with these will probably crash your program.
- 34-39 are input only and do not have pullups.
- 34-39 are input only and do not have pullups. Only 34 and 35 are available
on the board at all.
All other pins can be used for PWM.
All other pins can be freely used for any kind of digital input or output.
Pins 2, 4, 12, 13, 14, 15 are connected the the micro-SD slot.
Pins 2, 4, 12, 13, 14, 15 are connected the the micro-SD slot and can not be
used while the SD card is being used.
Digital and analog input
------------------------
@ -127,7 +175,16 @@ pin = Pin(4, Pin.IN, Pin.PULL_UP)
pin = Pin(4, Pin.IN, Pin.PULL_DOWN)
```
For analog input, use `machine.ADC`. By default, the ADC has an input range of 1.00 V, but this can be changed to up to 3.6 V. Available pins are 32 through 39.
When connecting a button between a pin and the supply voltage (3V3 pins), use a
pull-down - then the normal state will read as 0, and switch to 1 when the
button is pressed.
You can also connect the button between ground (GND) and a pin and use a pull-up,
now the pin will normally read as 1 and switch to 0 when pressed.
For analog input, use `machine.ADC`. By default, the ADC has an input range of
1.0 V, but this can be changed to up to 3.6 V using `ADC.atten`. Available pins
are 32 through 35.
``` python
from machine import Pin, ADC
@ -145,7 +202,10 @@ while True:
Timers
------
MicroPython on the ESP32 has virtual timers and 4 hardware timers. You can use a lot more virtual timers, but they are more prone to jitter. In either case, you can not allocate memory in a timer, as they are executed from an interrupt context.
MicroPython on the ESP32 has virtual timers and 4 hardware timers. You can use
a lot more virtual timers, but they are more prone to jitter. In either case,
you can not allocate memory in a timer, as they are executed from an interrupt
context.
Timers execute a callback, which takes the timer as an argument
@ -157,15 +217,21 @@ import utime
# IDs >= 0 are hardware timers.
timer = Timer(-1)
# Create variables used by the interrupt
data = [0] * 32
index = 0
# Use the normal LED as output
led = Pin(5, Pin.OUT)
def callback(timer):
global data, index
# Store the time since startup (in ms)
data[index] = utime.ticks_ms()
# Next write will be at the next index
# Restarts at index 0 when the array is full!
index = (index + 1) % 32
# Toggle the LED
led(not led())
# Run the callback once, after 100 ms
@ -174,8 +240,13 @@ timer.init(mode = Timer.ONE_SHOT, period = 100, callback = callback)
# Run the callback every second
timer.init(period = 1000, callback = callback)
# After some time
# After a few seconds
# Most of the values will have the same last three digits
# You might see something like
# [ 456, 5662, 6662, 7662, 8662, ... ]
print(data)
# Stop the timer
timer.deinit()
```
@ -205,7 +276,9 @@ print(open("data.txt").read())
Sleep modes and power consumption
---------------------------------
When transmitting data to a WLAN, power consumption will be 160 - 260 mA (so use `WLAN.active(false)` when you don't need it). Even with a deactivated modem, the power consumption can still be up to 20 mA when the CPU is running.
When transmitting data to a WLAN, power consumption will be 160 - 260 mA (so
use `WLAN.active(false)` when you don't need it). Even with a deactivated
modem, the power consumption can still be up to 20 mA when the CPU is running.
### Idle
@ -342,8 +415,10 @@ HTTP
### Requests
``` python
import upip
upip.install('urequests')
import urequests
urequests.get('https://hotspot.vodafone.de/api/v4/login?loginProfile=6')
urequests.get('https://imaginaerraum.de')
```
### Server