В этой статье мы рассмотрим как программировать платы Arduino с помощью Python. Ранее на нашем сайте мы рассматривали использование языка программирования Python вместе с Arduino, чтобы продемонстрировать как управлять светодиодом из кода Python. Но тот проект использовал последовательный монитор, и были ограничения в том, что вы могли с ним делать. Но сегодня мы покажем вам, как превратить плату Arduino в инструмент сбора данных, который легко интегрируется с вашим кодом Python, независимо от операционной системы. Фактически, вы можете получить контроль над вводами-выводами платы Arduino с помощью Python. Это буквально позволит вам наслаждаться всеми функциями платы Arduino с помощью кода Python.
Крутая идея, не правда ли? Итак, без дальнейших проволочек, давайте рассмотрим эту концепцию более подробно.
Могу ли я писать код для Arduino с использованием Python?
Как мы уже знаем, взаимодействие с платой Arduino с помощью Python возможно, но требует особого подхода. Это подразумевает программирование в реальном времени, когда наша программа Python взаимодействует с платой Arduino. Для этого нам необходимо проводное или беспроводное соединение между платой Arduino и устройством, на котором запущена программа Python. Вот тут-то и приходит на помощь такой инструмент как Firmata.
Что такое Firmata?
Firmata — это протокол связи, используемый для соединения микроконтроллеров, таких как Arduino, с компьютером. Он позволяет вам управлять и взаимодействовать с входами и выходами микроконтроллера непосредственно из программного обеспечения на вашем ПК. Firmata построен на формате сообщений MIDI, который может обрабатывать сообщения различной длины. Однако это не проблема для Firmata и микроконтроллеров, поскольку объем передаваемых данных обычно минимален.
Ключевым преимуществом Firmata является то, что он реализован на нескольких языках программирования, включая Python. Это означает, что вы можете использовать Firmata с различными языками для связи с вашим микроконтроллером, что делает его универсальным и легко интегрируемым в различные программные среды. В этой статье мы сосредоточимся на Python.
Также на нашем сайте вы можете прочитать статью про управление Arduino с помощью Raspberry Pi и pyFirmata.
Как работает Firmata?
Это действительно просто, поскольку базовая архитектура для реализации Firmata уже существует в установке Arduino IDE по умолчанию. Ниже вы можете увидеть шаги, которые нужно выполнить,
- Установка стандартной программы Firmata на плату Arduino - тем самым плата Arduino ожидает протокол Firmata через USB.
- Включение библиотеки PyFirmata в существующий код Python. Таким образом, после включения PyFirmata мы можем начать добавлять специальные функции PyFirmata для взаимодействия с Arduino.
- Завершение настройки оборудования — подготовка оборудования со всеми необходимыми соединениями цепей для обеспечения надлежащей связи между датчиками, исполнительными механизмами и ПК, при этом плата Arduino должна находиться посередине.
Если вы хотите опробовать Firmata, не написав ни единой строчки кода, для пользователей Windows доступно программное обеспечение, с помощью которого можно изучить протокол Firmata с помощью простого и удобного пользовательского интерфейса.
На изображении выше показан пользовательский интерфейс программного обеспечения Windows Remote Arduino Experience, которое можно загрузить из магазина Microsoft.
Компоненты, необходимые для экспериментов с Firmata и Arduino
Поскольку мы собираемся заняться базовыми операциями ввода-вывода, компоненты будут более простыми.
- Плата Aruino UNO R3 x1 (купить на AliExpress).
- Светодиод 5мм x1 (купить на AliExpress).
- Кнопка x1.
- Потенциометр 10К x1 (купить на AliExpress).
- Микросерводвигатель SG90 x1 (купить на AliExpress).
- Макетная плата x1.
- USB-кабель для программирования Arduino x1.
- Резистор 330 Ом, 10 кОм - каждый по 1 шт. (купить на AliExpress).
- Соединительные провода - необходимое количество.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Программирование платы Arduino UNO
Сначала подготовим плату Arduino для связи по протоколу Firmata.
Как я уже упоминал ранее, нет необходимости писать ни одной строки кода на стороне Arduino. В Arduino IDE есть готовый пример для протокола Firmata. Фактически, доступно несколько режимов подключения, таких как Bluetooth, WiFi и другие. Остальное я оставлю вам для изучения. Итак, хватит разговоров — давайте начнем программировать прямо сейчас!
Выше вы можете увидеть изображение, показывающее местоположение библиотеки Firmata. Вы можете перейти по этому адресу, чтобы открыть стандартную программу Firmata. Теперь, выбрав соответствующий порт и тип платы, загрузите программу. Вот и все.
После успешной загрузки все делается на стороне Arduino. Далее мы поэкспериментируем с Python.
Установка PyFirmata
Согласно нашему тестированию, мы обнаружили, что этот модуль PyFirmata не работает с Python 3.11 или 3.12. Поэтому рекомендуемые версии — от 3.6 до 3.10. Для беспроблемной установки следуйте инструкциям ниже.
- Установка поддерживаемой версии Python: в моем случае я установил Python 3.10.
- Установка предпочитаемой вами IDE: использование непосредственно Python IDLE также должно подойти, но новичкам я рекомендую использовать PyCharm Community Edition.
- Установка необходимых пакетов: единственным требуемым пакетом здесь является PyFirmata, а при установке PyFirmata автоматически устанавливается также PySerial.
Выше вы можете увидеть список пакетов, установленных с помощью Package Manager в PyCharm.
На этом установка необходимого ПО завершена. Далее мы можем перейти к программированию Arduino с помощью Python.
Базовые функции ввода-вывода Pyfirmata
Существует пять основных операций ввода-вывода, которые мы можем выполнить с помощью PyFirmata:
- Цифровое чтение.
- Цифровая запись.
- Аналоговое считывание.
- Аналоговая запись или ШИМ-управление.
- Управление серводвигателем.
Давайте рассмотрим каждую из этих операций более подробно.
Цифровое чтение
Здесь, чтобы выполнить цифровое считывание с помощью Python на Arduino, я собираюсь подключить кнопку к контакту 2 платы Arduino. Затем этот контакт 2 подтягивается вниз с помощью резистора 10 кОм для поддержания стабильного низкого уровня.
На изображении выше показана принципиальная схема для проведения данного эксперимента. После завершения сборки принципиальной схемы подключите плату Arduino к компьютеру с помощью кабеля USB. Далее следует часть кодирования.
Код Python для цифрового считывания на Arduino
Давайте разберем код.
Шаг 1:
1 |
from pyfirmata import Arduino, util |
Эта строка импортирует определенные части библиотеки PyFirmata, а именно Arduino (для подключения к плате Arduino) и util (которая содержит полезные инструменты, такие как Iterator).
Шаг 2:
1 |
board = Arduino('COM8') |
Эта строка устанавливает соединение между вашим компьютером и платой Arduino. «COM8» — это порт, к которому подключена плата Arduino. (На разных компьютерах это может быть другой порт, например COM3, COM4 и т. д., или /dev/ttyACM0 в Linux.)
Шаг 3:
1 |
button_pin = board.get_pin('d:2:i') |
Эта строка устанавливает пин 2 на Arduino как входной пин. Вот что означают параметры:
- «d» означает «цифровой» (в отличие от аналогового).
- «2» — номер контакта на Arduino.
- «i» означает «вход», то есть этот вывод будет принимать сигналы (например, нажатие кнопки).
Шаг 4:
1 2 |
it = util.Iterator(board) it.start() |
it = util.Iterator(board): создает объект Iterator, который будет постоянно проверять состояние контактов на Arduino.
it.start(): запускает Iterator. Без него скрипт не смог бы непрерывно считывать состояние кнопки.
Шаг 5:
1 |
button_state = button_pin.read() |
«button_pin.read()» считывает состояние кнопки и сохраняет в «button_state». Состояние может быть:
- True (если кнопка нажата),
- False (если кнопка не нажата),
- None (если состояние неизвестно или вывод еще не инициализирован).
Шаг 6:
1 |
board.exit() |
Это безопасно закрывает соединение с Arduino, гарантируя, что все ресурсы освобождены и Arduino готов к следующему использованию.
Код для управления выводами GPIO Arduino с использованием Python Firmata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
from pyfirmata import Arduino, util import time # Replace 'COM8' with your Arduino port board = Arduino('COM8') # Establish a connection to the Arduino board # Set up digital pin 2 as an input pin for the button button_pin = board.get_pin('d:2:i') # 'd' stands for digital, '2' is the pin number, 'i' is for input # Start the iterator to continuously read and update pin states it = util.Iterator(board) it.start() try: while True: button_state = button_pin.read() # Read the state of the button (True, False, or None) print(f"Button state: {button_state}") # Print the current button state to the console time.sleep(1) # Wait for 1 second before reading the button state again except KeyboardInterrupt: print("Program interrupted by user.") # Print a message if the program is interrupted finally: board.exit() # Safely exit and close the connection to the Arduino |
Если вы запустите этот скрипт Python, то получите вывод, похожий на приведенное ниже GIF-видео.
Цифровая запись
Мы будем использовать простой светодиод, чтобы продемонстрировать, как можно выполнять цифровую запись на Python для Arduino. Мы подключим светодиод к контакту 3 Arduino. Контакт 3 используется как выходной контакт для управления светодиодом. Светодиод подключен последовательно с токоограничивающим резистором чтобы предотвратить повреждение светодиода чрезмерным током.
На изображении выше показана принципиальная схема для проведения данного эксперимента. После завершения схемы подключите плату Arduino к компьютеру с помощью кабеля USB. Теперь перейдем к кодированию.
Код Python для цифровой записи Arduino:
Давайте разберем код, пропуская похожие части.
1. Настройка светодиода
1 |
led_pin = board.get_pin('d:3:o') |
led_pin = board.get_pin('d:3:o'): Устанавливает контакт 3 на Arduino как выходной контакт. Параметры означают:
- «d» означает «цифровой» (в отличие от аналогового).
- «3» — номер контакта на Arduino.
- «o» означает «выход», то есть этот вывод будет отправлять сигналы (например, включать или выключать светодиод).
2. Основной цикл
1 2 3 4 5 |
while True: led_pin.write(1) # Turn LED on time.sleep(1) # Wait for 1 second led_pin.write(0) # Turn LED off time.sleep(1) # Wait for 1 second |
while True: Создает бесконечный цикл, заставляя светодиод мигать многократно.
led_pin.write(1): Включает светодиод, отправляя сигнал на контакт 3.
time.sleep(1): Приостанавливает программу на 1 секунду перед следующим действием.
led_pin.write(0): Выключает светодиод.
time.sleep(1): Приостанавливает программу еще на 1 секунду, завершая цикл мигания.
Полный код:
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 |
from pyfirmata import Arduino, util import time # Replace 'COM8' with your Arduino port board = Arduino('COM8') # Set up digital pin 3 as an output pin for the LED led_pin = board.get_pin('d:3:o') # Start the iterator to continuously read and update pin states it = util.Iterator(board) it.start() try: while True: led_pin.write(1) # Turn LED on time.sleep(1) # Wait for 1 second led_pin.write(0) # Turn LED off time.sleep(1) # Wait for 1 second except KeyboardInterrupt: print("Program interrupted by user.") # Print a message when interrupted finally: board.exit() # Safely exit and close the connection to the Arduino |
Если запустить этот скрипт Python, то на выходе вы увидите светодиод, который будет мигать каждую секунду.
Аналоговое считывание
Для считывания аналогового датчика на Arduino с помощью Python мы подключим аналоговый датчик (например, потенциометр или датчик температуры) к Arduino на аналоговом выводе A0. Датчик будет выдавать переменное напряжение, которое Arduino будет считывать и обрабатывать как аналоговый вход.
Приведенная выше схема наглядно иллюстрирует, как подключить датчик к плате Arduino. После подключения схемы подключите плату Arduino к компьютеру с помощью кабеля USB. Теперь перейдем к аспекту кодирования.
Пояснение кода:
Давайте разберем ключевые части кода.
1. Настройка датчика:
1 |
sensor_pin = board.get_pin('a:0:i') |
Настраивает аналоговый контакт A0 на Arduino как входной контакт.
- «а» означает «аналоговый».
- «0» — номер аналогового контакта.
- «i» означает «вход», указывая на то, что этот контакт будет принимать сигналы от датчика.
2. Основной цикл:
1 2 3 4 5 6 7 8 9 |
while True: # Read the current sensor value from analog pin A0 sensor_value = sensor_pin.read() # Print the sensor value to the console print(f"Sensor value: {sensor_value}") # Wait for 1 second before the next reading time.sleep(1) |
sensor_pin.read(): Считывает текущее значение с аналогового датчика, подключенного к контакту A0. Значение обычно находится в диапазоне от 0 (0 В) до 1 (5 В).
print(f"Sensor value: {sensor_value}"): отображает текущее значение датчика в консоли.
time.sleep(1): приостанавливает программу на 1 секунду перед следующим считыванием, позволяя вам отчетливо видеть каждое значение.
Код Python для считывания аналогового датчика на Arduino
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 |
from pyfirmata import Arduino, util import time # Establish connection to the Arduino board (replace 'COM8' with your specific port) board = Arduino('COM8') # Set up the sensor on analog pin A0 as an input sensor_pin = board.get_pin('a:0:i') # Start an iterator to continuously update the pin values from the Arduino it = util.Iterator(board) it.start() try: while True: # Read the current sensor value from analog pin A0 sensor_value = sensor_pin.read() # Print the sensor value to the console print(f"Sensor value: {sensor_value}") # Wait for 1 second before the next reading time.sleep(1) except KeyboardInterrupt: # Handle the program interruption by the user (Ctrl+C) print("Program interrupted by user.") finally: # Safely exit the program and close the connection to the Arduino board.exit() |
При запуске этого скрипта Python он будет непрерывно считывать и отображать значение датчика каждую секунду.
Аналоговая запись или ШИМ-управление
В этом примере мы будем управлять яркостью светодиода с помощью широтно-импульсной модуляции (ШИМ) в Python на Arduino. Светодиод подключен к цифровому контакту 5 платы Arduino, который способен выводить ШИМ. ШИМ позволяет нам изменять интенсивность свечения светодиода, регулируя рабочий цикл сигнала.
На изображении выше показана схема для проведения данного эксперимента. После настройки цепи подключите Arduino к компьютеру с помощью кабеля USB. Теперь перейдем к разделу кодирования.
Код Python для управления яркостью светодиода:
Мы разберем основные части кода, чтобы понять, как он работает.
1. Настройка светодиода для ШИМ:
1 |
led_pin = board.get_pin('d:5:p') # Цифровой вывод 5 как выход ШИМ |
Настраивает контакт 5 на Arduino как выходной контакт ШИМ. Вот что означают параметры:
- «d» означает «цифровой».
- «5» — номер контакта на Arduino.
- «p» означает «ШИМ», что позволяет выводу выдавать сигнал с различными скважностями.
2. Основной цикл:
1 2 3 4 5 6 7 8 9 10 |
while True: # Gradually increase the LED brightness from 0 to 255 for brightness in range(256): led_pin.write(brightness / 255.0) # Set LED brightness (0 to 1.0 scale) # time.sleep(0.01) # Small delay for a visible effect # Gradually decrease the LED brightness from 255 to 0 for brightness in range(255, -1, -1): led_pin.write(brightness / 255.0) # Set LED brightness (0 to 1.0 scale) # time.sleep(0.01) # Small delay for a visible effect |
- for brightness in range (256): Этот цикл постепенно увеличивает яркость светодиода от 0 (выключен) до 255 (полная яркость).
- led_pin.write(brightness / 255.0): Устанавливает яркость светодиода. Метод write() принимает значение от 0 до 1.0, поэтому мы делим яркость на 255.
- time.sleep(0.01): (Закомментировано в этом примере) Кратковременно приостанавливает программу для создания эффекта плавного затухания. Раскомментируйте, чтобы замедлить переход.
Второй цикл выполняет обратный процесс, постепенно уменьшая яркость светодиода от полной до выключенного состояния.
Код Python для управления ШИМ на Arduino
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 |
from pyfirmata import Arduino, util import time # Establish connection to the Arduino board (replace 'COM8' with your specific port) board = Arduino('COM8') # Set up the LED on digital pin 5 as a PWM output led_pin = board.get_pin('d:5:p') # Digital pin 5 as PWM output # Start an iterator to continuously update the pin values from the Arduino it = util.Iterator(board) it.start() try: while True: # Gradually increase the LED brightness from 0 to 255 for brightness in range(256): led_pin.write(brightness / 255.0) # Set LED brightness (0 to 1.0 scale) # time.sleep(0.01) # Small delay for a visible effect # Gradually decrease the LED brightness from 255 to 0 for brightness in range(255, -1, -1): led_pin.write(brightness / 255.0) # Set LED brightness (0 to 1.0 scale) # time.sleep(0.01) # Small delay for a visible effect except KeyboardInterrupt: # Handle the program interruption by the user (Ctrl+C) print("Program interrupted by user.") finally: # Safely exit the program and close the connection to the Arduino board.exit() |
При запуске этого скрипта светодиод будет постепенно загораться и гаснуть, создавая эффект плавной пульсации.
Управление серводвигателем
В этом примере мы будем управлять серводвигателем с помощью Python и Arduino. Сервопривод подключен к цифровому контакту 9 Arduino. Серводвигатель можно поворачивать на заданный угол, обычно от 0 до 180 градусов.
На схеме показано как подключить серводвигатель к Arduino. После подключения схемы подключите Arduino к компьютеру с помощью USB-кабеля, и давайте перейдем к кодированию.
Объяснение кода Python для управления серводвигателем Arduino:
Вот пошаговый разбор кода:
1. Настройка сервопривода:
1 2 |
# Установите контакт, к которому подключен сервопривод (например, контакт 9) servo_pin = board.get_pin('d:9:s') # 'd' для цифрового, 9 - номер контакта, 's' для сервопривода |
Настраивает контакт 9 на Arduino как контакт управления сервоприводом.
- «d» указывает на то, что это цифровой контакт.
- «9» — это номер контакта.
- «s» означает «сервопривод», указывая на то, что этот контакт будет управлять серводвигателем.
2. Управление сервоприводом:
1 2 3 4 5 6 7 8 9 10 |
while True: # Sweep from 0 to 180 degrees for angle in range(0, 181, 1): servo_pin.write(angle) # Move servo to the specified angle time.sleep(0.001) # Adjust the speed of the sweep # Sweep back from 180 to 0 degrees for angle in range(180, -1, -1): servo_pin.write(angle) # Move servo to the specified angle time.sleep(0.001) |
- for angle in range(0, 181, 1): Этот цикл поворачивает сервопривод от 0 до 180 градусов.
- servo_pin.write(angle): перемещает сервопривод на указанный угол.
- time.sleep(0.001): Кратковременно приостанавливает программу между изменениями угла для управления скоростью движения сервопривода.
Второй цикл меняет направление, поворачивая сервопривод со 180 градусов обратно в 0.
Код Python для управления серводвигателем:
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 |
import time from pyfirmata import Arduino # Change the port to the one your Arduino is connected to board = Arduino('COM8') # Set the pin where the servo is connected (e.g., pin 9) servo_pin = board.get_pin('d:9:s') # 'd' for digital, 9 is the pin number, 's' for servo def sweep_servo(): try: while True: # Sweep from 0 to 180 degrees for angle in range(0, 181, 1): servo_pin.write(angle) # Move servo to the specified angle time.sleep(0.001) # Adjust the speed of the sweep # Sweep back from 180 to 0 degrees for angle in range(180, -1, -1): servo_pin.write(angle) # Move servo to the specified angle time.sleep(0.001) except KeyboardInterrupt: # Handle the program interruption by the user (Ctrl+C) print("Sweep interrupted by user.") finally: # Safely exit the program and close the connection to the Arduino board.exit() # Run the sweep function sweep_servo() |
При запуске этого скрипта серводвигатель будет плавно поворачиваться вперед и назад в диапазоне от 0 до 180 градусов.
Преимущества использования Firmata:
- Простота использования: Firmata взаимодействует между Arduino и Python, позволяя вам управлять оборудованием с помощью простых команд без необходимости написания специальной прошивки.
- Взаимодействие в реальном времени: Firmata поддерживает обмен данными в реальном времени, что делает его идеальным для интерактивных приложений, где необходимы немедленная обратная связь и контроль.
- Кроссплатформенная совместимость: Firmata поддерживается на различных платформах, что позволяет разрабатывать и запускать проекты на разных операционных системах с минимальными изменениями.
- Быстрое прототипирование: ускоряет создание прототипов за счет сокращения необходимости в низкоуровневом коде, позволяя вам сосредоточиться на логике и функциональности вашего приложения.
Недостатки использования Firmata:
- Ограниченное управление: Firmata предоставляет интерфейс общего назначения, который может не подойти для проектов, требующих точной настройки управления или доступа к расширенным функциям микроконтроллера.
- Ограничение производительности: Уровень абстракции, введенный Firmata, может привести к ограничениям производительности, особенно в приложениях, чувствительных ко времени или ограниченных по ресурсам.
- Зависимость от внешних библиотек: использование Firmata требует дополнительных библиотек, что может вызвать проблемы совместимости или увеличить сложность управления зависимостями в вашем проекте.
Рассмотрев эти плюсы и минусы, вы сможете определить, является ли Firmata правильным выбором для нужд вашего конкретного проекта.
44 просмотров