Начало работы с Raspberry Pi Pico с использованием языков программирования MicroPython и C


Плата 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 был правильно распознан на нашем ноутбуке:

[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 перезагружается как последовательное устройство:

[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:

sudo usermod -a -G dialout $(whoami)

Bootterm правильно определил порт ttyACM0, поэтому просто запускаем «bt» для доступа к интерфейсу MicroPython REPL и набираем несколько команд MicroPython.

$ 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)

>>> led2 = Pin(14, Pin.OUT)
>>> led2.value(1)

и это сработало! Если вы хотите узнать больше об API MicroPyton, нажмите Ctrl + B и введите help ():

>>> 
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:

pip3 install thonny

Затем переходим в «Выполнить» -> «Выбрать интерпретатор»… чтобы выбрать «MicroPython (Raspberry Pi Pico)».

В пользовательском интерфейсе вводим код, чтобы выключить встроенный светодиод:

Чтобы попеременно мигать встроенным светодиодом и светодиодом макета с интервалом в одну секунду, мы скопировали и изменили некоторый код из документации Python SDK:

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, зависимости и примеры следующим образом:

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:

/**
 * 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 и настроив сборку:

$ 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:

$ 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

Теперь у нас есть куча файлов:

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:

#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);
    }
}

и заново соберем программу:

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.

Оригинал статьи вы можете прочитать здесь.

5 1 vote
Article Rating
Подписаться
Уведомление о
guest

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

0 Комментарий
Inline Feedbacks
View all comments