КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Установка поддержки Rasbperry Pi Pico в Arduino IDE

Общие сведения

В этой статье мы объясним как установить поддержку плат Raspberry Pi Pico в Arduino IDE.

Для установки поддержки этих плат достаточно выполнить несколько простых шагов. Перед их выполнением убедитесь, что на ПК на котором они выполняются есть подключение к сети Интернет и доступ к нему для Arduino IDE не заблокирован в Брендмауре Windows.

1 - Откройте менеджер плат Arduino IDE

Выберете пункт меню "Инструметы"->"Плата:"->"Менеджер плат..."

2 - Найдите плату в списке

Введите rp2040 в поле поиска

3 - Установите поддержку плат

Найдите строку Arduino Mbed OS RP2040 Boards и нажмите "Установить"

Начнётся установка. Если появится диалоговое окно "Контроль учётных записей", нажмите "Да".

Если появятся окна "Безопасность Windows" с установкой USB устройств, нажмите "Установить"

4 - проверка

Если Вы ещё не подключили плату к ПК, подключите её зажав кнопку "BOOTSEL" на плате.

Выберете пункт меню "Инструменты"->"Плата:"->"Arduino Mbed OS RP2040 Boards"->"Rasbperry Pi Pico"

Начнётся настройка устройства

После завершения настройки в меню "Инструменты"->"Порт" должен появится новый COM порт. Выберете его.

Загрузите проверочный скетч в плату (например Blink)

Готово!

5 - устранение неполадок (Нет COM порта в списке)

Способ 1

Если Вы уже использовали плату с MicroPython и после этого сбрасывали на заводские настройки при помощи flash_nuke.uf2 файла, то после подключения к ПК в Arduino IDE порт платы может быть не виден, но при этом внизу окна Arduino IDE будет показан COM порт отсутствующий в списке.

Просто нажмите "Загрузить скетч" не выбирая никаких портов и после загрузки скетча и перезагрузки платы появится новый порт в списке.



Способ 2

Если внизу окна Arduino IDE нет порта не из списка портов или в меню порт уже выбран какой-либо порт, то:

  • Зажмите кнопку "BOOTSEL" на плате при подключении к ПК. Плата определится как флеш карта.
  • Скопируйте на неё вот этот файл. Дождитесь перезагрузки микроконтроллера.
  • В меню "Инструменты"->"Порт" появится новый порт. Выберете его и загрузите в плату любой скетч, выбрав при этом Raspberry Pi Pico в меню плат.
  • После загрузки скетча плата определится как Raspberry Pi Pico.

Сброс на заводские настройки

Не важно, что вы загружали в плату, её всегда можно перезагрузить в режиме флеш-карты и сбросить на заводские настройки. Для этого:

  • Зажмите кнопку "BOOTSEL" на плате при подключении к ПК. Плата определится как флеш карта.
  • Скопируйте на неё flash_nuke.uf2 файл с сайта производителя. Дождитесь перезагрузки микроконтроллера.
  • Микроконтроллер сброшен на заводские настройки.

Назначение выводов Raspberry Pi Pico.

Перед тем как подключить к плате внешнее питание или устройства, необходимо разобраться с назначением выводов:

Распиновка платы:

Выводы питания на плате:

  • Вывод питания +VBUS (вход/выход) подключен к линии +5В от разъёма USB.
  • Вывод питания +VSYS (вход/выход) получает напряжение +5В от шины +VBUS через диод на плате. Если не используется питание от USB, то на вывод +VSYS можно подать внешнее питание от +1,8 до +5,5В. Напряжение шины +VSYS поступает на вход DC-DC преобразователя на плате, который может как повышать, так и понижать входное напряжение, до выходного +3,3В.
  • Вход разрешения работы 3V3_EN этот вход разрешает работу DC-DC преобразователя. Линия 3V3_EN подтянута до напряжения +VSYS, то есть по умолчанию работа DC-DC разрешена. Если вход 3V3_EN соединить с GND, то DC-DC преобразователь отключится и пропадёт напряжение 3,3В питающее микроконтроллер.
  • Выход питания +3V3(OUT) получает напряжение +3,3В с выхода DC-DC преобразователя RT6150-33GQW расположенного на плате. Этот выход можно использовать для питания внешних устройств. Максимальный ток 800 мА (включая ток потребляемый всеми чипами платы).
  • Вход +ADC_VREF позволяет задать опорное напряжение аналого-цифрового преобразователя (АЦП) ниже +3,3В. Максимальное значение АЦП будет соответствовать напряжению на данном выводе. Линия +ADC_VREF подключена на плате к линии +3V3(OUT) через сопротивление 200 Ом, значит опорное напряжение по умолчанию равно +3,3В.

Выводы подключённые к узлам схемы платы:

Из распиновки видно, что на плате не выведены выводы: GP23, GP24, GP25, GP29, но они имеются у микроконтроллера и подключены к отдельным узлам схемы на плате.

  • Вывод GP29 - подключён к шине питания +VSYS через делитель 1/3. Данный вывод можно использовать как аналоговый вход для вычисления напряжения на шине +VSYS.
  • Вывод GP25 - подключён к светодиоду на плате, через токоограничительный резистор 470 Ом. Данный вывод можно использовать как выход для включения (1) и выключения (0) светодиода.
  • Вывод GP24 - подключен к шине питания +VBUS через делитель 9/14. Данный вывод можно использовать как цифровой вход для определения наличия напряжения на шине +VBUS.
  • Вывод GP23 - подключён к входу PS преобразователя RT6150-33GQW на плате. Вывод может управлять режимом работы DC-DC преобразователя. Если на вывод подать 0, то преобразователь будет работать в режиме подбора частоты под малую нагрузку (по умолчанию), если на вывод подать 1, то преобразователь будет работать в режиме фиксированной частоты. При высокой нагрузке DC-DC преобразователь самостоятельно переходит в режим фиксированной частоты, независимо от состояния на входе PS.
  • Кнопка BOOTSEL - подключает линию GND к выводу CS чипа flash-памяти W25Q16JVUXIQ расположенного на плате.

Примеры работы с Raspberry Pi Pico в Arduino IDE.

Программы (скетчи) для работы с Raspberry Pi Pico в Arduino IDE не сильно отличаются от скетчей написанных в Arduino IDE для работы с платами Arduino, но есть некоторые отличия.

Управление выводами Raspberry Pi Pico в Arduino IDE:

При работе с выводами используются стандартные функции: pinMode(), digitalRead(), digitalWrite(), analogRead(), analogWrite(), которым указываются номера GPIO от 0 до 29, а не номера выводов платы по порядку от 1 до 40.

  • Конфигурация выводов:
    Синтаксис: pinMode( номер вывода, режим работы );
    Возвращаемое значение: Нет.
pinMode(0, INPUT);           // Конфигурируем вывод GP0 как вход.
pinMode(1, OUTPUT);          // Конфигурируем вывод GP1 как выход.
pinMode(2, INPUT_PULLUP);    // Конфигурируем вывод GP2 как вход с подтяжкой к 3V3.
pinMode(3, INPUT_PULLDOWN);  // Конфигурируем вывод GP3 как вход с прижатием к GND.

Примечание: Функция выполняется несколько миллисекунд.

  • Чтение логического уровня:
    Синтаксис: digitalRead( номер вывода );
    Возвращаемое значение: 0 (LOW) или 1 (HIGH).
bool i = digitalRead(0);     // Читаем логический уровень с вывода GP0.
bool j = digitalRead(1);     // Читаем логический уровень с вывода GP1.

Примечание: Перед чтением нужно сконфигурировать вывод.

  • Чтение аналогово сигнала:
    Синтаксис: analogRead( номер вывода );
    Возвращаемое значение: int 0...1023 (по умолчанию). Диапазон можно изменить.
int i = analogRead(26);      // Читаем аналоговый уровень с вывода GP26 (A0).
int j = analogRead(A0);      // Читаем аналоговый уровень с вывода A0 (GP26).

Примечание: Выводы можно не конфигурировать.

  • Изменение диапазона при чтении аналогово сигнала:
    Синтаксис: analogReadResolution( разрядность в битах );
    Возвращаемое значение: Нет.
analogReadResolution( 12 );  // Указываем разрядность АЦП = 12 бит.
int j = analogRead(A0);      // Теперь функция вернёт значение от 0 до 4095.

Примечание: Функцию достаточно вызвать однократно, например, в коде setup(). Функция принимает значения от 1 до 12. Можно указать разрядность выше поддерживаемой, вплоть до 32 бит, но тогда значения возвращаемые функциями analogRead() будут просто усреднены. Если функцию не вызывать, то разрядность АЦП по умолчанию будет 10 бит, а диапазон значений возвращаемых функциями analogRead() будет лежать в пределах 0 ... 1023.

  • Указание логического уровня:
    Синтаксис: digitalWrite( номер вывода, уровень );
    Возвращаемое значение: Нет.
digitalWrite(2, LOW );       // Устанавливаем на выводе GP2 низкий  уровень 0.
digitalWrite(3, HIGH);       // Устанавливаем на выводе GP3 высокий уровень 1.

Примечание: Перед указанием уровня, вывод нужно сконфигурировать как выход.

  • Указание ШИМ:
    Синтаксис: analogWrite( номер вывода, коэффициент ШИМ );
    Возвращаемое значение: Нет.
analogWrite(2, 127);         // Устанавливаем на ШИМ 127 (по умолчанию 50%).
analogWrite(3, 255);         // Устанавливаем на ШИМ 255 (по умолчанию 100%).

Примечание: Перед указанием ШИМ, вывод нужно сконфигурировать как выход. Все выводы поддерживают ШИМ, но одновременно можно использовать ШИМ не более чем на 16 выводах.

  • Изменение диапазона при указании ШИМ:
    Синтаксис: analogWriteResolution( разрядность в битах );
    Возвращаемое значение: Нет.
analogWriteResolution( 16 ); // Указываем разрядность ШИМ = 16 бит.
analogWrite(4,   255);       // Устанавливаем на выводе GP4 значение ШИМ 255   (0.4%)
analogWrite(5, 65535);       // Устанавливаем на выводе GP5 значение ШИМ 65535 (100%)

Примечание: Функцию достаточно вызвать однократно, например, в коде setup(). Функция принимает значения от 8 до 16. Если указать разрядность выше или ниже аппаратных, то коэффициент указанный функции analogWrite(), будет либо усечен, либо дополнен нулями. Если функцию не вызывать, то разрядность ШИМ по умолчанию будет 8 бит, а диапазон значений принимаемых функциями analogWrite() будет лежать в пределах 0 ... 255.

Работа с шинами Raspberry Pi Pico: UART, I2C, SPI в Arduino IDE:

На плате Raspberry Pi Pico имеются две шины UART, две шины I2C и две шины SPI.

Главное отличие шин на плате Raspberry Pi Pico от шин на платах Arduino Uno, Mini, Nano, Mega и т.д. заключается в том, что вы можете выбирать выводы шин из представленных на распиновке (см. раздел Назначение выводов).

  • Шина UART:
    Библиотека: Serial.h (предустановлена в Arduino IDE).
    Класс: UART
    Объекты:
    • Serial - для работы с шиной UART-USB (монитор последовательного порта).
    • Serial1 - для работы с шиной UART-0 (выводы по умолчанию GP0=TX, GP1=RX).
    • Для работы с шиной UART-0 можно создать свой объект указав другие выводы.
    • Для работы с шиной UART-1 нужно создать свой объект указав выводы.

Пример использования объектов шины UART-USB и UART-0 по умолчанию:

void setup(){                        //
     Serial.begin(9600);             // Инициируем работу с шиной UART-USB на скорости 9600.
     Serial1.begin(9600);            // Инициируем работу с шиной UART-0 на скорости 9600.
}                                    //
                                     //
void loop(){                         //
     Serial.println("Hello");        // Отправляем текст "Hello" по шине UART-USB (в монитор последовательного порта).
     Serial1.println("world");       // Отправляем текст "world" по шине UART-0.
//   Задержка перед новой отправкой: //
     delay(1000);                    // Ждём 1 секунду.
}                                    //

Пример создания своего объекта с указанием выводов TX и RX:

UART MySerial(4, 5);                 // Создаём экземпляр класса UART библиотеки Serial.
                                     // Указав выводы TX=4, RX=5.
void setup(){                        //
     MySerial.begin(9600);           // Инициируем работу с шиной UART на скорости 9600.
}                                    //
                                     //
void loop(){                         //
     MySerial.println("Hello");      // Отправляем текст "Hello" по шине UART.
//   Задержка перед новой отправкой: //
     delay(1000);                    // Ждём 1 секунду.
}                                    //

В примере указаны выводы 4, 5, значит используется шина UART-1.
Если указать выводы 0,1; 12,13; 16,17; то будет использована шина UART-0.
Если указать выводы 4,5; 8,9; то будет использована шина UART-1.
Можно одновременно использовать шины: UART-USB, UART-0 и UART-1.

Пример использования объекта шины UART для работы с библиотеками iArduino:

#include <iarduino_GSM.h>            // Подключаем библиотеку для работы с модулем GSM.
                                     //
UART MySerial(0, 1);                 // Создаём экземпляр класса UART библиотеки Serial, указав выводы TX=0, RX=1.
iarduino_GSM gsm(7);                 // Создаём объект gsm для работы с модулем GSM, указав вывод PWR.
                                     //
void setup(){                        //
     gsm.begin(MySerial);            // Инициируем работу с модулем GSM, указывая объект шины UART.
}                                    //
                                     //
void loop(){                         //
//   Работа с модулем GSM...         //
}                                    //

Объектам библиотек iArduino можно указывать как шину UART-0, так и шину UART-1.

Рекомендуем ознакомиться с кратким руководством по работе с шиной UART.

  • Шина I2C:
    Библиотека: Wire.h (предустановлена в Arduino IDE).
    Класс: MbedI2C
    Объекты:
    • Wire - для работы с шиной I2C-0 (выводы по умолчанию GP4=SDA, GP5=SCL).
    • Для работы с шиной I2C-0 можно создать свой объект указав другие выводы.
    • Для работы с шиной I2C-1 нужно создать свой объект указав выводы.

Пример использования объекта шины I2C по умолчанию (Wire):

#include <Wire.h>                    // Подключаем библиотеку для работы с шиной I2C.
                                     //
void setup(){                        //
     Wire.begin();                   // Инициируем работу с шиной I2C в качестве мастера.
}                                    //
                                     //
void loop(){                         //
     Wire.beginTransmission(0x09);   // Инициируем передачу данных к устройству 0x09.
     Wire.write(0x01);               // Помещаем в буфер адрес регистра.
     Wire.write(0x02);               // Помещаем в буфер байт для записи в регистр.
//   Wire.write(0x03);               // Следующие байт в следующий регистр.
     Wire.endTransmission();         // Выполняем инициированную ранее передачу данных.
//   Задержка перед новой записью:   //
     delay(1000);                    // Ждём 1 секунду.
}                                    //

Пример создания своего объекта с указанием выводов SDA и SCL:

#include <Wire.h>                    // Подключаем библиотеку для работы с шиной I2C.
MbedI2C MyWire(2, 3);                // Создаём экземпляр класса MbedI2C библиотеки Wire.
                                     // Указав выводы SDA=2, SCL=3.
void setup(){                        //
     MyWire.begin();                 // Инициируем работу с шиной I2C в качестве мастера.
}                                    //
                                     //
void loop(){                         //
     MyWire.beginTransmission(0x09); // Инициируем передачу данных к устройству 0x09.
     MyWire.write(0x01);             // Помещаем в буфер адрес регистра.
     MyWire.write(0x02);             // Помещаем в буфер байт для записи в регистр.
//   MyWire.write(0x03);             // Следующие байт в следующий регистр.
     MyWire.endTransmission();       // Выполняем инициированную ранее передачу данных.
//   Задержка перед новой записью:   //
     delay(1000);                    // Ждём 1 секунду.
}                                    //

В примере указаны выводы 2, 3, значит используется шина I2C-1.
Если указать выводы 0,1; 4,5; 8,9; 12,13; 16,17; 20,21; то будет использована шина I2C-0.
Если указать выводы 2,3; 6,7; 10,11; 14,15; 18,19; 26,27; то будет использована шина I2C-1.
Можно одновременно использовать шину I2C-0 и I2C-1.

Пример использования объекта шины I2C для работы с библиотеками iArduino:

#include <Wire.h>                    // Подключаем библиотеку для работы с шиной I2C.
#include <iarduino_I2C_Bumper.h>     // Подключаем библиотеку для работы с бампером.
                                     //
MbedI2C MyWire(0, 1);                // Создаём экземпляр класса MbedI2C библиотеки Wire, указав выводы SDA=0, SCL=1.
iarduino_I2C_Bumper bum(0x09);       // Создаём объект bum для работы с бампером, указав его адрес на шине.
                                     //
void setup(){                        //
     bum.begin(&MyWire);             // Инициируем работу с бампером, указав объект шины I2C.
}                                    //
                                     //
void loop(){                         //
//   Работа с бампером ...           //
}                                    //

Объектам библиотек iArduino можно указывать как шину I2C-0, так и шину I2C-1.

Рекомендуем ознакомиться с кратким руководством по работе с шиной I2C.

  • Шина SPI:
    Библиотека: SPI.h (предустановлена в Arduino IDE).
    Класс: MbedSPI
    Объекты:
    • SPI - для работы с шиной SPI-0
      (выводы по умолчанию GP16=MOSI, GP17=SS, GP18=SCK, GP19=MISO).
    • Для работы с шиной SPI-0 можно создать свой объект указав другие выводы.
    • Для работы с шиной SPI-1 нужно создать свой объект указав выводы.

Пример использования объекта шины SPI по умолчанию (SPI):

#include <SPI.h>                       // Подключаем библиотеку для работы с шиной SPI.
uint8_t pinSS = 17;                    // Определяем номер вывода SS.
                                       //
// Определяем настройки SPI:           //
SPISettings MySet(10000000, MSBFIRST, SPI_MODE0); // 10МГц, старшим битом вперёд, режим 0.
                                       //
void setup(){                          //
     SPI.begin();                      // Инициируем работу с шиной SPI.
     pinMode(pinSS, OUTPUT);           // Конфигурируем вывод SS как выход.
     digitalWrite(pinSS, HIGH);        // Устанавливаем высокий уровень на выводе SS.
}                                      //
                                       //
void loop(void){                       //
     uint8_t dataIn  = 0;              // Переменная для получения байта.
     uint8_t dataOut = 0;              // Переменная для передачи  байта.
     SPI.beginTransaction(MySet);      // Применяем настройки (не обязательно, если используются настройки по умолчанию).
     digitalWrite(pinSS, LOW);         // Устанавливаем низкий уровень на выводе SS.
     dataIn = SPI.transfer(dataOut);   // Передаём dataOut, получаем dataIn.
     dataIn = SPI.transfer(dataOut);   // Можно передать/получить требуемое количество байт.
     digitalWrite(pinSS, HIGH);        // Устанавливаем высокий уровень на выводе SS.
     SPI.endTransaction();             // Отменяем настройки (если они применялись функцией beginTransaction).
//   Задержка перед новыми пакетами:   //
     delay(10);                        // Ждём 10 мс.
}                                      //

Пример создания своего объекта с указанием выводов MISO, MOSI, SCK и SS:

#include <SPI.h>                       // Подключаем библиотеку для работы с шиной SPI.
MbedSPI MySPI(8, 11, 10);              // Создаём экземпляр класса MbedSPI библиотеки SPI, указав выводы MISO=12, MOSI=11, SCK=10.
uint8_t pinSS = 9;                     // Определяем номер вывода SS.
                                       //
// Определяем настройки SPI:           //
SPISettings MySet(8000000, LSBFIRST, SPI_MODE3); // 8МГц, младшим битом вперёд, режим 3.
                                       //
void setup(){                          //
     MySPI.begin();                    // Инициируем работу с шиной SPI.
     pinMode(pinSS, OUTPUT);           // Конфигурируем вывод SS как выход.
     digitalWrite(pinSS, HIGH);        // Устанавливаем высокий уровень на выводе SS.
}                                      //
                                       //
void loop(void){                       //
     uint8_t dataIn  = 0;              // Переменная для получения байта.
     uint8_t dataOut = 0;              // Переменная для передачи  байта.
     MySPI.beginTransaction(MySet);    // Применяем настройки (не обязательно, если используются настройки по умолчанию).
     digitalWrite(pinSS, LOW);         // Устанавливаем низкий уровень на выводе SS.
     dataIn = MySPI.transfer(dataOut); // Передаём dataOut, получаем dataIn.
     dataIn = MySPI.transfer(dataOut); // Можно передать/получить требуемое количество байт.
     digitalWrite(pinSS, HIGH);        // Устанавливаем высокий уровень на выводе SS.
     MySPI.endTransaction();           // Отменяем настройки (если они применялись функцией beginTransaction).
//   Задержка перед новыми пакетами:   //
     delay(10);                        // Ждём 10 мс.
}                                      //

В примере указаны выводы 8, 11, 10, 9 значит используется шина SPI-1.
Если указать выводы 0,3,2,1; 4,7,6,5; 16,19,18,17; то будет использована шина SPI-0.
Если указать выводы 8,11,10,9; 12,15,14,13; то будет использована шина SPI-1.
Можно одновременно использовать шину SPI-0 и SPI-1.

При создании объекта шины SPI указаны выводы MISO, MOSI, SCK, а вывод SS в режиме мастера управляется отдельно. В режиме ведомого используется вывод SS по умолчанию для выбранной шины SPI.

Рекомендуем ознакомиться с кратким руководством по работе с шиной SPI.

Многозадачность:

Многозадачность реализуется предустановленной в Arduino IDE библиотекой Scheduler. Библиотека автоматически устанавливается при добавлении платы.

#include <Scheduler.h>               // Подключаем библиотеку многозадачности.
                                     //
void setup(){                        //
     Serial.begin(9600);             //
     Scheduler.startLoop(MyLoop1);   // Добавляем функцию которая будет выполняться параллельно циклу loop().
     Scheduler.startLoop(MyLoop2);   // Добавляем функцию которая будет выполняться параллельно циклу loop().
}                                    //
                                     //
void loop(){                         //
     Serial.println(1);              //
     delay(1500);                    //
}                                    //
                                     //
void MyLoop1(){                      //
     while( millis()<500 );          // Задержка в течении первых 500 мс после старта.
     Serial.println(2);              //
     delay(1500);                    //
}                                    //
                                     //
void MyLoop2(){                      //
     while( millis()<1000 );         // Задержка в течении первых 1000 мс после старта.
     Serial.println(3);              //
     delay(1500);                    //
}                                    //

В примере параллельно выполняются коды функций: loop(), MyLoop1() и MyLoop2(). Можно добавить и больше функций.

Функция loop() отправляет 1 в монитор последовательного порта, с интервалом 1500мс.

В начале кода функции MyLoop1() имеется цикл while() который задержит начало выполнения этой функции на 500 мс. Далее функция будет отправлять 2, с интервалом 1500 мс.

В начале кода функции MyLoop2() имеется цикл while() который задержит начало выполнения этой функции на 1000 мс. Далее функция будет отправлять 3, с интервалом 1500 мс.

В результате в мониторе последовательного порта, через каждые 500 мс будут поочерёдно появляться цифры: 1, 2, 3.




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями