diff --git a/docs/esp8266/tutorial/adc.rst b/docs/esp8266/tutorial/adc.rst new file mode 100644 index 0000000000..fa6fdaba73 --- /dev/null +++ b/docs/esp8266/tutorial/adc.rst @@ -0,0 +1,19 @@ +Analog to Digital Conversion +============================ + +The ESP8266 has a single pin (separate to the GPIO pins) which can be used to +read analog voltages and convert them to a digital value. You can construct +such an ADC pin object using:: + + >>> import machine + >>> adc = machine.ADC(0) + +Then read its value with:: + + >>> adc.read() + 58 + +The values returned from the ``read()`` function are between 0 (for 0.0 volts) +and 1024 (for 1.0 volts). Please note that this input can only tolerate a +maximum of 1.0 volts and you must use a voltage divider circuit to measure +larger voltages. diff --git a/docs/esp8266/tutorial/filesystem.rst b/docs/esp8266/tutorial/filesystem.rst new file mode 100644 index 0000000000..9033a8576f --- /dev/null +++ b/docs/esp8266/tutorial/filesystem.rst @@ -0,0 +1,70 @@ +The internal filesystem +======================= + +If your devices has 1Mbyte or more of storage then it will be set up (upon first +boot) to contain a filesystem. This filesystem uses the FAT format and is +stored in the flash after the MicroPython firmware. + +Creating and reading files +-------------------------- + +MicroPython on the ESP8266 supports the standard way of accessing files in +Python, using the built-in ``open()`` function. + +To create a file try:: + + >>> f = open('data.txt', 'w') + >>> f.write('some data') + 9 + >>> f.close() + +The "9" is the number of bytes that were written with the ``write()`` method. +Then you can read back the contents of this new file using:: + + >>> f = open('data.txt') + >>> f.read() + 'some data' + >>> f.close() + +Note that the default mode when opening a file is to open it in read-only mode, +and as a text file. Specify ``'wb'`` as the second argument to ``open()`` to +open for writing in binary mode, and ``'rb'`` to open for reading in binary +mode. + +Listing file and more +--------------------- + +The os module can be used for further control over the filesystem. First +import the module:: + + >>> import os + +Then try listing the contents of the filesystem:: + + >>> os.listdir() + ['boot.py', 'port_config.py', 'data.txt'] + +You can make directories:: + + >>> os.mkdir('dir') + +And remove entries:: + + >>> os.remove('data.txt') + +Start up scripts +---------------- + +There are two files that are treated specially by the ESP8266 when it starts up: +boot.py and main.py. The boot.py script is executed first (if it exists) and +then once it completes the main.py script is executed. You can create these +files yourself and populate them with the code that you want to run when the +device starts up. + +Accessing the filesystem via WebREPL +------------------------------------ + +You can access the filesystem over WebREPL using the provided command-line +tool. This tool is found at ``__ +and is called webrepl_cli.py. Please refer to that program for information +on how to use it. diff --git a/docs/esp8266/tutorial/index.rst b/docs/esp8266/tutorial/index.rst index 7a68e9dc47..1a00afd853 100644 --- a/docs/esp8266/tutorial/index.rst +++ b/docs/esp8266/tutorial/index.rst @@ -3,4 +3,30 @@ MicroPython tutorial for ESP8266 ================================ -TBD +This tutorial is intended to get you started using MicroPython on the ESP8266 +system-on-a-chip. If it is your first time it is recommended to follow the +tutorial through in the order below. Otherwise the sections are mostly self +contained, so feel free to skip to those that interest you. + +The tutorial does not assume that you know Python, but it also does not attempt +to explain any of the details of the Python language. Instead it provides you +with commands that are ready to run, and hopes that you will gain a bit of +Python knowledge along the way. To learn more about Python itself please refer +to ``__. + +.. toctree:: + :maxdepth: 1 + :numbered: + + intro.rst + repl.rst + filesystem.rst + network_basics.rst + network_tcp.rst + pins.rst + pwm.rst + adc.rst + powerctrl.rst + onewire.rst + neopixel.rst + nextsteps.rst diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst new file mode 100644 index 0000000000..2db2ba5bd5 --- /dev/null +++ b/docs/esp8266/tutorial/intro.rst @@ -0,0 +1,95 @@ +Introduction to MicroPython on the ESP8266 +========================================== + +Using MicroPython is a great way to get the most of your ESP8266 board. And +vice versa, the ESP8266 chip is a great platform for using MicroPython. This +tutorial will guide you through setting up MicroPython, getting a prompt, using +WebREPL, connecting to the network and communicating with the Internet, using +the hardware peripherals, and controlling some external components. + +Let's get started! + +Requirements +------------ + +The first thing you need is a board with an ESP8266 chip. The MicroPython +software supports the ESP8266 chip itself and any board should work. The main +characteristic of a board is how much flash it has, how the GPIO pins are +connected to the outside world, and whether it includes a built-in USB-serial +convertor to make the UART available to your PC. + +The minimum requirement for flash size is 512k. A board with this amount of +flash will not have room for a filesystem, but otherwise is fully functional. +If your board has 1Mbyte or more of flash then it will support a filesystem. + +Names of pins will be given in this tutorial using the chip names (eg GPIO0) +and it should be straightforward to find which pin this corresponds to on your +particular board. + +Powering the board +------------------ + +If your board has a USB connector on it then most likely it is powered through +this when connected to your PC. Otherwise you will need to power it directly. +Please refer to the documentation for your board for further details. + +Deploying the firmware +---------------------- + +The very first thing you need to do is put the MicroPython firmware (compiled +code) on your ESP8266 device. There are two main steps to do this: first you +need to put your device in boot-loader mode, and second you need to copy across +the firmware. The exact procedure for these steps is highly dependent on the +particular board and you will need to refer to its documentation for details. + +If you have a board that has a USB connector, a USB-serial convertor, and has +the DTR and RTS pins wired in a special way then deploying the firmware should +be easy as all steps can be done automatically. Boards that have such features +include the Adafruit Feather HUZZAH and NodeMCU boards. + +For best results it is recommended to first erase the entire flash of your +device before putting on new MicroPython firmware. + +Currently we only support esptool.py to copy across the firmware. You can find +this tool here: ``__ . Any other +flashing program should work, so feel free to try them out, or refer to the +documentation for your board to see its recommendations. + +Using esptool.py you can erase the flash with the command:: + + esptool.py --port /dev/ttyUSB0 erase_flash + +And then deploy the new firmware using:: + + esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m 0 mp-esp8266-firmware.bin + +You might need to change the "port" setting to something else relevant for your +PC. You may also need to reduce the baudrate if you get errors when flashing +(eg down to 115200). + +If you have a NodeMCU board, you may need to use the following command to deploy +the firmware (note the "-fm dio" option):: + + esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m -fm dio 0 mp-esp8266-firmware.bin + +If the above commands run without error then MicroPython should be installed on +your board! + +Serial prompt +------------- + +Once you have the firmware on the device you can access the REPL (Python prompt) +over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial +convertor, depending on your board. The baudrate is 115200. The next part of +the tutorial will discuss the prompt in more detail. + +WiFi +---- + +After a fresh install and boot the device configures itself as a WiFi access +point (AP) that you can connect to. The ESSID is of the form MicroPython-xxxxxx +where the x's are replaced with part of the MAC address of your device (so will +be the same everytime, and most likely different for all ESP8266 chips). The +password for the WiFi is micropythoN (note the upper-case N). Its IP address +will be 192.168.4.1 once you connect to its network. WiFi configuration will +be discussed in more detail later in the tutorial. diff --git a/docs/esp8266/tutorial/neopixel.rst b/docs/esp8266/tutorial/neopixel.rst new file mode 100644 index 0000000000..245aed6d46 --- /dev/null +++ b/docs/esp8266/tutorial/neopixel.rst @@ -0,0 +1,70 @@ +Controlling NeoPixels +===================== + +NeoPixels, also known as WS2812 LEDs, are full-colour LEDs that are connected in +serial, are individually addressable, and can have their red, green and blue +components set between 0 and 255. They require precise timing to control them +and there is a special neopixel module to do just this. + +To create a NeoPixel object do the following:: + + >>> import machine, neopixel + >>> np = neopixel.NeoPixel(machine.Pin(4), 8) + +This configures a NeoPixel strip on GPIO4 with 8 pixels. You can adjust the +"4" (pin number) and the "8" (number of pixel) to suit your set up. + +To set the colour of pixels use:: + + >>> np[0] = (255, 0, 0) # set to red, full brightness + >>> np[1] = (0, 128, 0) # set to green, half brightness + >>> np[2] = (0, 0, 64) # set to blue, quarter brightness + +Then use the ``write()`` method to output the colours to the LEDs:: + + >>> np.write() + +The following demo function makes a fancy show on the LEDs:: + + import time + + def demo(np): + n = np.n + + # cycle + for i in range(4 * n): + for j in range(n): + np[j] = (0, 0, 0) + np[i % n] = (255, 255, 255) + np.write() + time.sleep_ms(25) + + # bounce + for i in range(4 * n): + for j in range(n): + np[j] = (0, 0, 128) + if (i // n) % 2 == 0: + np[i % n] = (0, 0, 0) + else: + np[n - 1 - (i % n)] = (0, 0, 0) + np.write() + time.sleep_ms(60) + + # fade in/out + for i in range(0, 4 * 256, 8): + for j in range(n): + if (i // 256) % 2 == 0: + val = i & 0xff + else: + val = 255 - (i & 0xff) + np[j] = (val, 0, 0) + np.write() + + # clear + for i in range(n): + np[i] = (0, 0, 0) + np.write() + +Execute it using:: + + >>> demo(np) diff --git a/docs/esp8266/tutorial/network_basics.rst b/docs/esp8266/tutorial/network_basics.rst new file mode 100644 index 0000000000..02a7054858 --- /dev/null +++ b/docs/esp8266/tutorial/network_basics.rst @@ -0,0 +1,81 @@ +Network basics +============== + +The network module is used to configure the WiFi connection. There are two WiFi +interfaces, one for the station (when the ESP8266 connects to a router) and one +for the access point (for other devices to connect to the ESP8266). Create +instances of these objects using:: + + >>> import network + >>> sta_if = network.WLAN(network.STA_IF) + >>> ap_if = network.WLAN(network.AP_IF) + +You can check if the interfaces are active by:: + + >>> sta_if.active() + False + >>> ap_if.active() + True + +You can also check the network settings of the interface by:: + + >>> ap.ifconfig() + ('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8') + +The returned values are: IP address, netmask, gateway, DNS. + +Configuration of the WiFi +------------------------- + +Upon a fresh install the ESP8266 is configured in access point mode, so the +AP_IF interface is active and the STA_IF interface is inactive. You can +configure the module to connect to your own network using the STA_IF interface. + +First activate the station interface:: + + >>> sta_if.active(True) + +Then connect to your WiFi network:: + + >>> sta_if.connect('', '') + +To check if the connection is established use:: + + >>> sta_if.isconnected() + +Once established you can check the IP address:: + + >>> sta_if.ifconfig() + ('192.168.0.2', '255.255.255.0', '192.168.0.1', '8.8.8.8') + +You can then disable the access-point interface if you no longer need it:: + + >>> ap_if.active(False) + +Here is a function you can run (or put in your boot.py file) to automatically +connect to your WiFi network:: + + def do_connect(): + import network + sta_if = network.WLAN(network.STA_IF) + if not sta_if.isconnected(): + print('connecting to network...') + sta_if.active(True) + sta_if.connect('', '') + while not network.isconnected(): + pass + print('network config:', sta_if.ifconfig()) + +Sockets +------- + +Once the WiFi is set up the way to access the network is by using sockets. +A socket represents an endpoint on a network device, and when two sockets are +connected together communication can proceed. +Internet protocols are built on top of sockets, such as email (SMTP), the web +(HTTP), telnet, ssh, among many others. Each of these protocols is assigned +a specific port, which is just an integer. Given an IP address and a port +number you can connect to a remote device and start talking with it. + +The next part of the tutorial discusses how to use sockets to do some common +and useful network tasks. diff --git a/docs/esp8266/tutorial/network_tcp.rst b/docs/esp8266/tutorial/network_tcp.rst new file mode 100644 index 0000000000..0a1cca4457 --- /dev/null +++ b/docs/esp8266/tutorial/network_tcp.rst @@ -0,0 +1,121 @@ +Network - TCP sockets +===================== + +The building block of most of the internet is the TCP socket. These sockets +provide a reliable stream of bytes between the connected network devices. +This part of the tutorial will show how to use TCP sockets in a few different +cases. + +Star Wars Asciimation +--------------------- + +The simplest thing to do is to download data from the internet. In this case +we will use the Star Wars Asciimation service provided by the blinkenlights.nl +website. It uses the telnet protocol on port 23 to stream data to anyone that +connects. It's very simple to use because it doesn't require you to +authenticate (give a username or password), you can just start downloading data +straight away. + +The first thing to do is make sure we have the socket module available:: + + >>> import socket + +Then get the IP address of the server:: + + >>> addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23) + +The ``getaddrinfo`` function actually returns a list of addresses, and each +address has more information than we need. We want to get just the first valid +address, and then just the IP address and port of the server. To do this use:: + + >>> addr = addr_info[0][-1] + +If you type ``addr_info`` and ``addr`` at the prompt you will see exactly what +information they hold. + +Using the IP address we can make a socket and connect to the server:: + + >>> s = socket.socket() + >>> s.connect(addr[0][-1]) + +Now that we are connected we can download and display the data:: + + >>> while True: + ... data = s.recv(500) + ... print(str(data, 'utf8'), end='') + ... + +When this loop executes it should start showing the animation (use ctrl-C to +interrupt it). + +You should also be able to run this same code on your PC using normal Python if +you want to try it out there. + +HTTP GET request +---------------- + +The next example shows how to download a webpage. HTTP uses port 80 and you +first need to send a "GET" request before you can download anything. As part +of the request you need to specify the page to retrieve. + +Let's define a function that can download and print a URL:: + + def http_get(url): + _, _, host, path = url.split('/', 3) + addr = socket.getaddrinfo(host, 80)[0][-1] + s = socket.socket() + s.connect(addr) + s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8')) + while True: + data = s.recv(100) + if data: + print(str(data, 'utf8'), end='') + else: + break + +Make sure that you import the socket module before running this function. Then +you can try:: + + >>> http_get('http://micropython.org/ks/test.html') + +This should retrieve the webpage and print the HTML to the console. + +Simple HTTP server +------------------ + +The following code creates an simple HTTP server which serves a single webpage +that contains a table with the state of all the GPIO pins:: + + import machine + pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)] + + html = """ + + ESP8266 Pins +

ESP8266 Pins

+ %s
PinValue
+ + + """ + + import socket + addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] + + s = socket.socket() + s.bind(addr) + s.listen(1) + + print('listening on', addr) + + while True: + cl, addr = s.accept() + print('client connected from', addr) + cl_file = cl.makefile('rwb', 0) + while True: + line = cl_file.readline() + if not line or line == b'\r\n': + break + rows = ['%s%d' % (str(p), p.value()) for p in pins] + response = html % '\n'.join(rows) + cl.send(response) + cl.close() diff --git a/docs/esp8266/tutorial/nextsteps.rst b/docs/esp8266/tutorial/nextsteps.rst new file mode 100644 index 0000000000..318bd7ddf8 --- /dev/null +++ b/docs/esp8266/tutorial/nextsteps.rst @@ -0,0 +1,12 @@ +Next steps +========== + +That brings us to the end of the tutorial! Hopefully by now you have a good +feel for the capabilities of MicroPython on the ESP8266 and understand how to +control both the WiFi and IO aspects of the chip. + +There are many features that were not covered in this tutorial. The best way +to learn about them is to read the full documentation of the modules, and to +experiment! + +Good luck creating your Internet of Things devices! diff --git a/docs/esp8266/tutorial/onewire.rst b/docs/esp8266/tutorial/onewire.rst new file mode 100644 index 0000000000..c90044b7a8 --- /dev/null +++ b/docs/esp8266/tutorial/onewire.rst @@ -0,0 +1,37 @@ +Controlling 1-wire devices +========================== + +The 1-wire bus is a serial bus that uses just a single wire for communication +(in addition to wires for ground and power). The DS18B20 temperature sensor +is a very popular 1-wire device, and here we show how to use the onewire module +to read from such a device. + +For the following code to work you need to have at least one DS18B20 temperature +sensor with its data line connected to GPIO12. You must also power the sensors +and connect a 4.7k Ohm resistor between the data pin and the power pin. :: + + import time + import machine + import onewire + + # the device is on GPIO12 + dat = machine.Pin(12) + + # create the onewire object + ds = onewire.DS18B20(onewire.OneWire(dat)) + + # scan for devices on the bus + roms = ds.scan() + print('found devices:', roms) + + # loop 10 times and print all temperatures + for i in range(10): + print('temperatures:', end=' ') + ds.convert_temp() + time.sleep_ms(750) + for rom in roms: + print(ds.read_temp(rom), end=' ') + print() + +Note that you must execute the ``convert_temp()`` function to initiate a +temperature reading, then wait at least 750ms before reading the value. diff --git a/docs/esp8266/tutorial/pins.rst b/docs/esp8266/tutorial/pins.rst new file mode 100644 index 0000000000..8ba4516273 --- /dev/null +++ b/docs/esp8266/tutorial/pins.rst @@ -0,0 +1,75 @@ +GPIO Pins +========= + +The way to connect your board to the external world, and control other +components, is through the GPIO pins. Not all pins are available to use, +in most cases only pins 0, 2, 4, 5, 12, 13, 14, 15, and 16 can be used. + +The pins are available in the machine module, so make sure you import that +first. Then you can create a pin using:: + + >>> pin = machine.Pin(0) + +Here, the "0" is the pin that you want to access. Usually you want to +configure the pin to be input or output, and you do this when constructing +it. To make an input pin use:: + + >>> pin = machine.Pin(0, machine.Pin.OUT, machine.Pin.PULL_UP) + +You can either use PULL_UP or PULL_NONE for the input pull-mode. If it's +not specified then it defaults to PULL_NONE. You can read the value on +the pin using:: + + >>> pin.value() + 0 + +The pin on your board may return 0 or 1 here, depending on what it's connected +to. To make an output pin use:: + + >>> pin = machine.Pin(0, machine.Pin.OUT) + +Then set its value using:: + + >>> pin.value(0) + >>> pin.value(1) + +Or:: + + >>> pin.low() + >>> pin.high() + +External interrupts +------------------- + +All pins except number 16 can be configured to trigger a hard interrupt if their +input changes. You can set code (a callback function) to be executed on the +trigger. + +Let's first define a callback function, which must take a single argument, +being the pin that triggered the function. We will make the function just print +the pin:: + + >>> def callback(p): + ... print('pin change', p) + +Next we will create two pins and configure them as inputs:: + + >>> from machine import Pin + >>> p0 = Pin(0, Pin.IN) + >>> p2 = Pin(2, Pin.IN) + +An finally we need to tell the pins when to trigger, and the function to call +when they detect an event:: + + >>> p0.irq(Pin.IRQ_FALLING, callback) + >>> p2.irq(Pin.IRQ_RISING | Pin.IRQ_FALLING, callback) + +We set pin 0 to trigger only on a falling edge of the input (when it goes from +high to low), and set pin 2 to trigger on both a rising and falling edge. After +entering this code you can apply high and low voltages to pins 0 and 2 to see +the interrupt being executed. + +A hard interrupt will trigger as soon as the event occurs and will interrupt any +running code, including Python code. As such your callback functions are +limited in what they can do (they cannot allocate memory, for example) and +should be as short and simple as possible. diff --git a/docs/esp8266/tutorial/powerctrl.rst b/docs/esp8266/tutorial/powerctrl.rst new file mode 100644 index 0000000000..9e44339c86 --- /dev/null +++ b/docs/esp8266/tutorial/powerctrl.rst @@ -0,0 +1,61 @@ +Power control +============= + +The ESP8266 provides the ability to change the CPU frequency on the fly, and +enter a deep-sleep state. Both can be used to manage power consumption. + +Changing the CPU frequency +-------------------------- + +The machine module has a function to get and set the CPU frequency. To get the +current frequency use:: + + >>> import machine + >>> machine.freq() + 80000000 + +By default the CPU runs at 80MHz. It can be change to 160MHz if you need more +processing power, at the expense of current consumption:: + + >>> machine.freq(160000000) + >>> machine.freq() + 160000000 + +You can change to the higher frequency just while your code does the heavy +processing and then change back when its finished. + +Deep-sleep mode +--------------- + +The deep-sleep mode will shut down the ESP8266 and all its peripherals, +including the WiFi (but not including the real-time-clock, which is used to wake +the chip). This drastically reduces current consumption and is a good way to +make devices that can run for a while on a battery. + +To be able to use the deep-sleep feature you must connect GPIO16 to the reset +pin (RST on the Adafruit Feather HUZZAH board). Then the following code can be +used to sleep and wake the device:: + + import machine + + # configure RTC.ALARM0 to be able to wake the device + rtc = machine.RTC() + rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP) + + # set RTC.ALARM0 to fire after 10 seconds (waking the device) + rtc.alarm(rtc.ALARM0, 10000) + + # put the device to sleep + machine.deepsleep() + +Note that when the chip wakes from a deep-sleep it is completely reset, +including all of the memory. The boot scripts will run as usual and you can +put code in them to check the reset cause to perhaps do something different if +the device just woke from a deep-sleep. For example, to print the reset cause +you can use:: + + if machine.reset_cause() == machine.DEEPSLEEP_RESET: + print('woke from a deep sleep') + else: + print('power on or hard reset') + diff --git a/docs/esp8266/tutorial/pwm.rst b/docs/esp8266/tutorial/pwm.rst new file mode 100644 index 0000000000..8de509427c --- /dev/null +++ b/docs/esp8266/tutorial/pwm.rst @@ -0,0 +1,87 @@ +Pulse Width Modulation +====================== + +Pulse width modulation (PWM) is a way to get an artificial analog output on a +digital pin. It achieves this by rapidly toggling the pin from low to high. +There are two parameters associated with this: the frequency of the toggling, +and the duty cycle. The duty cycle is defined to be how long the pin is high +compared with the length of a single period (low plus high time). Maximum +duty cycle is when the pin is high all of the time, and minimum is when it is +low all of the time. + +On the ESP8266 the pins 0, 2, 4, 5, 12, 13, 14 and 15 all support PWM. The +limitation is that they must all be at the same frequency, and the frequency +must be between 1Hz and 1kHz. + +To use PWM on a pin you must first create the pin object, for example:: + + >>> import machine + >>> p12 = machine.Pin(12) + +Then create the PWM object using:: + + >>> pwm12 = machine.PWM(p12) + +You can set the frequency and duty cycle using:: + + >>> pwm12.freq(500) + >>> pwm12.duty(512) + +Note that the duty cycle is between 0 (all off) and 1023 (all on), with 512 +being a 50% duty. If you print the PWM object then it will tell you its current +configuration:: + + >>> pwm12 + PWM(12, freq=500, duty=512) + +You can also call the ``freq()`` and ``duty()`` methods with no arguments to +get their current values. + +The pin will continue to be in PWM mode until you deinitialise it using:: + + >>> pwm12.deinit() + +Fading an LED +------------- + +Let's use the PWM feature to fade an LED. Assuming your board has an LED +connected to pin 2 (ESP-12 modules do) we can create an LED-PWM object using:: + + >>> led = machine.PWM(machine.Pin(2), freq=1000) + +Notice that we can set the frequency in the PWM constructor. + +For the next part we will use timing and some math, so import these modules:: + + >>> import time, math + +Then create a function to pulse the LED:: + + >>> def pulse(l, t): + ... for i in range(20): + ... l.duty(int(math.sin(i / 10 * math.pi) * 500 + 500)) + ... time.sleep_ms(t) + +You can try this function out using:: + + >>> pulse(led, 50) + +For a nice effect you can pulse many times in a row:: + + >>> for i in range(10): + ... pulse(led, 20) + +Remember you can use ctrl-C to interrupt the code. + +Control a hobby servo +--------------------- + +Hobby servo motors can be controlled using PWM. They require a frequency of +50Hz and then a duty between about 40 and 115, with 77 being the centre value. +If you connect a servo to the power and ground pins, and then the signal line +to pin 12 (other pins will work just as well), you can control the motor using:: + + >>> servo = machine.PWM(machine.Pin(12), freq=50) + >>> servo.duty(40) + >>> servo.duty(115) + >>> servo.duty(77) diff --git a/docs/esp8266/tutorial/repl.rst b/docs/esp8266/tutorial/repl.rst new file mode 100644 index 0000000000..594adb3831 --- /dev/null +++ b/docs/esp8266/tutorial/repl.rst @@ -0,0 +1,205 @@ +Getting a MicroPython REPL prompt +================================= + +REPL stands for Read Evaluate Print Loop, and is the name given to the +interactive MicroPython prompt that you can access on the ESP8266. Using the +REPL is by far the easiest way to test out your code and run commands. + +There are two ways to access the REPL: either via a wired connection through the +UART serial port, or via WiFi. + +REPL over the serial port +------------------------- + +The REPL is always available on the UART0 serial peripheral, which is connected +to the pins GPIO1 for TX and GPIO3 for RX. The baudrate of the REPL is 115200. +If your board has a USB-serial convertor on it then you should be able to access +the REPL directly from your PC. Otherwise you will need to have a way of +communicating with the UART. + +To access the prompt over USB-serial you need to use a terminal emulator program. +On Windows TeraTerm is a good choice, on Mac you can use the built-in screen +program, and Linux has picocom and minicom. Of course, there are many other +terminal programs that will work, so pick your favourite! + +For example, on Linux you can try running:: + + picocom /dev/ttyUSB0 + +Once you have made the connection over the serial port you can test if it is +working by hitting enter a few times. You should see the Python REPL prompt, +indicated by ``>>>``. + +WebREPL - a prompt over WiFi +---------------------------- + +WebREPL allows you to use the Python prompt over WiFi, connecting through a +browser. + +The first thing you need to do is get the WebREPL client loaded in your +favourite browser. The client can be found in the GitHub repository +``__ . It is called webrepl.html. +The latest versions of Firefox and Chrome are supported. + +To use WebREPL connect your computer to the ESP8266's access point +(MicroPython-xxxxxx, see the previous section about this). If you have +already reconfigured your ESP8266 to connect to a router then you can +skip this part. + +Once you are on the same network as the ESP8266 you should then open +open webrepl.html in your browser and click the "Connect" button (if +you are connecting via a router then you may need to change the IP address, +by default the IP address is correct when connected to the ESP8266's access +point). If the connection succeeds then you should see a welcome message. + +On the first connection you need to set a password. Make sure that the +terminal widget is selected by clicking on it, and then type it your password +twice (they should match each other). Then ESP8266 will then reboot with +the password applied (the WiFi will go down but come back up again). + +You should then click the "Connect" button again, and enter your password +to connect. If you type in the correct password you should get a prompt +looking like ``>>>``. You can now start typing Python commands! + +Using the REPL +-------------- + +Once you have a prompt you can start experimenting! Anything you type at the +prompt will be executed after you press the Enter key. MicroPython will run +the code that you enter and print the result (if there is one). If there is an +error with the text that you enter then an error message is printed. + +Try typing the following at the prompt:: + + >>> print('hello esp8266!') + hello esp8266! + +Note that you shouldn't type the ``>>>`` arrows, they are there to indicate that +you should type the text after it at the prompt. And then the line following is +what the device should respond with. In the end, once you have entered the text +``print("hello esp8266!")`` and pressed the Enter key, the output on your screen +should look exactly like it does above. + +If you already know some python you can now try some basic commands here. For +example:: + + >>> 1 + 2 + 3 + >>> 1 / 2 + 0.5 + >>> 12**34 + 4922235242952026704037113243122008064 + +If your board has an LED attached to GPIO2 (the ESP-12 modules do) then you can +turn it on and off using the following code:: + + >>> import machine + >>> pin = machine.Pin(2, machine.Pin.OUT) + >>> pin.high() + >>> pin.low() + +Note that ``high`` might turn the LED off and ``low`` might turn it on (or vice +versa), depending on how the LED is wired on your board. + +Line editing +~~~~~~~~~~~~ + +You can edit the current line that you are entering using the left and right +arrow keys to move the cursor, as well as the delete and backspace keys. Also, +pressing Home or ctrl-A moves the cursor to the start of the line, and pressing +End or ctrl-E moves to the end of the line. + +Input history +~~~~~~~~~~~~~ + +The REPL remembers a certain number of previous lines of text that you entered +(up to 8 on the ESP8266). To recall previous lines use the up and down arrow +keys. + +Tab completion +~~~~~~~~~~~~~~ + +Pressing the Tab key will do an auto-completion of the current word that you are +entering. This can be very useful to find out functions and methods that a +module or object has. Try it out by typing "ma" and then pressing Tab. It +should complete to "machine" (assuming you imported machine in the above +example). Then type "." and press Tab again to see a list of all the functions +that the machine module has. + +Line continuation and auto-indent +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Certain things that you type will need "continuing", that is, will need more +lines of text to make a proper Python statement. In this case the prompt will +change to ``...`` and the cursor will auto-indent the correct amount so you can +start typing the next line straight away. Try this by defining the following +function:: + + >>> def toggle(p): + ... p.value(not p.value()) + ... + ... + ... + >>> + +In the above, you needed to press the Enter key three times in a row to finish +the compound statement (that's the three lines with just dots on them). The +other way to finish a compound statement is to press backspace to get to the +start of the line, then press the Enter key. (If you did something wrong and +want to escape the continuation mode then press ctrl-C; all lines will be +ignored.) + +The function you just defined allows you to toggle a pin. The pin object you +created earlier should still exist (recreate it if it doesn't) and you can +toggle the LED using:: + + >>> toggle(pin) + +Let's now toggle the LED in a loop (if you don't have an LED then you can just +print some text instead of calling toggle, to see the effect):: + + >>> import time + >>> while True: + ... toggle(pin) + ... time.sleep_ms(500) + ... + ... + ... + >>> + +This will toggle the LED at 1Hz (half a second on, half a second off). To stop +the toggling press ctrl-C, which will raise a KeyboardInterrupt exception and +break out of the loop. + +The time module provides some useful functions for making delays and doing +timing. Use tab completion to find out what they are and play around with them! + +Paste mode +~~~~~~~~~~ + +Pressing ctrl-E will enter a special paste mode. This allows you to copy and +paste a chunk of text into the REPL. If you press ctrl-E you will see the +paste-mode prompt:: + + paste mode; Ctrl-C to cancel, Ctrl-D to finish + === + +You can then paste (or type) your text in. Note that none of the special keys +or commands work in paste mode (eg Tab or backspace), they are just accepted +as-is. Press ctrl-D to finish entering the text and execute it. + +Other control commands +~~~~~~~~~~~~~~~~~~~~~~ + +There are four other control commands: + +* Ctrl-A on a blank line will enter raw REPL mode. This is like a permanent + paste mode, except that characters are not echoed back. + +* Ctrl-B on a blank like goes to normal REPL mode. + +* Ctrl-C cancels any input, or interrupts the currently running code. + +* Ctrl-D on a blank line will do a soft reset. + +Note that ctrl-A and ctrl-D do not work with WebREPL.