======= Arduino Nano RP2040 Connect: инструкция, примеры использования и документация ======
Используйте платформу [[amp>product/arduino-nano-rp2040-connect?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Nano RP2040 Connect]] для создания электронных гаджетов, метеостанций, роботов и других изобретений. Плата программируется на языке C++ или MicroPython и отлично подойдёт как начинающим мейкерам, так и опытным разработчикам.
{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect.1.jpg?nolink |}}
===== Программирование на C++ =====
{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-software-arduino.1.png?nolink |}}
Рассмотрим программирование Nano RP2040 Connect на языке C++ в среде Arduino IDE на компьютере под управлением Windows.
==== Подключение и настройка ====
- [[#запись_загрузчика|Запишите загрузчик Arduino в плату Nano RP2040]]. Если вы только купили плату или использовали её только в Arduino IDE, загрузчик записывать не нужно.
- [[:articles:arduino-ide-install|Скачайте и установите Arduino IDE.]]
- По умолчанию среда программирования настроена только на AVR-платы. Для работы с платформой Nano RP2040 Connect добавьте в менеджере плат поддержку [[articles:arduino-boards-manager#платформы_arduino_mbed_os_nano_boards|платформ Mbed OS Nano Boards]].
- Выберите плату Nano RP2040 Connect в IDE:
Инструменты
Плата
Arduino Mbed OS Nano Boards
Arduino Nano RP2040 Connect{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-software-arduino.2.png?nolink |}}
- Выберите COM-порт в IDE:
Инструменты
Порт
COMx, где
x — номер текущего порта.{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-software-arduino.3.png?nolink |}}
- Это значит, всё получилось и можно смело переходить к [[#примеры_работы1|примерам работы]].
[[https://docs.arduino.cc/hardware/nano-rp2040-connect|Документация на плату Arduino Nano RP2040 Connect.]]
==== Примеры работы ====
Рассмотрим несколько примеров программирования Nano RP2040 Connect на C++ через Arduino IDE.
Библиотеки, которые используют в своём коде программируемый ввод-вывод PIO, используют нумерацию
GPIO микроконтроллера RP2040 вместо Arduino. Подробности по нумерацию читайте в разделе [[#распиновка|Распиновка]].
Для стабильной работы примеров обновите все сторонние библиотеки до последней версии в менеджере библиотек.
=== Маячок ===
Для начала мигнём встроенным светодиодом LED на 13 пине.
== Код для Arduino ==
// Даём имя встроенному светодиоду на 13 пине
constexpr uint8_t LED_ARDUINO_PIN = 13;
void setup() {
// Настраиваем пин со светодиодом в режим выхода
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Ждём 1 секунду
delay(1000);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Ждём 1 секунду
delay(1000);
}
После прошивки скетча светодиод начнёт мигать раз в секунду.
{{ :products:arduino-nano-rp2040-connect:example-arduino-blink.gif?nolink |}}
=== Гирлянда ===
Главная фишка Nano RP2040 — это микроконтроллер, который поддерживает возможность программируемого ввода-вывода через блоки PIO, на которых можно реализовать произвольный интерфейс. В следующем примере заставим Arduino рулить светодиодами WS2812.
== Что понадобится ==
* [[amp>product/arduino-nano-rp2040-connect?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Arduino Nano RP2040 Connect]]
* [[amp>product/usb-cable-micro?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Кабель USB (A — Micro USB)]]
* [[amp>product/breadboard-half?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Breadboard Half]]
* [[amp>product/troyka-rgb-led-4x4?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Светодиодная матрица WS2812B 4×4]]
* [[amp>product/wire-mm?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Соединительные провода «папа-папа»]]
== Схема устройства ==
{{ :products:arduino-nano-rp2040-connect:example-ws2812-rainbow.1.png?nolink |}}
== Код для Arduino ==
Для работы примера скачайте и установите библиотеку [[https://github.com/adafruit/Adafruit_NeoPixel/|Adafruit NeoPixel]].
// Библиотека для работы со светодиодами WS2812
#include
// Номер пина, к которому подключена матрица WS2812
// Библиотека использует блок PIO,
// который в свою очередь использует нумерацию
// микроконтроллера RP2040, а не Arduino.
constexpr uint8_t PIN_GPIO_WS2812 = 25;
// Количество светодиодов в матрице
constexpr uint8_t LED_COUNT = 16;
// Создаём объект для работы со светодиодной матрицей
Adafruit_NeoPixel matrix = Adafruit_NeoPixel(LED_COUNT, PIN_GPIO_WS2812, NEO_GRB + NEO_KHZ800);
void setup() {
// Инициализация матрицы
matrix.begin();
// Устанавливаем яркость светодиодов
// Диапазон значений от 0 до 255
matrix.setBrightness(40);
}
void loop() {
// Заполняем матрицу по сегментам «бегущий огонь» красного цвета
colorWipe(matrix.Color(255, 0, 0), 100);
// Заполняем матрицу по сегментам «бегущий огонь» зелёного цвета
colorWipe(matrix.Color(0, 255, 0), 100);
// Заполняем матрицу по сегментам «бегущий огонь» синего цвета
colorWipe(matrix.Color(0, 0, 255), 100);
// Гасим матрицу по сегментам «бегущая тень»
colorWipe(matrix.Color(0, 0, 0), 100);
}
// Функция заполнения каждого сегмента
void colorWipe(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < matrix.numPixels(); i++) {
// Заполняем текущий сегмент выбранным цветом
matrix.setPixelColor(i, c);
matrix.show();
// Ждём
delay(wait);
}
}
После прошивки управляющей платформы вы увидите заполнение по очереди каждого светодиода матрицы из красного, зелёного и синего цветов.
{{ :products:arduino-nano-rp2040-connect:example-ws2812-rainbow.2.gif?nolink |}}
=== Вывод информации на дисплей ===
А теперь попробуем подружить плату с дисплеем и отобразить простой текст.
== Что понадобится ==
* [[amp>product/arduino-nano-rp2040-connect?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Arduino Nano RP2040 Connect]]
* [[amp>product/usb-cable-micro?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Кабель USB (A — Micro USB)]]
* [[amp>product/breadboard-half?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Breadboard Full]]
* [[amp>product/troyka-display-lcd-text-16x2?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Текстовый дисплей 16×2 (Troyka-модуль)]]
* [[amp>product/wire-mm?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Соединительные провода «папа-папа»]]
== Схема устройства==
{{ :products:arduino-nano-rp2040-connect:example-print-text-lcd.1.png?nolink |}}
== Код для Arduino ==
Для работы примера скачайте и установите библиотеку [[https://github.com/amperka/TroykaTextLCD|TroykaTextLCD]].
// Библиотека для работы с дисплеем
#include
// Номер пина, к которому подключена подсветка дисплея
constexpr uint8_t PIN_ARDUINO_LCD_BACKLIGHT = A3;
// I²C-адрес дисплея
constexpr uint8_t LCD_SLAVE_ADDRESS = 0x3E;
// Создаём объект для работы с дисплеем
// передаём ему объект I²C, I²C-адрес и пин подсветки
TroykaTextLCD lcd(&Wire, LCD_SLAVE_ADDRESS, PIN_ARDUINO_LCD_BACKLIGHT);
void setup() {
// Устанавливаем количество столбцов и строк экрана
lcd.begin(16, 2);
// Устанавливаем контрастность в диапазоне от 0 до 63
lcd.setContrast(45);
// Устанавливаем яркость в диапазоне от 0 до 255
lcd.setBrightness(255);
// Устанавливаем курсор в колонку 0, строку 0
lcd.setCursor(0, 0);
// Печатаем первую строку
lcd.print("Hello, world!");
// Устанавливаем курсор в колонку 0, строку 1
lcd.setCursor(0, 1);
// Печатаем вторую строку
lcd.print("Arduino RP2040");
}
void loop() {
}
После прошивки управляющей платформы на дисплее отобразится приветствующий текст.{{ :products:arduino-nano-rp2040-connect:example-print-text-lcd.2.png?nolink |}}
=== Звуковая волна ===
Пришло время пошуметь, будем считывать звук со встроенного микрофона и выводить полученные данные в Serial Plotter.
== Код для Arduino ==
Для работы примера скачайте и установите библиотеку [[https://www.arduino.cc/en/Reference/PDM|PDM]].
// Библиотека для работы с микрофоном
#include
// Количество аудио каналов
constexpr uint8_t channels = 1;
// Частота дискретизации
constexpr uint32_t frequency = 16000;
// Буфер для хранения семплов
short sampleBuffer[512];
// Счётчик пришедших семплов
volatile int samplesRead;
// Границы верхнего и нижнего диапазона выводимого семпла
// Для наглядной визуализации звуковой волны в Serial Plotter
constexpr int32_t sampleLimitUpper = 3000;
constexpr int32_t sampleLimitLower = -3000;
void setup() {
// Открываем Serial-порт
Serial.begin(115200);
while (!Serial);
// Выполняем конфигурацию
PDM.onReceive(onPDMdata);
// Устанавливаем усиление сигнала
PDM.setGain(1);
// Инициализируем PDM
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop() {
// Ожидаем семплы для считывания
if (samplesRead) {
// Печатаем семплы в Serial-порт
for (int i = 0; i < samplesRead; i++) {
Serial.print(sampleLimitLower);
Serial.print("\t");
Serial.print(sampleBuffer[i]);
Serial.print("\t");
Serial.println(sampleLimitUpper);
}
// сбрасываем счётчик семплов
samplesRead = 0;
}
}
// Функция для обработки данных с микрофона
void onPDMdata() {
// Запрашиваем количество пришедших байтов
int bytesAvailable = PDM.available();
// Считываем данные в буфер
PDM.read(sampleBuffer, bytesAvailable);
// 16 бит, 2 байта на семпл
samplesRead = bytesAvailable / 2;
}
После прошивки скетча запустите Serial Plotter. А затем попробуйте пошуметь — например, хлопнуть в ладоши или включить музыку.{{ :products:arduino-nano-rp2040-connect:example-microphone-serialplotter.png?nolink |}}
=== Визуализация объекта в пространстве ===
В продолжение приведём пример отображения платы в пространстве в виде самолёта, а для этого нам поможет встроенный IMU-сенсор. Для запуска примера необходимо прошить платформу Nano RP2040 кодом ниже и настроить графическую среду Processing.
== Код для Arduino ==
Для работы примера скачайте и установите библиотеку [[https://www.arduino.cc/en/Reference/ArduinoLSM6DSOX|LSM6DSOX]].
// Библиотека для работы фильтра Madgwick
#include
// Библиотека для работы IMU-сенсора LSM6DSOXTR
#include
// Создаём объект для фильтра Madgwick
Madgwick filter;
// Переменные для данных с гироскопа и акселерометра
float gx, gy, gz, ax, ay, az;
// Переменные для хранения самолётных углов ориентации
float yaw, pitch, roll;
// Переменная для хранения частоты выборок фильтра
float sampleRate = 100;
void setup() {
// Открываем последовательный порт
Serial.begin(9600);
// Выводим сообщение об неудачной инициализации IMU
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
}
// Выводим сообщение об удачной инициализации IMU
Serial.println("Success to initialize IMU");
// Инициализируем фильтр
filter.begin();
}
void loop() {
// Запоминаем текущее время
unsigned long startMillis = millis();
// Считываем данные с акселерометра в единицах G
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(ax, ay, az);
}
// Считываем данные с гироскопа в градусах
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(gx, gy, gz);
}
// Переводим показания гироскопа изградусов в радианы в секунду
gx *= DEG_TO_RAD;
gy *= DEG_TO_RAD;
gz *= DEG_TO_RAD;
// Устанавливаем частоту фильтра
filter.setFrequency(sampleRate);
// Обновляем входные данные в фильтр
filter.update(gx, gy, gz, ax, ay, az);
if (Serial.available() > 0) {
int val = Serial.read();
// Если пришёл символ 's'
if (val == 's') {
float q0, q1, q2, q3;
filter.readQuaternion(q0, q1, q2, q3);
// Выводим кватернион в serial-порт
Serial.print(q0);
Serial.print(",");
Serial.print(q1);
Serial.print(",");
Serial.print(q2);
Serial.print(",");
Serial.println(q3);
}
}
// Вычисляем затраченное время на обработку данных
unsigned long deltaMillis = millis() - startMillis;
// Вычисляем частоту обработки фильтра
sampleRate = 1000 / deltaMillis;
}
== Настройка Processing ==
- [[https://processing.org/|Скачайте и установите графическую среду Processing.]]
- {{ :products:troyka-imu-10-dof-v2:toxiclibs.zip |Скачайте библиотеки для Processing}} и распакуйте их в директорию хранения модулей для Processing:
userdir
Processing
libraries
- [[#код_для_processing|Запустите на Processing программный код, расположенный ниже.]]
== Код для Processing ==
import processing.serial.*;
import toxi.geom.*;
import toxi.processing.*;
// NOTE: requires ToxicLibs to be installed in order to run properly.
// 1. Download from http://toxiclibs.org/downloads
// 2. Extract into [userdir]/Processing/libraries
// (location may be different on Mac/Linux)
// 3. Run and bask in awesomeness
// The serial port
Serial port;
String message;
float[] q = new float[4];
Quaternion quat = new Quaternion(1, 0, 0, 0);
// New line character in ASCII
final char newLine = '\n';
String [] massQ = new String [4];
float[] ypr = new float[3];
void setup() {
// Size form 400x400
size(400, 400, P3D);
// Open serial port
// Replace "COM7" with the COM port on which your arduino is connected
port = new Serial(this, "COM7", 9600);
}
void draw() {
// Read and parse incoming serial message
serialEvent();
// Set background to black
background(0);
printQuaternions();
printYawPitchRoll();
// Set position to centre
translate(width / 2, height / 2);
// Begin object
pushMatrix();
float[] axis = quat.toAxisAngle();
rotate(axis[0], axis[2], axis[3], axis[1]);
// Draw main body in red
drawBody();
// Draw front-facing tip in blue
drawCylinder();
// Draw Triangles
drawTriangles();
// Draw Quads
drawQuads();
// End of object
popMatrix();
// Send character 's' to Arduino
port.write('s');
}
void serialEvent() {
// Read from port until new line (ASCII code 13)
message = port.readStringUntil(newLine);
if (message != null) {
// Split message by commas and store in String array
massQ = split(message, ",");
q[0] = float(massQ[0]);
q[1] = float(massQ[1]);
q[2] = float(massQ[2]);
q[3] = float(massQ[3]);
}
// Print values to console
print(q[0]);
print("\t");
print(q[1]);
print("\t");
print(q[2]);
print("\t");
print(q[3]);
println("\t");
// Set our toxilibs quaternion to new data
quat.set(q[0], q[1], q[2], q[3]);
}
void drawCylinder() {
float topRadius = 0;
float bottomRadius = 20;
float tall = 20;
int sides = 8;
// Begin object
pushMatrix();
translate(0, 0, -120);
rotateX(PI/2);
fill(0, 0, 255, 200);
float angle = 0;
float angleIncrement = TWO_PI / sides;
beginShape(QUAD_STRIP);
for (int i = 0; i < sides + 1; ++i) {
vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
angle += angleIncrement;
}
endShape();
// if it is not a cone, draw the circular top cap
if (topRadius != 0) {
angle = 0;
beginShape(TRIANGLE_FAN);
// Center point
vertex(0, 0, 0);
for (int i = 0; i < sides + 1; i++) {
vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
angle += angleIncrement;
}
endShape();
}
// If it is not a cone, draw the circular bottom cap
if (bottomRadius != 0) {
angle = 0;
beginShape(TRIANGLE_FAN);
// Center point
vertex(0, tall, 0);
for (int i = 0; i < sides + 1; i++) {
vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
angle += angleIncrement;
}
endShape();
}
popMatrix();
}
void drawBody() {
fill(255, 0, 0, 200);
box(10, 10, 200);
}
void drawTriangles() {
// Draw wings and tail fin in green
fill(0, 255, 0, 200);
beginShape(TRIANGLES);
// Wing top layer
vertex(-100, 2, 30); vertex(0, 2, -80); vertex(100, 2, 30);
// Wing bottom layer
vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30);
// Tail left layer
vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70);
// Tail right layer
vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70);
endShape();
}
void drawQuads() {
beginShape(QUADS);
vertex(-100, 2, 30); vertex(-100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80);
vertex( 100, 2, 30); vertex( 100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80);
vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2, 30); vertex(100, 2, 30);
vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, -30, 98); vertex(-2, -30, 98);
vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, 0, 70); vertex(-2, 0, 70);
vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2, 0, 70); vertex(-2, 0, 70);
endShape();
}
void printQuaternions() {
// Set text mode to shape
textMode(SHAPE);
textSize(13);
fill(255, 255, 255);
text("Quaternions:", 20, 20, 10);
text(q[0], 20, 40, 10);
text(q[1], 20, 60, 10);
text(q[2], 20, 80, 10);
text(q[3], 20, 100, 10);
}
void printYawPitchRoll() {
// Calculate yaw/pitch/roll angles
ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1) * 57.2;
ypr[1] = atan2(2 * q[2] * q[3] - 2 * q[0] * q[1], 2 * q[0] * q[0] + 2 * q[3] * q[3] - 1) * 57.2;
ypr[2] = -atan2(2 * (q[0] * q[2] - q[1] * q[3]), 1 - 2 * (q[2] * q[2] + q[1] *q[1])) * 57.2;
text("Yaw:", 150, 20, 10);
text(ypr[0], 150, 40, 10);
text("Pitch:", 220, 20, 10);
text(ypr[1], 220, 40, 10);
text("Roll:", 290, 20, 10);
text(ypr[2], 290, 40, 10);
}
При запуске визуализации на Processing откроется окно с графическим отображением платы в виде самолёта. Самолёт на экране будет повторять перемещения IMU-сенсора в пространстве.
{{ :products:arduino-nano-rp2040-connect:example-imu-visualization-6dof-processing.png?nolink |}}
=== Соединение двух плат ===
Приведём пример, как соединить две платы по беспроводной сети.
== Что понадобится ==
* 2× [[amp>product/arduino-nano-rp2040-connect?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Arduino Nano RP2040 Connect]]
* 2× [[amp>product/usb-cable-micro?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Кабель USB (A — Micro USB)]]
* 2× [[amp>product/breadboard-half?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Breadboard Half]]
* 1× [[amp>product/troyka-rgb-led-4x4?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Кнопка (Troyka-модуль)]]
* 1× [[amp>product/troyka-rgb-led-4x4?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Светодиод 5 мм / красный (Troyka-модуль)]]
* 1× [[amp>product/wire-mm?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Соединительные провода «папа-папа» (65 шт.)]]
== Схема Peripheral Device ==
{{ :products:arduino-nano-rp2040-connect:example-peripheral-device.1.png?nolink |}}
== Схема Central Device ==
{{ :products:arduino-nano-rp2040-connect:example-central-device.1.png?nolink |}}
== Код для Peripheral Device ==
// Библиотека для общения устройств по BLE
#include
// Номер пина, к которому подключена кнопка
constexpr uint8_t PIN_ARDUINO_BUTTON = 19;
// Переменная, для хранения состояния светодиода
boolean ledSwitch;
// BLE LED Service
BLEService LEDService("19B10000-E8F2-537E-4F6C-D104768A1214");
// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic LEDCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214",
BLERead | BLENotify | BLEWrite);
void setup() {
// Открываем Serial-порт
Serial.begin(9600);
// Ожидаем подключение по USB
// Если не используете отладку, удалите строку
while (!Serial);
// Кнопку в режим входа
pinMode(PIN_ARDUINO_BUTTON, INPUT);
// Инициализируем BLE
if (!BLE.begin()) {
Serial.println("Starting BLE failed!");
}
// Устанавливаем локальное имя
BLE.setLocalName("Button Device LED");
// Устанавливаем службу UUID
BLE.setAdvertisedService(LEDService);
// Добавляем характеристику
LEDService.addCharacteristic(LEDCharacteristic);
// Добавляем сервис
BLE.addService(LEDService);
// Запускаем
BLE.advertise();
Serial.println("BLE LED Peripheral, waiting for connections…");
}
void loop() {
// Слушаем все устройства BLE
BLEDevice central = BLE.central();
// Если Central Device подключилось
if (central) {
Serial.print("Connected to central: ");
// Выводим MAC-адрес подключенного устройства
Serial.println(central.address());
// Пока Central Device подключено к переферийному
while (central.connected()) {
// Считываем состояние кнопки
bool buttonState = digitalRead(PIN_ARDUINO_BUTTON);
// Если кнопка нажата
if (buttonState == LOW) {
ledSwitch = !ledSwitch;
delay(500);
// Если светодиод не горит, включаем его
// Если светодиод горит, выключаем его
if (ledSwitch) {
Serial.println("ON");
LEDCharacteristic.writeValue((byte)0x01);
} else {
LEDCharacteristic.writeValue((byte)0x00);
Serial.println("OFF");
}
}
}
// Если Central Device отключилось
// Выводим сообщение в Serial-порт
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
== Код для Central Device ==
// Библиотека для общения устройств по BLE
#include
// Номер пина, к которому подключен светодиод
constexpr uint8_t PIN_ARDUINO_LED = 14;
void setup() {
// Открываем Serial-порт
Serial.begin(9600);
// Ожидаем подключение по USB
// Если не используете отладку, удалите строку
while (!Serial);
// Светодиод в режим выхода
pinMode(PIN_ARDUINO_LED, OUTPUT);
// Инициализируем BLE
BLE.begin();
Serial.println("BLE Central - LED control");
// Сканируем все устройства LED BLE peripherals
BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
}
void loop() {
// Проверяем было ли найдено Peripheral Device
BLEDevice peripheral = BLE.available();
// Если Peripheral Device найдено, выводим информацию в Serial-порт
if (peripheral) {
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
// Если имя Peripheral Device не содержит фразу «LED»
// Выходим из функции
if (peripheral.localName().indexOf("LED") < 0) {
Serial.println("No 'LED' in name");
return;
}
// Останавливаем сканирование
BLE.stopScan();
controlLed(peripheral);
// Если Peripheral Device отключено, продолжаем сканирование
BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
}
}
void controlLed(BLEDevice peripheral) {
// Подключаемся к Peripheral Device
Serial.println("Connecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// Сканируем свойства Peripheral Device
Serial.println("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
// Получаем текущее состояние светодиода
BLECharacteristic LEDCharacteristic = peripheral.characteristic(
"19b10001-e8f2-537e-4f6c-d104768a1214");
if (!LEDCharacteristic) {
Serial.println("Peripheral does not have LED characteristic!");
peripheral.disconnect();
return;
}
while (peripheral.connected()) {
if (LEDCharacteristic.canRead()) {
byte value = LEDCharacteristic.read();
LEDCharacteristic.readValue(value);
if (value == 0x01) {
Serial.println("ON");
digitalWrite(PIN_ARDUINO_LED, HIGH);
}
else if (value == 0x00) {
digitalWrite(PIN_ARDUINO_LED, LOW);
Serial.println("OFF");
}
}
delay(500);
}
Serial.println("Peripheral disconnected");
}
== Запуск эксперимента ==
- Соберите схему двух устройств: [[#схема_peripheral_device|Peripheral Device]] и [[#схема_central_device|Central Device]]
- Прошейте оба устройства соответствующим кодом ниже: [[#код_для_peripheral_device|Peripheral Device]] и [[#код_для_central_device|Central Device]]
- Подключите Peripheral Device и Central Device к питанию. Для отладки советуем подключить Peripheral Device к одному ПК по USB, Central Device к другому ПК по USB.
- При нажатии на кнопку на Peripheral Device, светодиод на Central Device должен менять своё состояния.{{ :products:arduino-nano-rp2040-connect:example-bluetooth-device-to-device.gif?nolink |}}
===== Программирование на MicroPython =====
{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-software-micropython.1.png?nolink |}}
Рассмотрим программирование Nano RP2040 Connect на языке MycroPython на компьютере под управлением Windows.
==== Подключение и настройка ====
- [[#запись_загрузчика|Запишите загрузчик MycroPython в плату Nano RP2040 Connect]].
- [[articles:thonny-python-ide|Скачайте и настройте Thonny Python IDE.]]
- На этом всё, можно смело переходить к [[#примеры_работы1|примерам работы]].
==== Примеры работы ====
Рассмотрим несколько примеров программирования Nano RP2040 Connect на MicroPython.
Интерпретатор Python используют нумерацию GPIO микроконтроллера RP2040 вместо Arduino. Подробности про нумерацию читайте в разделе [[#распиновка|Распиновка]].
=== Маячок ===
Для начала мигнём встроенным светодиодом LED на плате Nano RP2040. В коде используем нумерацию GPIO.
== Код для MicroPython ==
# Библиотека для работы с пинами ввода-вывода
from machine import Pin
# Библиотека для работы с временем
import time
# Даём имя встроенному светодиоду
# на 6 пине нумерации GPIO
LED_GPIO_PIN = 6
# Светодиод в режим выхода на 6 пине
led = Pin(6, Pin.OUT)
while True:
# Зажигаем светодиод
led.value(1)
# Ждём 1 секунду
time.sleep(1)
# Гасим светодиод
led.value(0)
# Ждём 1 секунду
time.sleep(1)
После прошивки скетча, светодиод начнёт мигать раз в секунду.
{{ :products:arduino-nano-rp2040-connect:example-arduino-blink.gif?nolink |}}
===== Запись загрузчика =====
- [[#режим_загрузчика|Включите плату в режиме загрузчика.]]
- Перетяните файл с прошивкой методом
Drag-and-drop в устройство Flash-накопителя с именем
RPI-RP2.
- {{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-arduino-blink.zip |Загрузчик для Arduino IDE}}
- [[https://micropython.org/download/rp2-pico/|Загрузчик для MycroPython.]]
- Перезагрузите плату, нажав на кнопку RESET.
===== Режимы загрузки =====
Arduino Nano RP2040 Connect поддерживает два метода загрузки: [[#штатный_режим|штатный режим]] и [[#режим_загрузчика|режим загрузчика]].
==== Штатный режим ====
Платформа загружается с [[#flash-память_at25sf128a-mhb-t|внешней Flash-памяти]], распаянной на плате Arduino Nano RP2040 Connect. В диспетчере устройств OS Windows плата отображается как виртуальный COM-порт с именем Устройство с последовательным интерфейсом USB. Режим служит для загрузки пользовательских программ через Arduino IDE, Thonny Python и друг сред разработки.{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-bootsel-normal-mode.1.png?nolink |}}
Активация режима происходит простым подключением платы по USB.{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-bootsel-normal-mode.2.png?nolink |}}
==== Режим загрузчика ====
Платформа загружается с внутренней памяти микроконтроллера RP2040. В диспетчере устройств OS Windows плата отображается как съёмный накопитель с именем RPI-RP2. Режим служит для загрузки прошивки в формате UF2 простым перемещением файла с одного носителя на другой.{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-bootsel-boot-mode.1.png?nolink |}}
Активация режима:
- Замкните между собой контакты REC и GND. В качестве перемычки используйте [[amp>product/jumper_pins_x10?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|джампер]] или [[amp>product/wire-mm?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|провод «папа-папа»]].
- Подключите плату к компьютеру по USB.
- Разомкните между собой контакты REC и GND.{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-bootsel-boot-mode.2.gif?nolink |}}
===== Элементы платы =====
{{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-annotation.png?nolink |}}
==== Микроконтроллер RP2040 ====
Платформа Arduino Nano RP2040 Connect выполнена на одноименном чипе {{ :products:arduino-nano-rp2040-connect:rp2040-datasheet.pdf |RP2040}} от компании Raspberry Pi Foundation. Кристалл содержит двухъядерный процессор на архитектуре ARM Cortex M0+ с тактовой частотой до 133 МГц. На RP2040 также расположились часы реального времени, датчик температуры и SRAM-память на 264 КБ. А [[#flash-память_at25sf128a-mhb-t|Flash-память на 16 МБ]] расположилась на плате отдельной микросхемой.
==== Flash-память AT25SF128A-MHB-T ====
Для хранения программ и сопутствующих статичных ресурсов на плате распаяна внешняя Flash-память {{ :products:arduino-nano-rp2040-connect:at25sf128a-mhb-t-datasheet.pdf |AT25SF128A-MHB-T}} объёмом 16 МБ.
==== Беспроводной модуль NINA-W102 ====
За беспроводную передачу данных отвечает чип {{ :products:arduino-nano-rp2040-connect:nina-w102-datasheet.pdf |U-blox NINA-W102}} со встроенным чипом ESP32 для обмена данными по воздуху в диапазоне 2,4 ГГц по Wi-Fi и Bluetooth. Для работы с модулем используйте библиотеку [[https://www.arduino.cc/en/Reference/WiFiNINA|WiFiNINA]].
==== IMU-сенсор LSM6DSOXTR ====
Инерционный модуль на чипе {{ :products:arduino-nano-rp2040-connect:lsm6dsox-datasheet.pdf |LSM6DSOXTR}} трёхосевой акселерометр и трёхосевой гироскоп для распознавания движений и моушен-функций с жестами. Для работы с модулем используйте библиотеку [[https://www.arduino.cc/en/Reference/ArduinoLSM6DSOX|ArduinoLSM6DSOX]].
==== Микрофон MP34DT05 ====
Встроенный цифровой микрофон {{ :products:arduino-nano-rp2040-connect:mp34dt05-a-datasheet.pdf |MP34DT05}} пригодится для распознавания коротких голосовых команд или записи звука. Для работы с модулем используйте библиотеку [[https://www.arduino.cc/en/Reference/PDM|PDM]].
==== Крипточип ATECC608A ====
Криптографический сопроцессор Microchip {{ :products:arduino-nano-rp2040-connect:atecc608a-datasheet.pdf |ATECC608A}} интегрирует протокол безопасности ECDH (Elliptic Curve Diffie Hellman) в сверхзащищённый метод, обеспечивающий согласование ключей для шифрования / дешифрования, наряду с ECDSA (алгоритм цифровой подписи эллиптической кривой) для проверки подлинности с подписью для Интернета вещей (IoT), включая домашнюю автоматизацию, промышленные сети, медицинские услуги, аутентификацию аксессуаров и расходных материалов.
==== Преобразователь питания MP2332 ====
Понижающий DC-DC преобразователь {{ :products:arduino-nano-rp2040-connect:mp2322-datasheet.pdf |MP2322}} обеспечивает питание [[#микроконтроллер_rp2040|микроконтроллера RP2040]] и другой логики на плате. Диапазон входного напряжения от 5 до 18 вольт. Выходное напряжение 3,3 В с максимальным выходным током 1 А.
==== Светодиодная индикация ====
^ Имя светодиода ^ Назначение ^
| ON |Индикатор питания платформы. |
| L | Пользовательский светодиод, подключенный к пину GPIO6 микроконтроллера RP2040. При задании значения высокого уровня светодиод включается, при низком – выключается. Для управления светодиодом в Arduino IDE используйте нумерацию Arduino — пин 13 или определение LED_BUILTIN. А в среде Thonny Python используйте нумерацию портов микроконтроллера PR2040 — пин 6.|
| RGB | Пользовательский RGB-светодиод с общим анодом. Катоды красного, зелёного и синего цвета выведены на пины GPIO27, GPIO25 и GPIO26 беспроводного модуля NINA-W102. При задании значения высокого уровня светодиоды выключаются, при низком – включаются. Для управления RGB-светодиодом в Arduino IDE используйте библиотеку [[https://www.arduino.cc/en/Reference/WiFiNINA|WiFiNINA]] и встроенные определения LEDR, LEDG и LEDB. |
==== Порт micro-USB ====
Разъём USB Micro предназначен для прошивки и питания платформы. Для подключения к ПК понадобится [[amp>product/usb-cable-micro?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|кабель USB (A — Micro USB)]].
==== Кнопка сброса ====
Кнопка предназначена для ручного сброса прошивки — аналог кнопки RESET обычного компьютера.
===== Распиновка =====
[[this>_media/products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-pinout.pdf|{{:products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-pinout.png}}]]
===== Принципиальная схема =====
[[this>_media/products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-schematic.pdf|{{:products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-schematic.png}}]]
===== Габаритный чертеж =====
[[this>_media/products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-dimensions.pdf|{{:products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-dimensions.png}}]]
===== Характеристики =====
* Модель: Arduino Nano RP2040 Connect (SKU ABX00053)
* Чипы и периферийные устройства:
* Микроконтроллер RP2040
* Внешняя Flash-память AT25SF128A-MHB-T
* Беспроводной модуль NINA-W102
* Инерциальный датчик LSM6DSOXTR
* МЭМС-микрофон MP34DT05
* Крипто чип ATECC608A
* RGB-светодиод
* Входное напряжение питания:
* Через USB: 5 В
* Через пин Vin: 5–18 В
* Напряжение логических уровней: 3,3 В
* Контакты ввода-вывода: 22
* Контакты с АЦП: 8
* Разрядность АЦП: 12 бит
* Контакты с ШИМ: 20
* Каналы DMA: 12
* Аппаратные интерфейсы:
* 1× UART
* 1× I²C
* 1× SPI
* Программируемый интерфейс PIO:
* До 8 подпрограмм одновременно
* До 26 контактов одновременно
* Размеры: 44,3×17,7×14,2 мм
==== Микроконтроллер RP2040 ====
* Модель: Raspberry Pi RP2040
* Количество ядер: 2× ARM Cortex-M0+ (32 бита)
* Тактовая частота: 133 МГц
* Оперативная память: 264 КБ
==== Внешняя Flash-память AT25SF128A-MHB-T ====
* Модель: Adesto Technologies AT25SF128A-MHB-T
* Объём памяти в чипе: 16 МБ
* Интерфейс: QSPI
* Скорость передачи: до 532 Мбит/с
* Циклы перезаписи: 100000
==== Беспроводной модуль NINA-W102 ====
* Модель: U-blox NINA-W102
* Количество ядер: 2× Tensilica Xtensa LX6 (32 бита)
* Тактовая частота: до 240 МГц
* Flash-память: 2 МБ
* ROM-память: 448 КБ
* SRAM-память: 520 КБ
* Частотный диапазон связи: 2,4 ГГц
* Стандарт Wi-Fi: 802.11b/g/n
* Стандарт Bluetooth: BLE v4.2 BR/EDR
* Встроенная антенна: планарная F-образная (PIFA)
==== IMU-сенсор LSM6DSOXTR ====
* Модель: ST LSM6DSOXTR
* Частота обновления 3-осевого акселерометра: 1,6–6664 Гц
* Диапазон измерения ускорения: ±2/±4/±8/±16g
* Частота обновления 3-осевого гироскопа: 12,5–6664 Гц
* Диапазон измерения поворота: ±125/±250/±500/±1000/±2000 град./с
* Дополнительные аппаратные возможности:
* Активация сценариев при наклоне устройства
* Режим шагомера — продвинутое определение и подсчёт шагов
* Конечные автоматы (FSM) и ядро машинного обучения для распознавания жестов и сценариев
==== Микрофон MP34DT05 ====
* Модель: ST MP34DT05
* Тип: микроэлектромеханический (MEMS), всенаправленный
* Точка акустической перегрузки (AOP): 122,5 дБ
* Чувствительность: -26 дБ
* Отношение сигнал/шум: 64 дБ
==== Крипточип ATECC608A ====
* Модель: криптографический сопроцессор Microchip ATECC608A
* Защищённое хранилище для криптографических ключей
* Аппаратная поддержка симметричных алгоритмов шифрования:
* SHA-256 / HMAC
* AES-128
* Встроенный генератор случайных чисел: NIST SP 800-90A/B/C
* Безопасная загрузка с цифровой подписью ECDSA
===== Ресурсы =====
* [[amp>product/arduino-nano-rp2040-connect?utm_source=man&utm_campaign=arduino-nano-rp2040-connect&utm_medium=wiki|Arduino Nano RP2040 Connect]] в магазине.
* [[https://github.com/amperka/hardware-drawings/blob/master/arduino-nano-rp2040-connect.svg|Векторное изображение Nano RP2040 Connect]]
* {{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-3d.zip |3D-файлы Nano RP2040 Connect}}
==== Полезные статьи ====
* [[articles:arduino-ide-install|Подключение и настройка Arduino IDE]]
* [[articles:thonny-python-ide|Подключение и настройка Thonny Pyhon IDE]]
==== Документация ====
* [[https://docs.arduino.cc/hardware/nano-rp2040-connect|Документация на плату Arduino Nano RP2040 Connect]]
* {{ :products:arduino-nano-rp2040-connect:arduino-nano-rp2040-connect-datasheet.pdf |Datasheet на Nano RP2040 Connect}}
* {{ :products:arduino-nano-rp2040-connect:rp2040-datasheet.pdf |Datasheet на микроконтроллер RP2040}}
* {{ :products:arduino-nano-rp2040-connect:at25sf128a-mhb-t-datasheet.pdf |Datasheet на внешнюю Flash-память AT25SF128A-MHB-T}}
* {{ :products:arduino-nano-rp2040-connect:nina-w102-datasheet.pdf |Datasheet на беспроводной модуль NINA-W102}}
* {{ :products:arduino-nano-rp2040-connect:lsm6dsox-datasheet.pdf |Datasheet на IMU-сенсор LSM6DSOX}}
* {{ :products:arduino-nano-rp2040-connect:mp34dt05-a-datasheet.pdf |Datasheet на микрофон MP34DT05}}
* {{ :products:arduino-nano-rp2040-connect:atecc608a-datasheet.pdf |Datasheet на крипточип ATECC608A}}
* {{ :products:arduino-nano-rp2040-connect:mp2322-datasheet.pdf |Datasheet на преобразователь питания MP2322}}
==== Библиотеки ====
* [[https://www.arduino.cc/en/Reference/WiFiNINA|Библиотека для беспроводного модуля NINA-W102]]
* [[https://www.arduino.cc/en/Reference/ArduinoLSM6DSOX|Библиотека для IMU-сенсора LSM6DSOXTR]]
* [[https://www.arduino.cc/en/Reference/PDM|Библиотека для микрофона MP34DT05]]