Плата Raspberry Pi Pico была выпущена только в прошлый четверг, и благодаря Cytron мы получили образец уже через несколько часов после выпуска. У нас было достаточно времени поэкспериментировать с платой, используя языки программирования MicroPython и C.
Для начала работы мы обратились к официальной документации. Однако, чтобы добиться того, что мы хотели сделать, а именно попеременно мигать светодиодами, нам пришлось немного потрудиться, поэтому представим вам наш опыт работы с Raspberry Pi Pico с использованием компьютера, работающего на операционной системе Ubuntu 20.04. Инструкции будут аналогичными для Windows и Mac OS.
Подготовка оборудования
Мы могли бы просто начать работу только с платы, но мы решили так же воспользоваться возможностью опробовать паяльник Pinecil Pine64, работающий от источника питания MINIX NEO P2 USB-C.
Паяльник работал отлично около минуты, а потом начались проблемы… Посмотрев на экран, мы увидели, что устройство перешло в спящий режим и температуру упала. Видимо, мы недостаточно сдвигали паяльник и, не обнаружив никакой активности, устройство погрузилось в спящий режим. Изменение чувствительности к движению или интервала сна может легко решить эту проблему.
Было бы обидно не использовать эти разъемы, поэтому мы вставили Raspberry Pi Pico в макет и добавили светодиод с сопутствующей схемой.
5 В подключен к VBUS (контакт 40), GND – к контакту 38, и мы решили использовать GPIO, ближайший к светодиоду, а именно GP15 (контакт 20). Маркировка GPIO на Raspberry Pi Pico отображается только на нижней части платы, поэтому, когда плата подключена к макетной плате, помогает распиновка.
На этом настройка оборудования завершена, и все, что нам нужно, это кабель Micro USB-USB-A для подключения платы к ноутбуку.
MicroPython на Raspberry Pi Pico
Сначала мы должны скопировать прошивку MicroPython на плату. Для этого мы можем загрузить последнюю версию прошивки из руководства по началу работы (pico_micropython_20210121.uf2 на момент обзора), затем нажать клавишу BOOTSEL на плате при подключении к компьютеру с портом USB и отпустить клавишу после подключения. Мы так и сделали, но ничего не произошло. Это потому, что мы использовали USB-кабель велосипедной фары, у которого нет линии передачи данных … Поэтому мы выбрали правильный кабель micro USB – USB-Type-A, и Raspberry Pi Pico был правильно распознан на нашем ноутбуке:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[422070.155550] usb 1-2: new full-speed USB device number 16 using xhci_hcd [422070.330829] usb 1-2: New USB device found, idVendor=2e8a, idProduct=0003, bcdDevice= 1.00 [422070.330836] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [422070.330839] usb 1-2: Product: RP2 Boot [422070.330842] usb 1-2: Manufacturer: Raspberry Pi [422070.330845] usb 1-2: SerialNumber: E0C912D24340 [422070.415044] usb-storage 1-2:1.0: USB Mass Storage device detected [422070.415349] scsi host2: usb-storage 1-2:1.0 [422070.415538] usbcore: registered new interface driver usb-storage [422070.418743] usbcore: registered new interface driver uas [422071.551633] usb 1-2: reset full-speed USB device number 16 using xhci_hcd [422071.727779] scsi 2:0:0:0: Direct-Access RPI RP2 1 PQ: 0 ANSI: 2 [422071.728263] sd 2:0:0:0: Attached scsi generic sg2 type 0 [422071.728572] sd 2:0:0:0: [sdc] 262144 512-byte logical blocks: (134 MB/128 MiB) [422071.729857] sd 2:0:0:0: [sdc] Write Protect is off [422071.729860] sd 2:0:0:0: [sdc] Mode Sense: 03 00 00 00 [422071.731895] sd 2:0:0:0: [sdc] No Caching mode page found [422071.731900] sd 2:0:0:0: [sdc] Assuming drive cache: write through [422071.767149] sdc: sdc1 [422071.771908] sd 2:0:0:0: [sdc] Attached SCSI removable disk |
.. и установлен как запоминающее устройство RPI-RP2.
После копирования файла pico_micropython_20210121.uf2 на диск он автоматически отключается, и плата Pico перезагружается как последовательное устройство:
1 2 3 4 5 6 7 |
[422425.812363] usb 1-2: new full-speed USB device number 19 using xhci_hcd [422425.990450] usb 1-2: New USB device found, idVendor=2e8a, idProduct=0005, bcdDevice= 1.00 [422425.990459] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [422425.990463] usb 1-2: Product: Board in FS mode [422425.990466] usb 1-2: Manufacturer: MicroPython [422425.990470] usb 1-2: SerialNumber: 000000000000 [422426.016529] cdc_acm 1-2:1.0: ttyACM0: USB ACM device |
На данный момент руководство по началу работы на веб-сайте Raspberry Pi не очень информативно, поэтому переключаемся на документацию Python SDK (PDF).
В документации для последовательной консоли используется minicom, но мы предпочитаем Bootterm, так как его проще использовать. В любом случае, если вы программируете плату в Linux, убедитесь, что ваш текущий пользователь добавлен в группу dialout, иначе вам нужно будет запускать все программы как root:
1 |
sudo usermod -a -G dialout $(whoami) |
Bootterm правильно определил порт ttyACM0, поэтому просто запускаем «bt» для доступа к интерфейсу MicroPython REPL и набираем несколько команд MicroPython.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ bt -l port | age (sec) | device | driver | description ------+------------+------------+------------------+---------------------- * 0 | 29 | ttyACM0 | cdc_acm | Board CDC $ bt No port specified, using ttyACM0 (last registered). Use -l to list ports. Trying port ttyACM0... Connected to ttyACM0 at 115200 bps. Escape character is 'Ctrl-]'. Use escape followed by '?' for help. >>> print("Hello, Pico!") Hello, Pico! >>> from machine import Pin >>> led = Pin(25, Pin.OUT) >>> led.value(1) >>> led2 = Pin(15, Pin.OUT) >>> led2.value(1) >>> |
Нам удалось включить встроенный светодиод (GP25), но когда мы сделали то же самое для светодиода на макете (GP15), это не сработало. Перепроверяем схему и используем мультиметр, чтобы проверить уровни напряжения, и обнаруживаем, что GP25 все еще находится на низком уровне. Поискав в Интернете, мы поняли, что GP15 отключен в CircuitPython, потому что это мешает работе интерфейса USB.
Это сделано специально, GP15 не должен использоваться, он используется внутренним периферийным USB-устройством.
Мы полагаем, что то же самое произойдет и с MicroPython, поэтому переключаемся на соседний контакт (GP14, контакт 19)
1 2 |
>>> led2 = Pin(14, Pin.OUT) >>> led2.value(1) |
и это сработало! Если вы хотите узнать больше об API MicroPyton, нажмите Ctrl + B и введите help ():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
>>> raw REPL; CTRL-B to exit > MicroPython v1.13-290-g556ae7914 on 2021-01-21; Raspberry Pi Pico with RP2040 Type "help()" for more information. >>> help() Welcome to MicroPython! For online help please visit https://micropython.org/help/. For access to the hardware use the 'machine' module. RP2 specific commands are in the 'rp2' module. Quick overview of some objects: machine.Pin(pin) -- get a pin, eg machine.Pin(0) machine.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p methods: init(..), value([v]), high(), low(), irq(handler) machine.ADC(pin) -- make an analog object from a pin methods: read_u16() machine.PWM(pin) -- make a PWM object from a pin methods: deinit(), freq([f]), duty_u16([d]), duty_ns([d]) machine.I2C(id) -- create an I2C object (id=0,1) methods: readfrom(addr, buf, stop=True), writeto(addr, buf, stop=True) readfrom_mem(addr, memaddr, arg), writeto_mem(addr, memaddr, arg) machine.SPI(id, baudrate=1000000) -- create an SPI object (id=0,1) methods: read(nbytes, write=0x00), write(buf), write_readinto(wr_buf, rd_buf) machine.Timer(freq, callback) -- create a software timer object eg: machine.Timer(freq=1, callback=lambda t:print(t)) Pins are numbered 0-29, and 26-29 have ADC capabilities Pin IO modes are: Pin.IN, Pin.OUT, Pin.ALT Pin pull modes are: Pin.PULL_UP, Pin.PULL_DOWN Useful control commands: CTRL-C -- interrupt a running program CTRL-D -- on a blank line, do a soft reset of the board CTRL-E -- on a blank line, enter paste mode For further help on a specific object, type help(obj) For a list of available modules, type help('modules') |
Мы можем выйти из bootterm, нажав «Ctrl +]», а затем «q». Но что, если мы хотим сохранить нашу программу Python на плате и запускать ее автоматически? Возможно, что мы что-то пропустили, но в документации Python SDK об этом нет ничего, поэтому нам пришлось перейти к третьему руководству, чтобы узнать, как лучше всего использовать Thonny.
Ubuntu 20.04 действительно имеет Thonny 3.2.7 в своем репозитории, который мы можем установить с помощью sudo apt install thonny, но он не поддерживает Raspberry Pi Pico, поэтому устанавливаем последнюю версию программы (v3.3.3) с помощью pip3:
1 |
pip3 install thonny |
Затем переходим в «Выполнить» -> «Выбрать интерпретатор»… чтобы выбрать «MicroPython (Raspberry Pi Pico)».
В пользовательском интерфейсе вводим код, чтобы выключить встроенный светодиод:
Чтобы попеременно мигать встроенным светодиодом и светодиодом макета с интервалом в одну секунду, мы скопировали и изменили некоторый код из документации Python SDK:
1 2 3 4 5 6 7 8 9 10 11 12 |
from machine import Pin, Timer led = Pin(25, Pin.OUT) led2 = Pin(14, Pin.OUT) led.value(0) led2.value(1) tim = Timer() def tick(timer): global led, led2 led.toggle() led2.toggle() tim.init(freq=1, mode=Timer.PERIODIC, callback=tick) |
Сохраняем файл как blink.py на своем ПК, все работает нормально. Но если вы хотите запустить код без ПК, его можно сохранить на Raspberry Pi Pico. Щелкните Файл-> Сохранить копию, затем кнопку «Raspberry Pi Pico»,
и сохраните программу как main.py. Теперь вы можете запускать программу автоматически, подключив плату к любому источнику питания USB.
C / C ++ на Raspberry Pi Pico
Давайте попробуем «C / C ++ SDK», который в основном состоит из языка C, за исключением некоторых инструментов, написанных на C ++. Мы можем вернуться к официальной документации по началу работы, где нас просят скопировать blink.uf2 в Raspberry Pi Pico в режиме загрузки, и мигает встроенным светодиодом. Все работает, и это очень просто, т.к. двоичный файл предварительно собран, но мы хотим изменить исходный код и создать собственный двоичный файл, чтобы мигал как внутренний, так и внешний светодиод.
Поэтому нам нужно установить C/C++ SDK, зависимости и примеры следующим образом:
1 2 3 4 5 6 |
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential git clone https://github.com/raspberrypi/pico-sdk cd pico-sdk git submodule update --init cd .. git clone -b master https://github.com/raspberrypi/pico-examples.git |
Мы можем взглянуть на пример мигания в pico-examples / blink / blink.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include "pico/stdlib.h" int main() { const uint LED_PIN = 25; gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); while (true) { gpio_put(LED_PIN, 1); sleep_ms(250); gpio_put(LED_PIN, 0); sleep_ms(250); } } |
Хорошо. Прежде чем изменять его, мы должны попытаться собрать его, сначала экспортировав путь к SDK и настроив сборку:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ cd pico-examples/blink $ export PICO_SDK_PATH=../../pico-sdk $ cmake .. Using PICO_SDK_PATH from environment ('../../pico-sdk') Pico SDK is located at /home/jaufranc/edev/sandbox/pico-sdk Defaulting PICO_PLATFORM to rp2040 since not specified. Defaulting PICO platform compiler to pico_arm_gcc since not specified. -- Defaulting build type to 'Release' since not specified. PICO compiler is pico_arm_gcc PICO_GCC_TRIPLE defaulted to arm-none-eabi -- The C compiler identification is GNU 9.2.1 -- The CXX compiler identification is GNU 9.2.1 -- The ASM compiler identification is GNU -- Found assembler: /usr/bin/arm-none-eabi-gcc Defaulting PICO target board to pico since not specified. Using board configuration from /home/jaufranc/edev/sandbox/pico-sdk/src/boards/include/boards/pico.h -- Found Python3: /usr/bin/python3.8 (found version "3.8.5") found components: Interpreter TinyUSB available at /home/jaufranc/edev/sandbox/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; adding USB support. -- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) ELF2UF2 will need to be built PIOASM will need to be built -- Configuring done -- Generating done -- Build files have been written to: /home/jaufranc/edev/sandbox/pico-examples/blink |
Теперь мы можем войти в каталог blink (новый, созданный cmake) и запустить make:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ cd blink $ make -j8 Scanning dependencies of target ELF2UF2Build Scanning dependencies of target bs2_default [ 0%] Creating directories for 'ELF2UF2Build' [ 0%] No download step for 'ELF2UF2Build' [ 0%] No patch step for 'ELF2UF2Build' [ 0%] No update step for 'ELF2UF2Build' [ 0%] Building ASM object pico_sdk/src/rp2_common/boot_stage2/CMakeFiles/bs2_default.dir/boot2_w25q080.S.obj [ 0%] Performing configure step for 'ELF2UF2Build' [ 0%] Linking ASM executable bs2_default.elf [ 0%] Built target bs2_default ... [ 50%] Building CXX object blink/CMakeFiles/blink.dir/home/jaufranc/edev/sandbox/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj [ 50%] Building C object blink/CMakeFiles/blink.dir/home/jaufranc/edev/sandbox/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj [100%] Building C object blink/CMakeFiles/blink.dir/home/jaufranc/edev/sandbox/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj [100%] Building C object blink/CMakeFiles/blink.dir/home/jaufranc/edev/sandbox/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj [100%] Linking CXX executable blink.elf [100%] Built target blink |
Теперь у нас есть куча файлов:
1 2 3 4 5 6 7 8 9 10 11 12 |
jaufranc@cnx-laptop-4:~/edev/sandbox/pico-examples/blink/blink$ ls -l total 636 -rwxrwxr-x 1 jaufranc jaufranc 12696 Jan 24 11:42 blink.bin -rw-rw-r-- 1 jaufranc jaufranc 197019 Jan 24 11:42 blink.dis -rwxrwxr-x 1 jaufranc jaufranc 204232 Jan 24 11:42 blink.elf -rw-rw-r-- 1 jaufranc jaufranc 172574 Jan 24 11:42 blink.elf.map -rw-rw-r-- 1 jaufranc jaufranc 35778 Jan 24 11:42 blink.hex -rw-rw-r-- 1 jaufranc jaufranc 25600 Jan 24 11:42 blink.uf2 drwxrwxr-x 4 jaufranc jaufranc 4096 Jan 24 11:41 CMakeFiles -rw-rw-r-- 1 jaufranc jaufranc 1004 Jan 24 11:39 cmake_install.cmake drwxrwxr-x 4 jaufranc jaufranc 4096 Jan 24 11:39 elf2uf2 -rw-rw-r-- 1 jaufranc jaufranc 89141 Jan 24 11:39 Makefile |
Наиболее важными из них являются blink.uf2, который мы можем скопировать в Raspberry Pi Pico для запуска программы, и blink.elf, который может использоваться отладчиком (OpenOCD + GDB), но это выходит за рамки данного руководства по началу работы.
Теперь, когда мы знаем, как скомпилировать программу на C для платы Pico, давайте изменим пример blink.c, чтобы поочередно включать и выключать встроенный светодиод и внешний светодиод, подключенный к контакту 14:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include "pico/stdlib.h" int main() { const uint LED_PIN = 25; /* onboard LED */ const uint LED2_PIN = 14; /* external LED */ gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); gpio_init(LED2_PIN); gpio_set_dir(LED2_PIN, GPIO_OUT); while (true) { gpio_put(LED_PIN, 1); gpio_put(LED2_PIN, 0); sleep_ms(1000); gpio_put(LED_PIN, 0); gpio_put(LED2_PIN, 1); sleep_ms(1000); } } |
и заново соберем программу:
1 2 |
cd blink make |
Затем войдем в режим загрузки и скопируем blink.uf2 на плату, и успех!
Мы можем достичь тех же результатов с помощью программы на C или Python. Мы рассмотрим интерфейс PIO (программируемый ввод-вывод) RP2040 в одном из следующих постов, поскольку, по нашему мнению, это больше всего отличает Raspberry Pi RP2040 от других микроконтроллеров.
Мы хотели бы поблагодарить Cytron за отправку Raspberry Pi Pico на рассмотрение. Если вы находитесь в АСЕАН, вы можете приобрести плату в их магазине за 4,98 доллара США, или, если у вас есть время, вы можете заказать несущую плату за 5 долларов для Raspberry Pi Pico по той же цене с уже припаянной платой, отправки которой, как ожидается, начнутся после 10-го февраля и будут доступны во всем мире, а не только для стран АСЕАН.
Выражаем свою благодарность источнику из которого взята и переведена статья, сайту cnx-software.com.
Оригинал статьи вы можете прочитать здесь.