|
| 1 | +.. _rp2_quickref: |
| 2 | + |
| 3 | +Quick reference for the RP2 |
| 4 | +=========================== |
| 5 | + |
| 6 | +.. image:: img/rpipico.jpg |
| 7 | + :alt: Raspberry Pi Pico |
| 8 | + :width: 640px |
| 9 | + |
| 10 | +The Raspberry Pi Pico Development Board (image attribution: Raspberry Pi Foundation). |
| 11 | + |
| 12 | +Below is a quick reference for Raspberry Pi RP2xxx boards. If it is your first time |
| 13 | +working with this board it may be useful to get an overview of the microcontroller: |
| 14 | + |
| 15 | +.. toctree:: |
| 16 | + :maxdepth: 1 |
| 17 | + |
| 18 | + general.rst |
| 19 | + tutorial/intro.rst |
| 20 | + |
| 21 | +Installing MicroPython |
| 22 | +---------------------- |
| 23 | + |
| 24 | +See the corresponding section of tutorial: :ref:`rp2_intro`. It also includes |
| 25 | +a troubleshooting subsection. |
| 26 | + |
| 27 | +General board control |
| 28 | +--------------------- |
| 29 | + |
| 30 | +The MicroPython REPL is on the USB serial port. |
| 31 | +Tab-completion is useful to find out what methods an object has. |
| 32 | +Paste mode (ctrl-E) is useful to paste a large slab of Python code into |
| 33 | +the REPL. |
| 34 | + |
| 35 | +The :mod:`machine` module:: |
| 36 | + |
| 37 | + import machine |
| 38 | + |
| 39 | + machine.freq() # get the current frequency of the CPU |
| 40 | + machine.freq(240000000) # set the CPU frequency to 240 MHz |
| 41 | + |
| 42 | +The :mod:`rp2` module:: |
| 43 | + |
| 44 | + import rp2 |
| 45 | + |
| 46 | +Delay and timing |
| 47 | +---------------- |
| 48 | + |
| 49 | +Use the :mod:`time <utime>` module:: |
| 50 | + |
| 51 | + import time |
| 52 | + |
| 53 | + time.sleep(1) # sleep for 1 second |
| 54 | + time.sleep_ms(500) # sleep for 500 milliseconds |
| 55 | + time.sleep_us(10) # sleep for 10 microseconds |
| 56 | + start = time.ticks_ms() # get millisecond counter |
| 57 | + delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference |
| 58 | + |
| 59 | +Timers |
| 60 | +------ |
| 61 | + |
| 62 | +How do they work? |
| 63 | + |
| 64 | +.. _rp2_Pins_and_GPIO: |
| 65 | + |
| 66 | +Pins and GPIO |
| 67 | +------------- |
| 68 | + |
| 69 | +Use the :ref:`machine.Pin <machine.Pin>` class:: |
| 70 | + |
| 71 | + from machine import Pin |
| 72 | + |
| 73 | + p0 = Pin(0, Pin.OUT) # create output pin on GPIO0 |
| 74 | + p0.on() # set pin to "on" (high) level |
| 75 | + p0.off() # set pin to "off" (low) level |
| 76 | + p0.value(1) # set pin to on/high |
| 77 | + |
| 78 | + p2 = Pin(2, Pin.IN) # create input pin on GPIO2 |
| 79 | + print(p2.value()) # get value, 0 or 1 |
| 80 | + |
| 81 | + p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor |
| 82 | + p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation |
| 83 | + |
| 84 | +UART (serial bus) |
| 85 | +----------------- |
| 86 | + |
| 87 | +See :ref:`machine.UART <machine.UART>`. :: |
| 88 | + |
| 89 | + from machine import UART |
| 90 | + |
| 91 | + uart1 = UART(1, baudrate=9600, tx=33, rx=32) |
| 92 | + uart1.write('hello') # write 5 bytes |
| 93 | + uart1.read(5) # read up to 5 bytes |
| 94 | + |
| 95 | + |
| 96 | +PWM (pulse width modulation) |
| 97 | +---------------------------- |
| 98 | + |
| 99 | +How does PWM work on the RPi RP2xxx? |
| 100 | + |
| 101 | +Use the ``machine.PWM`` class:: |
| 102 | + |
| 103 | + from machine import Pin, PWM |
| 104 | + |
| 105 | + pwm0 = PWM(Pin(0)) # create PWM object from a pin |
| 106 | + pwm0.freq() # get current frequency |
| 107 | + pwm0.freq(1000) # set frequency |
| 108 | + pwm0.duty_u16() # get current duty cycle, range 0-65535 |
| 109 | + pwm0.duty_u16(200) # set duty cycle, range 0-65535 |
| 110 | + pwm0.deinit() # turn off PWM on the pin |
| 111 | + |
| 112 | +ADC (analog to digital conversion) |
| 113 | +---------------------------------- |
| 114 | + |
| 115 | +How does the ADC module work? |
| 116 | + |
| 117 | +Use the :ref:`machine.ADC <machine.ADC>` class:: |
| 118 | + |
| 119 | + from machine import ADC |
| 120 | + |
| 121 | + adc = ADC(Pin(32)) # create ADC object on ADC pin |
| 122 | + adc.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v |
| 123 | + |
| 124 | +Software SPI bus |
| 125 | +---------------- |
| 126 | + |
| 127 | +Software SPI (using bit-banging) works on all pins, and is accessed via the |
| 128 | +:ref:`machine.SoftSPI <machine.SoftSPI>` class:: |
| 129 | + |
| 130 | + from machine import Pin, SoftSPI |
| 131 | + |
| 132 | + # construct a SoftSPI bus on the given pins |
| 133 | + # polarity is the idle state of SCK |
| 134 | + # phase=0 means sample on the first edge of SCK, phase=1 means the second |
| 135 | + spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4)) |
| 136 | + |
| 137 | + spi.init(baudrate=200000) # set the baudrate |
| 138 | + |
| 139 | + spi.read(10) # read 10 bytes on MISO |
| 140 | + spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI |
| 141 | + |
| 142 | + buf = bytearray(50) # create a buffer |
| 143 | + spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case) |
| 144 | + spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI |
| 145 | + |
| 146 | + spi.write(b'12345') # write 5 bytes on MOSI |
| 147 | + |
| 148 | + buf = bytearray(4) # create a buffer |
| 149 | + spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer |
| 150 | + spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf |
| 151 | + |
| 152 | +.. Warning:: |
| 153 | + Currently *all* of ``sck``, ``mosi`` and ``miso`` *must* be specified when |
| 154 | + initialising Software SPI. |
| 155 | + |
| 156 | +Hardware SPI bus |
| 157 | +---------------- |
| 158 | + |
| 159 | +Hardware SPI is accessed via the :ref:`machine.SPI <machine.SPI>` class and |
| 160 | +has the same methods as software SPI above:: |
| 161 | + |
| 162 | + from machine import Pin, SPI |
| 163 | + |
| 164 | + spi = SPI(1, 10000000) |
| 165 | + spi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) |
| 166 | + spi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19)) |
| 167 | + |
| 168 | +Software I2C bus |
| 169 | +---------------- |
| 170 | + |
| 171 | +Software I2C (using bit-banging) works on all output-capable pins, and is |
| 172 | +accessed via the :ref:`machine.SoftI2C <machine.SoftI2C>` class:: |
| 173 | + |
| 174 | + from machine import Pin, SoftI2C |
| 175 | + |
| 176 | + i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000) |
| 177 | + |
| 178 | + i2c.scan() # scan for devices |
| 179 | + |
| 180 | + i2c.readfrom(0x3a, 4) # read 4 bytes from device with address 0x3a |
| 181 | + i2c.writeto(0x3a, '12') # write '12' to device with address 0x3a |
| 182 | + |
| 183 | + buf = bytearray(10) # create a buffer with 10 bytes |
| 184 | + i2c.writeto(0x3a, buf) # write the given buffer to the slave |
| 185 | + |
| 186 | +Hardware I2C bus |
| 187 | +---------------- |
| 188 | + |
| 189 | +The driver is accessed via the :ref:`machine.I2C <machine.I2C>` class and |
| 190 | +has the same methods as software I2C above:: |
| 191 | + |
| 192 | + from machine import Pin, I2C |
| 193 | + |
| 194 | + i2c = I2C(0) |
| 195 | + i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000) |
| 196 | + |
| 197 | +Real time clock (RTC) |
| 198 | +--------------------- |
| 199 | + |
| 200 | +See :ref:`machine.RTC <machine.RTC>` :: |
| 201 | + |
| 202 | + from machine import RTC |
| 203 | + |
| 204 | + rtc = RTC() |
| 205 | + rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time |
| 206 | + rtc.datetime() # get date and time |
| 207 | + |
| 208 | +WDT (Watchdog timer) |
| 209 | +-------------------- |
| 210 | + |
| 211 | +Is there a watchdog timer? |
| 212 | + |
| 213 | +See :ref:`machine.WDT <machine.WDT>`. :: |
| 214 | + |
| 215 | + from machine import WDT |
| 216 | + |
| 217 | + # enable the WDT with a timeout of 5s (1s is the minimum) |
| 218 | + wdt = WDT(timeout=5000) |
| 219 | + wdt.feed() |
| 220 | + |
| 221 | +Deep-sleep mode |
| 222 | +--------------- |
| 223 | + |
| 224 | +Is there deep-sleep support for the rp2? |
| 225 | + |
| 226 | +The following code can be used to sleep, wake and check the reset cause:: |
| 227 | + |
| 228 | + import machine |
| 229 | + |
| 230 | + # check if the device woke from a deep sleep |
| 231 | + if machine.reset_cause() == machine.DEEPSLEEP_RESET: |
| 232 | + print('woke from a deep sleep') |
| 233 | + |
| 234 | + # put the device to sleep for 10 seconds |
| 235 | + machine.deepsleep(10000) |
| 236 | + |
| 237 | +OneWire driver |
| 238 | +-------------- |
| 239 | + |
| 240 | +The OneWire driver is implemented in software and works on all pins:: |
| 241 | + |
| 242 | + from machine import Pin |
| 243 | + import onewire |
| 244 | + |
| 245 | + ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12 |
| 246 | + ow.scan() # return a list of devices on the bus |
| 247 | + ow.reset() # reset the bus |
| 248 | + ow.readbyte() # read a byte |
| 249 | + ow.writebyte(0x12) # write a byte on the bus |
| 250 | + ow.write('123') # write bytes on the bus |
| 251 | + ow.select_rom(b'12345678') # select a specific device by its ROM code |
| 252 | + |
| 253 | +There is a specific driver for DS18S20 and DS18B20 devices:: |
| 254 | + |
| 255 | + import time, ds18x20 |
| 256 | + ds = ds18x20.DS18X20(ow) |
| 257 | + roms = ds.scan() |
| 258 | + ds.convert_temp() |
| 259 | + time.sleep_ms(750) |
| 260 | + for rom in roms: |
| 261 | + print(ds.read_temp(rom)) |
| 262 | + |
| 263 | +Be sure to put a 4.7k pull-up resistor on the data line. Note that |
| 264 | +the ``convert_temp()`` method must be called each time you want to |
| 265 | +sample the temperature. |
| 266 | + |
| 267 | +NeoPixel and APA106 driver |
| 268 | +-------------------------- |
| 269 | + |
| 270 | +Use the ``neopixel`` and ``apa106`` modules:: |
| 271 | + |
| 272 | + from machine import Pin |
| 273 | + from neopixel import NeoPixel |
| 274 | + |
| 275 | + pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels |
| 276 | + np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels |
| 277 | + np[0] = (255, 255, 255) # set the first pixel to white |
| 278 | + np.write() # write data to all pixels |
| 279 | + r, g, b = np[0] # get first pixel colour |
| 280 | + |
| 281 | + |
| 282 | +The APA106 driver extends NeoPixel, but internally uses a different colour order:: |
| 283 | + |
| 284 | + from apa106 import APA106 |
| 285 | + ap = APA106(pin, 8) |
| 286 | + r, g, b = ap[0] |
| 287 | + |
| 288 | +APA102 (DotStar) uses a different driver as it has an additional clock pin. |
0 commit comments