Как разгрузить регулятор и подключить сервоприводы
Перейти к содержимому

Как разгрузить регулятор и подключить сервоприводы

  • автор:

Arduino UNO урок 2 — Управление сервоприводом

Сервопривод является очень важным элементом при конструировании роботов и радиоуправляемых моделей. Во втором уроке мы рассмотрим как при помощи Arduino UNO управлять сервоприводом. Программа очень проста и наглядна. Начинается она с подключения файла. Данный файл содержит все необходимые команды для управления серво, чтобы облегчить нам жизнь и не изобретать велосипед. Далее, мы должны создать обьект servo. Пусть это будет servoMain. Следующая функция будет setup(), в которой мы указываем, что сервопривод подключен к выводу 10 контроллера. Теперь все готово и мы можем посылать команды для управления серво. В главной функции loop(), мы даем различные команды для серводвигателя, выдерживая паузы между командами.

/* Arduino Servo */ #include "Servo.h" Servo servoMain; // Объект Servo void setup() < servoMain.attach(10); // Servo присоединен к 10 выводу >void loop() < servoMain.write(45); // Повернуть серво влево на 45 градусов delay(2000); // Пауза 2 сек. servoMain.write(0); // Повернуть серво влево на 0 градусов delay(1000); // Пауза 1 сек. servoMain.write(90); // Повернуть серво на 90 градусов. Центральная позиция delay(1500); // Пауза 1.5 сек. servoMain.write(135); // Повернуть серво вправо на 135 градусов delay(3000); // Пауза 3 сек. servoMain.write(180); // Повернуть серво вправо на 180 градусов delay(1000); // Пауза 1 сек. servoMain.write(90); // Повернуть серво на 90 градусов. Центральная позиция delay(5000); // Пауза 5 сек. >

Сервопривод

Используемый в проекте сервопривод содержит 3 провода: черный, красный и оранжевый или белый Схема подсоединения к Arduino следующая: черный провод присоединяем к выводу Arduino 0V, красный к Arduino 5V и оранжевый/белый к 10 выводу Arduino UNO. Оригинал статьи

Теги:

Колтыков А.В. Опубликована: 2011 г. 0 0

Вознаградить Я собрал 0 0

Оценить статью

  • Техническая грамотность

Настройка передатчика

Отлично, вы окончательно решились и приобрели желаемую радиоаппаратуру — с большим цифровым экраном, удобным рулевым колесом и большим количеством настроек. Что теперь? Вы можете просто распаковать радиоаппаратуру и начать ее использовать, или вы можете действительно потратить свое время для того, чтобы получить максимум от своего нового приобретения. Правильная настройка передатчика не займет слишком много времени, и что лучше всего, это не очень сложно.

1. Перед тем как настраивать, верните в исходное состояние

С совершенно новым передатчиком это не является проблемой, но если ваш «новый» передатчик в действительности уже использовался, вам необходимо удостовериться, что все настройки сброшены к заводским установкам, перед тем, как вы попытаетесь настраивать передатчик под новую модель. Не ничего хуже, чем пройти через все настройки только для того, чтобы обнаружить, что триммеры уже были установлены в максимум в одном из направлений, когда вы центровали сервоприводы. Большинство передатчиков обладают возможностью сбросить весь передатчик (или только одну модель) обратно к настройкам по умолчанию, за подробностями обратитесь к руководству по вашему передатчику. Удостоверьтесь, что ВСЕ триммеры и субтриммеры вашего передатчика находятся в «0» положении.

2. Проверка приемника

Это на самом деле не стоит разговоров, но достаточно много людей упускают это из виду, поэтому стоит упомянуть это здесь. Не все приемники работают со всеми передатчиками! Перед тем, как пробовать водить вашу модель, отсоедините мотор (в электрической автомодели) или оставьте двигатель заглушенным, и удостоверьтесь, что контролируете модель с текущей комбинацией передатчик-приемник. В большинстве случаев, если передатчик и приемник работают на одной частоте, одинаковом канале (например, 27 МГц канал 6) и с одинаковым типом модуляции радиосигнала (AM, FM), они будут нормально взаимодействовать. Но некоторые комбинации передатчик-приемник просто не будут нормально работать и, конечно, при различных частотах они вообще не будут работать. Если вы сомневаетесь, проконсультируйтесь в магазине, в котором вы покупали передатчик, будет ли он работать с вашим приемником.

3. Установите направление работы сервоприводов

Установка сервоприводов и направление расположения тяг зависит от модели. Следовательно, может потребоваться изменить направление работы сервоприводов относительно установленного в передатчике. Перед установкой сервопривода проверьте направление работы и настройте его, используя функцию реверса в передатчике.

Если колеса поворачиваются налево, когда вы поворачиваете рулевое колесо направо, тогда измените в вашем передатчике направление работы сервопривода рулевого управления (steering). Если применяется торможение, когда вы нажимаете курок газа, тогда измените направление работы сервопривода газа (throttle).

4. Центровка сервоприводов

Это один из наиболее важных шагов в настройке радиоаппаратуры и он должен быть выполнен до проведения любых настроек непосредственно в передатчике. Снимите с сервопривода рычаг сервопривода, и при включенном приемнике и передатчике расположите рычаг так, чтобы он находился настолько близко к желаемому положению, насколько это возможно, в то время, когда сервопривод отцентрован. Когда вы проводите эту операцию, все триммеры и субтриммеры в передатчике должны находиться точно в «0» положении. Это позволит сервоприводу начать работу максимально близко к нулевому/центральному положению.

5. Настройка субтриммеров

Теперь, когда ваши сервоприводы отцентрованы, используйте субтриммеры в вашем передатчике для точной установки сервоприводов в желаемое положение. Из-за наличия шлицов на выходном валу сервопривода, рычаг сервопривода обычно слегка отклоняется от желаемого положения, поэтому вам потребуется небольшая регулировка для получения точного выравнивания. В этом случае вам не должно потребоваться более 2-х или 3-х щелчков от центрального положения субтриммера, если это не так, тогда вы неправильно отцентровали сервопривод или вам необходимо отрегулировать тяги рулевого управления или газа. Всегда будет лучше удостовериться, что вся механика отцентрована, чем полагаться на триммеры передатчика.

Субтриммер регулирует весь диапазон сервопривода в указанном направлении. Используется для регулировки нейтрального положения сервоприводов.

6. Настройки электронного регулятора скорости

Очевидно, что это может быть пропущено для автомодели с двигателем внутреннего сгорания, но для электрической автомодели это необходимо. Электронный регулятор скорости вашей автомодели полагается на конечные точки газа, полученный от вашего передатчика, для определения своей отдачи газа, а когда вы меняете передатчик, эти точки также могут измениться. Большинство современных электронных регуляторов скорости (ESC) обладают возможностью настройки с помощью одного нажатия кнопки, что делает эту настройку достаточно простой. Обратитесь к руководству по вашему ESC и выполните настроечную процедуру (в этот момент мотор должен быть отсоединен).

7. Настройка конечных точек (End Point Adjustment)

Конечные точки рулевого управления (Steering EPA):

  • Найдите настройку EPA в передатчике, удостоверьтесь, что выбрали ST или steering.
  • Поверните рулевое колесо на 1/4 налево и снизьте левую конечную точку (EPA) до 30.
  • Поверните рулевое колесо на 1/4 направо и снизьте правую конечную точку (EPA) до 30.
  • Теперь поверните полностью рулевое колесо налево, медленно увеличивайте левую конечную точку (EPA) до тех пор, пока не увидите, что не можете поворачивать дальше, плюс к этому вы услышите звук застрявшего сервопривода. Как только вы достигли максимального значения при повороте налево, верните конечную точку (EPA) назад на 2 значения.
  • Теперь поверните полностью рулевое колесо направо, медленно увеличивайте правую конечную точку (EPA) до тех пор, пока не увидите, что не можете поворачивать дальше, плюс к этому вы услышите звук застрявшего сервопривода. Как только вы достигли максимального значения при повороте направо, верните конечную точку (EPA) назад на 2 значения.

Конечные точки газа (Throttle EPA):

  • Найдите настройку EPA в передатчике, удостоверьтесь, что выбрали TH или throttle.
  • Нажмите на курок газа на 1/4 и снизьте конечную точку газа (throttle EPA) до 30.
  • Толкните курок газа или примените торможение на 1/4 и снизьте конечную точку тормоза (brake EPA) до 30.
  • Теперь полностью нажмите газ, медленно увеличивайте конечную точку газа до тех пор, пока карбюратор полностью не откроется. Наблюдайте за тягой газа, плюс к этому вы услышите звук застрявшего сервопривода. Как только вы достигли максимального значения газа, верните конечную точку (EPA) назад на 1 значение.
  • Теперь примените полное торможение, затем прокатите вашу модель, чтобы определить текущую величину торможения, медленно увеличивайте или уменьшайте конечную точку тормоза до тех пор, пока не получите хорошего торможения. Запомните, что вам нужно хорошее торможение, а не полностью заблокированный тормоз.

Примечание: Если у вас есть передний и задний тормоз, отрегулируйте тяги для осуществления торможения на каждом из них. Некоторые предпочитают иметь меньшее торможение на переднем тормозе и большее торможение на заднем тормозе (40/60). После регулировки тяг вам может потребоваться снова отрегулировать конечную точку тормоза (EPA).

7. Тестирование на трассе

Теперь, когда вы завершили основные настройки, настало время для запуска автомодели и проведения дальнейших регулировок. В большинстве передатчиков существует больше настроек, чем эти, но это несколько самых первых, которые вы должны проверить:

Триммер — Настройка триммера передатчика позволяет вам точно настроить триммирование. Это наиболее часто используется с сервоприводом рулевого управления, где даже после центрирования и субтриммирования, может оставаться небольшое рассогласование. Запустите вашу автомодель по прямой линии, и если она смещается к одной из сторон, используйте триммер для исправления ситуации. Если вы попробовали это сделать несколько раз и не можете заставить автомодель ехать прямо, то вероятно существует механическая проблема, которая мешает достичь идеального выравнивания. Пройдитесь по тягам автомодели и по подвеске, и проверьте такие настройки, как развал и схождение.

Сдвоенный коэффициент (Dual Rate) — Сдвоенный коэффициент увеличивает или уменьшает расход рулевого управления сразу на обеих сторонах одновременно, в то же время увеличивая или уменьшая реакцию на управление рулевым колесом. Если вам нужна более чувствительная автомодель, тогда будет лучше использовать более высокие значения сдвоенного коэффициента, если вам нужно снизить чувствительность автомодели, тогда вы можете немного снизить значение сдвоенного коэффициента. Многие передатчики обладают возможностью легкой регулировки сдвоенного коэффициента во время вождения, так что вы можете легко отрегулировать его до желаемого уровня.

Экспонента (Exponential) — Многие профессиональные передатчики обладают настройками экспоненты для рулевого управления и газа. Настройка экспоненты будет изменять отклик рулевого управления или газа от линейного до экспоненциальной кривой, начиная от центра. Это обычно используется для снижения реакции автомодели около центрального положения, чтобы небольшие повороты рулевого колеса или небольшие нажатия на газ не оказывали резкого влияния на автомодель. При линейной настройке, поворот рулевого колеса на 25% вызывает поворот колес на 25% от максимальной величины поворота. Однако, с экспоненциальной кривой, эти же 25% поворота рулевого колеса поворачивают колеса только на 10% от максимальной величины поворота, в то же время поворот рулевого колеса в интервале между 50% и 100% поворачивает колеса намного быстрее. Если у вас есть проблемы со слишком резкой реакцией автомодели на поворот рулевого колеса, попробуйте небольшую отрицательную экспоненту и посмотрите на реакцию. Эти настройки подходят не для каждого, но некоторые — включая профессиональных водителей — ими пользуются. Экспонента также особенно полезна в качестве формы «traction control» для автомоделей с двигателем внутреннего сгорания путем смягчения газа.

Если ваш передатчик обладает памятью для нескольких моделей, и вы хотите проследить как именно некоторые настройки влияют на вашу автомодель, настройте две модели с одинаковыми начальными настройками. Некоторые передатчики имеют функцию копирования настроек для облегчения этой задачи. Как только вы настроили обе модели, делайте изменения (по одной настройке за один раз) в одном из профилей настройки, и затем переключайтесь между двумя профилями во время вождения. Вы должны определить, что эти изменения делают с вашей автомоделью, и принять решение, оставлять ли это изменение или попробовать что-нибудь еще.

● Проект 17: Сервопривод. Крутим потенциометр, меняем положение

Сервопривод (см. рис. 17.1) – устройство, обеспечивающее преобразование сигнала в строго соответствующее этому сигналу перемещение (как правило, поворот) исполнительного устройства. Представляет собой прямоугольную коробку с мотором, схемой и редуктором внутри и выходным валом, который может поворачиваться на строго фиксированный угол, определяемый входным сигналом.
Как правило, этот угол имеет предел в 60 в 180. Кроме этого, еще бывают сервоприводы и постоянного вращения.

Рис. 17.1. Сервопривод

 Сервопривод TowerPro SG90 подключается к Arduino

Сервопривод подключается с помощью трех проводов к управляющему устройству (драйверу или контроллеру) и источнику питания. Сервопривод управляется с помощью импульсов переменной длительности. Угол поворота определяется длительностью импульса, который подается по сигнальному проводу. Это называется широтно-импульсной модуляцией. Сервопривод ожидает импульса каждые 20 мс. Длительность импульса определяет, насколько далеко должен поворачиваться мотор. Например, импульс в 1,5 мс диктует мотору поворот в положение 90° (нейтральное положение). Когда сервопривод получает команду на перемещение, его управляющий орган перемещается в это положение и удерживает его. Если внешняя сила действует на сервопривод, когда он удерживает заданное положение, сервопривод будет сопротивляться перемещению из этого положения. Максимальная величина силы, которую может выдерживать сервопривод, характеризует вращающий момент сервопривода. Однако сервопривод не навсегда удерживает свое положение, импульсы позиционирования должны повторяться, информируя сервопривод о сохранении положения.
В нашем эксперименте мы будем управлять положением сервопривода с помощью потенциометра. Схема подключения сервопривода и потенциометра к плате Arduino показана на рис. 17.2.

Рис. 17.2. Схема подключения сервопривода и потенциометра к Arduino

Cервопривод подключается тремя проводами: питание (Vcc), «земля» (Gnd) и сигнальный (С). Питание– красный провод, он может быть подключен к +5 В внешнего источника питания, черны (или коричневый) провод – «земля» – подключается к GND-выводу Arduino GND, сигнальный (оранжевый/желтый/белый) провод подключается к цифровому выводу контроллера Arduino. Для питания сервопривода используем отдельный блок питания +5 В. Для управления сервоприводом в Arduino имеется стандартная библиотека Servo. На платах, отличных от Mega, использование библиотеки отключает возможность применения analogWrite() (ШИМ) на пинах 9 и 10 (вне зависимости, подключены к этим пинам сервы или нет). На платах Mega до 12 сервоприводов могут использоваться без влияния на функциональность ШИМ, но использование от 12 до 23 сервомашинок отключит PWM ШИМ на пинах 11 и 12.
Аналоговые данные потенциометра (0–1023) масштабируем функцией map() в значения угла поворота сервопривода (0–180) и с помощью библиотечной функции servo.write(angle) даем сервоприводу команду для поворота. Скетч приведен в листинге 17.1.

#include // подключение библиотеки Servo Servo servo1; const int pinServo=8; // Пин для подключения сервопривода const int POT=0; // Аналоговый вход A0 для подключения потенциометра int valpot = 0; // переменная для хранения значения потенциометра int angleServo = 0; // переменная для хранения угла поворота сервы void setup() < // подключить переменную servo к выводу pinServo servo1.attach(pinServo); > void loop() < valpot = analogRead(POT); // чтение данных потенциометра // масштабируем значение к интервалу 0-180 angleServo=map(valpot,0,1023,0,180); // поворот сервопривода на полученный угол servo1.write(angleServo); delay(15); // пауза для ожидания поворота сервопривода >

Порядок подключения:

1. Подключаем датчик сервопривода и потенциометр по схеме на рис. 17.2.
2. Загружаем в плату Arduino скетч из листинга 17.1.
3. Поворотом ручки потенциометра управляем положением сервопривода.

Листинги программ скачать

Repka Pi и управление сервоприводами, ЧАСТЬ 2. Управляем сервоприводами с помощью Robointellect Controller 001 и RISDK

В первой статье серии про сервоприводы с названием Сервоприводы: устройство и управление мы рассказывали о том, для чего нужны сервоприводы, как они устроены, и как ими управлять с помощью ШИМ, приведены характеристики некоторых популярных сервоприводов. Мы написали программу на Python для Repka Pi, позволяющую выполнять необходимые операции над сервоприводами с удержанием угла, а также с сервоприводами постоянного вращения.

С помощью этой, второй статьи серии, вы научитесь пользоваться 16-канальным ШИМ-контроллером Robointellect Controller 001. Данный контроллер создан на базе микросхемы PCA9685 и предназначен для управления различными исполнительными устройствами, использующими ШИМ-модуляцию:

  • светодиоды;
  • сервоприводы;
  • шаговые приводы;
  • реле

Вы узнаете, что этим новым устройством можно работать через порт USB ноутбука или настольного компьютера, и вам не потребуются никакие дополнительные микроконтроллеры или наборы устройств. С другой стороны, мы расскажем, как вместо ноутбука подключить этот контроллер к микрокомпьютеру Repka Pi для управления сервоприводами и светодиодом RGB.

В практической части вы научитесь пользоваться библиотекой RISDK для управления сервоприводами и светодиодами RGB, вызывая ее функции из программ, составленных на языке Python.

Контроллер Robointellect Controller 001 разработан и производится в России. Его можно приобрести на сайте производителя, а также на Озон.

Другие статьи серии про управление сервоприводами вы найдете здесь:

  • Repka Pi и управление сервоприводами, ЧАСТЬ 1. Сервоприводы — устройство и способы управления
  • Repka Pi и управление сервоприводами, ЧАСТЬ 2. Управляем сервоприводами с помощью Robointellect Controller 001 и RISDK — это как раз данная статья
  • Repka Pi и управление сервоприводами, ЧАСТЬ 3. Управляем ШИМ/PWM сервоприводами и светодиодами напрямую с Repka Pi
  • Repka Pi и управление сервоприводами, ЧАСТЬ 4. Прямое управление по I2C ШИМ/PWM сервоприводами и светодиодами с Repka Pi через Robointellect Controller 001 (статья в разработке)
  • Асинхронное управление и контроль потребляемой мощности устройств в Robointellect Controller 001 (статья в разработке)

Как устроен Robointellect Controller 001

Контроллер Robointellect Controller 001 представляет собой очень полезное устройство при создании робототехнических систем и систем автоматизации (рис. 1).

Рис. 1. Контроллер Robointellect Controller 001

Плата контроллера, созданная НПО Робоинтеллект, объединяет сразу четыре устройства:

  • 16-канальный 12-битный контроллер PWM на базе микросхемы PCA9685;
  • SB-I2C конвертер на базе микросхемы CH341T;
  • модуль RGB-светодиода;
  • I2C Hub для подключения дополнительных устройств I2C

Расскажем о возможностях этих устройств в составе Robointellect Controller 001.

Контроллер PWM

На плате Robointellect Controller 001 имеется контроллер ШИМ, созданный на базе микросхемы PCA9685. Если поискать контроллеры на Алиэкспресс по этому названию, то в результатах поиска вам попадется контроллер, показанный на рис. 2.

Рис. 2. Контроллер ШИМ на базе PCA9685

Как видите, здесь есть 16 портов для подключения сервоприводов, отдельные контакты для электропитания, а также контакты для подключения интерфейса I2C.

По сравнению с подобными контроллерами в Robointellect Controller 001 есть такие дополнения:

  • около каждого порта сервопривода находится светодиод, по свечению которого можно судить о наличии управляющих импульсов. Эти светодиоды помогают при отладке программного обеспечения (ПО);
  • есть контакты (пины) для подключения датчика тока, такого как INA219. Этот датчик позволяет контролировать потребление тока сервоприводами;
  • в комплекте с Robointellect Controller 001 поставляется сетевой блок для питания сервоприводов, который можно включить в специально предназначенный для этого разъем. Также имеется разъем для подключения питания с помощью проводов;
  • для Robointellect Controller 001 создана библиотека RISDK, с помощью которой можно управлять оборудованием, подключенным к этому контроллеру, из программ на языках C, C++, Golang, PHP и Python

Конвертер SB-I2C на базе микросхемы CH341T

В то время как управление контроллером, показанным на рис. 2, возможно только с помощью интерфейса I2C, контроллер Robointellect Controller 001 дает вам возможность подключения к управляющему компьютеру через USB. Причем это может быть компьютер под управлением Microsoft Windows или Linux, например, микрокомпьютер Repka Pi.

Управление через USB выполняет микросхема конвертера (моста) SB-I2C, созданная на базе микросхемы CH341T.

Не исключено что вы уже использовали подобные конвертеры, они есть в продаже на Алиэкспресс (рис. 3).

Рис. 3. Конвертер USB для I2C и UART

Наличие подобного конвертера в составе контроллера Robointellect Controller 001 упрощает работу с сервоприводами и другими устройствами. Вы можете разрабатывать ПО управления сервоприводами с помощью обычного ноутбука или настольного компьютера.

Модуль RGB-светодиода

На плате контроллера Robointellect Controller 001 установлен RGB-светодиод, для управления которым используются порты ШИМ с номерами 13, 14 и 15.

Светодиод можно использовать для отладки, а также для индикации состояния каких-либо процессов при работе вашего робота или другого устройства.

I2C Hub для подключения дополнительных устройств I2C

Контроллер Robointellect Controller 001 может быть использован как I2C Hub (расширитель I2C) для подключения дополнительных устройств, в том числе и дополнительных контроллеров Robointellect Controller 001.

Последнее обстоятельство дает возможность управления сотнями сервоприводов при каскадировании контроллеров Robointellect Controller 001.

Кроме этого, сам контроллер Robointellect Controller 001 может управляться через I2C, при этом с помощь набора переключателей можно устанавливать адреса контроллеров на шине I2C.

Установка для Windows

Для управления устройствами, подключенными к Robointellect Controller 001, доступна библиотека RISDK. В этом разделе мы установим ее на компьютер, работающий под управлением ОС Microsoft Windows.

Установка RISDK

Прежде всего, нужно открыть эту страницу и загрузить с нее RISDK для Windows.

В результате вы получите файл robointellect_sdk_windows_amd64.exe (номер версии в имени файла может отличаться). Запустите файл с правами администратора. Для этого щелкните имя файла в папке правой клавишей мыши и выберите в контекстном меню строку Запуск от имени администратора.

Если после запуска появится предупреждение, показанное на рис. 4, щелкните кнопку Подробнее.

Рис. 4. Предупреждение о запуске неопознанного приложения

Вы увидите информацию о запуске программы неизвестного издателя (рис. 5).

Рис. 5. Информация о запускаемой программе

Щелкните в этом окне кнопку Выполнить в любом случае, а затем согласитесь с внесением изменений на вашем устройстве от имени неизвестного приложения, щелкнув кнопку Да.

Вы увидите первое окно мастера установки RoboIntellect (рис. 6).

Рис. 6. Мастер установки RoboIntellect

Продолжите работу мастера при помощи кнопки Далее. Вам будет предложено согласиться с условиями лицензионного соглашения (рис. 7).

Рис. 7. Просмотр условий лицензионного соглашения

Установите отметку для флажка Я принимаю условия соглашения и затем щелкните кнопку Далее.

Вам будет предложено выбрать папку для установки (рис. 8).

Рис. 8. Выбор папки для установки RoboIntellect

Вы можете согласиться с предложенным вариантом или изменить путь к папке, подтвердив выбор кнопкой Далее.

На следующем этапе нужно выбрать компоненты для установки (рис. 9).

Рис. 9. Выбор компонентов для установки

Согласитесь с предложенным выбором, а затем снова щелкните кнопку Далее.

Теперь все готово для установки (рис. 10).

Рис. 10. Подготовка к установке завершена

Чтобы запустить установку, щелкните кнопку Установить и наблюдайте за ходом установки (рис. 11).

Рис. 11. Ход процесса установки RoboIntellect

После завершения установки вам будет предложено открыть руководство пользователя (рис. 12).

Рис. 12. Установка завершена

Далее нужно вручную скопировать файлы из каталога C:\Program Files (x86)\RoboIntellect\ri_sdk\ri_sdk_x64\drivers\x64\ в каталог C:\Windows\System32:

  • CH341DLLA64.dll
  • librisdk.dll
  • libusb-1.0.dll
  • SLABHIDDevice.dll
  • SLABHIDtoSMBus.dll
  • vcruntime140.dll

Для копирования нужны права администратора.

Чтобы не копировать эти файлы, можно добавить путь к каталогу C:\Program Files (x86)\RoboIntellect\ri_sdk\ri_sdk_x64\drivers\x64\ в переменную среды «PATH».

Чтобы это сделать в ОС Microsoft Windows 11, откройте окно Параметры. Далее выберите О системе и Дополнительные параметры системы.

На вкладке Дополнительно щелкните кнопку Переменные среды. В разделе Переменные среды для пользователя найдите переменную PATH и выделите её.

Затем щелкните кнопку Изменить. В открывшемся окне нажмите кнопку Новый и добавьте путь к каталогу C:\Program Files (x86)\RoboIntellect\ri_sdk\ri_sdk_x64\drivers\x64.

И, наконец, щелкните кнопку ОК во всех открытых окнах, чтобы сохранить изменения.

Установка пульта управления роботом-манипулятором

Библиотека RISDK также поставляется в составе ПО пульта управления роботом-манипулятором. Для установки этого ПО нужно открыть страницу и загрузить с нее Пульт управления роботом-манипулятором для Windows.

Установка Python

Установите Python 3.11 или более новой версии с помощью приложения Microsoft Store (рис. 13), если он еще не установлен.

Рис. 13. Установка Python

Далее откройте командное приглашение Microsoft Windows и введите там команду python -V:

C:\Users\1>python -V Python 3.11.4 

На консоль будет выведена версия Python.

Сборка макета

Для подключения контроллера Robointellect Controller 001 к порту USB компьютера вам потребуется кабель USB типа «папа-папа» (рис. 14).

Рис. 14. Кабель USB типа «папа-папа»

Соедините таким кабелем порт USB контроллера с одним из портов вашего ноутбука или настольного компьютера.

Подключите сервоприводы к соответствующим портам контроллера. Обратите внимание, что контакты портов раскрашены в черный, красный и желтый цвета.

Вам нужно подключить сервоприводы аналогично тому, как это показано на рис. 15.

Рис. 15. Подключение сервоприводов к контроллеру Robointellect Controller 001

Здесь коричневый провод подключается к черному контакту, это земля. Для сервопривода постоянного вращения DS4-NFC провод земли черный.

Провода питания должны быть подключены к красным контактам, а управляющие провода — к контактам желтого цвета.

Обратите внимание, что управляющий провод сервопривода постоянного DS4-NFC вращения белый.

Также подключите блок питания, который идет в комплекте с Robointellect Controller 001, к соответствующему разъему на плате контроллера.

Библиотека RISDK

Библиотека RISDK была создана для управления роботом-манипулятором, а также всеми устройствами, подключенными к контроллеру Robointellect Controller 001.

Эта весьма обширная библиотека работает на платформах Microsoft Windows и Linux. Она насчитывает десятки функций, предназначенных для работы с сервоприводами, RGB-светодиодами, адаптером I2C, а также цифровым датчиком тока, напряжения и мощности INA219.

В документации к библиотеке приведены многочисленные примеры программ для следующих языков программирования:

В этой статье мы сосредоточимся на использовании RISDK в программах Python.

Управление RGB светодиодами

Начнем с самого простого — научимся управлять светодиодом RGB, установленным на плате контроллера Robointellect Controller 001, из программы, составленной на языке Python.

Управление светодиодом с помощью функций RISDK

Пример программы risdk_led_sample.py, включающей RGB светодиод на 10 секунд, приведен в листинге 1. Вы также можете найти этот пример в описании функции RI_SDK_exec_RGB_LED_SinglePulse.

import sys from ctypes import * # Подключаем внешнюю библиотеку для работы с SDK lib = cdll.LoadLibrary("C:\Windows\system32\librisdk.dll") # Указываем типы аргументов для функций библиотеки RI_SDK lib.RI_SDK_InitSDK.argtypes = [c_int, c_char_p] lib.RI_SDK_CreateModelComponent.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_int), c_char_p] lib.RI_SDK_LinkPWMToController.argtypes = [c_int, c_int, c_uint8, c_char_p] lib.RI_SDK_LinkLedToController.argtypes = [c_int, c_int, c_int, c_int, c_int, c_char_p] lib.RI_SDK_DestroySDK.argtypes = [c_bool, c_char_p] lib.RI_SDK_exec_RGB_LED_SinglePulse.argtypes = [c_int, c_int, c_int, c_int, c_int, c_bool, c_char_p] def main(): errTextC = create_string_buffer(1000) # Текст ошибки. C type: char* i2c = c_int() pwm = c_int() led = c_int() # Инициализация библиотеки RI SDK с уровнем логирования 3 errCode = lib.RI_SDK_InitSDK(3, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) # Создание компонента i2c адаптера модели ch341 errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "i2c_adapter".encode(), "ch341".encode(), i2c, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) print("i2c: ", i2c.value) # Создание компонента ШИМ модели pca9685 errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "pwm".encode(), "pca9685".encode(), pwm, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) print("pwm: ", pwm.value) # Создание компонента светодиода модели ky016 errCode = lib.RI_SDK_CreateModelComponent("executor".encode(), "led".encode(), "ky016".encode(), led, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) print("led: ", led.value) # Связывание i2c с ШИМ errCode = lib.RI_SDK_LinkPWMToController(pwm, i2c, 0x40, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) # Связывание ШИМ со светодиодом errCode = lib.RI_SDK_LinkLedToController(led, pwm, 15, 14, 13, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) # Непрерывное свечение светодиода красным цветом в течение 10 секунд. # Яркость красного цвета - 150. Яркость остальных цветов - 0. errCode = lib.RI_SDK_exec_RGB_LED_SinglePulse(led, 150, 0, 0, 10000, False, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) # Удаление библиотеки со всеми компонентами errCode = lib.RI_SDK_DestroySDK(True, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) print("Success") main() 

Прежде всего необходимо подключить файл библиотеки librisdk.dll с помощью функции cdll.LoadLibrary:

lib = cdll.LoadLibrary("C:\Windows\system32\librisdk.dll") 

Здесь предполагается, что в процессе установки пульта управления роботом-манипулятором, описанным ранее в этой главе, были скопированы в системный каталог C:\Windows\system32\ все необходимые файлы DLL библиотек.

После загрузки библиотеки с помощью функции RI_SDK_CreateModelComponent программа создает компонент i2c для адаптера ch341, установленного на плате контроллера Robointellect Controller 001:

i2c = c_int() … errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "i2c_adapter".encode(), "ch341".encode(), i2c, errTextC) if errCode != 0: print(errCode, errTextC.raw.decode()) sys.exit(2) print("i2c: ", i2c.value) 

На следующем шаге наша программа создает компонент ШИМ модели pca9685, вызывая ту же функцию RI_SDK_CreateModelComponent:

pwm = c_int() … errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "pwm".encode(), "pca9685".encode(), pwm, errTextC) 

Также требуется создать компонент для GRB светодиода модели ky016, установленного на плате контроллера:

led = c_int() … errCode = lib.RI_SDK_CreateModelComponent("executor".encode(), "led".encode(), "ky016".encode(), led, errTextC) 

После создания компонент для i2c, ШИМ и светодиода нужно связать i2c и ШИМ, а ШИМ — со светодиодом:

errCode = lib.RI_SDK_LinkPWMToController(pwm, i2c, 0x40, errTextC) … errCode = lib.RI_SDK_LinkLedToController(led, pwm, 15, 14, 13, errTextC) 

Для привязки i2c к ШИМ используется функция RI_SDK_LinkPWMToController. Обратите внимание, что в качестве третьего параметра передается адрес ШИМ контроллера на шине i2c, равный 40.

Привязка светодиода выполняется функцией RI_SDK_LinkLedToController. Через третий, четвертый и пятый параметры этой функции нужно передать номера каналов ШИМ на плате контроллера Robointellect Controller 001, к которым подключены, соответственно, красный (R), зеленый (G) и голубой (B) контакт RGB светодиода, соответственно. По умолчанию это каналы 15, 14 и 13.

Обращаем ваше внимание, что на плате Robointellect Controller 001 имеется перемычка ON/OFF RGB LED. Если ее удалить, перечисленные выше каналы будут отключены от встроенного светодиода, и их можно будет использовать для подключения других устройств.

Теперь программа готова для работы со светодиодом. В примере программы с помощью функции RI_SDK_exec_RGB_LED_SinglePulse задается непрерывное свечение светодиода красным цветом в течение 10 секунд:

errCode = lib.RI_SDK_exec_RGB_LED_SinglePulse(led, 150, 0, 0, 10000, False, errTextC) 

Второй, третий и четвертый параметры задают яркости для красного, зеленого и голубого цвета в диапазоне от 0 до 255. В приведенном примере горит только красный свет с яркостью 155.

Пятый параметр задает длительность свечения в мс. В данном случае светодиод будет гореть 10 секунд.

Шестой параметр позволяет запустить выполнение команды в асинхронном режиме. При этом функция сразу вернет управление.

Перед завершением программы нужно удалить библиотеку со всеми компонентами. Это действие выполняется функцией RI_SDK_DestroySDK:

errCode = lib.RI_SDK_DestroySDK(True, errTextC) 

Программа для управления светодиодом RGB в синхронном режиме

Программа risk_led_demo.py, представленная в листинге 2, демонстрирует все функции управления RGB светодиодом, реализованные в RISDK, и работающие в синхронном режиме.

import sys from ctypes import * import platform import traceback def err_msg(errTextC): return(errTextC.raw.decode()) def init(i2c, pwm): platform_os = platform.system() try: if platform_os == "Windows": lib = cdll.LoadLibrary("C:\Windows\system32\librisdk.dll") if platform_os == "Linux": lib = cdll.LoadLibrary("/usr/local/robohand_remote_control/librisdk.so") except OSError as e: raise Exception("Failed to load: " + str(e)) lib.RI_SDK_InitSDK.argtypes = [c_int, c_char_p] lib.RI_SDK_CreateModelComponent.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_int), c_char_p] lib.RI_SDK_LinkPWMToController.argtypes = [c_int, c_int, c_uint8, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_InitSDK(3, errTextC) if errCode != 0: raise Exception(f"RI_SDK_InitSDK failed with error code : ") errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "i2c_adapter".encode(), "ch341".encode(), i2c, errTextC) if errCode != 0: raise Exception(f"RI_SDK_CreateModelComponent failed with error code : ") errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "pwm".encode(), "pca9685".encode(), pwm, errTextC) if errCode != 0: raise Exception(f"RI_SDK_CreateModelComponent failed with error code : ") errCode = lib.RI_SDK_LinkPWMToController(pwm, i2c, 0x40, errTextC) if errCode != 0: raise Exception(f"RI_SDK_LinkPWMToController failed with error code : ") return lib def add_led(lib, led, pwm, r, g, b): lib.RI_SDK_CreateModelComponent.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_int), c_char_p] lib.RI_SDK_LinkLedToController.argtypes = [c_int, c_int, c_int, c_int, c_int, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_CreateModelComponent("executor".encode(), "led".encode(), "ky016".encode(), led, errTextC) if errCode != 0: raise Exception(f"RI_SDK_CreateModelComponent failed with error code : ") errCode = lib.RI_SDK_LinkLedToController(led, pwm, 15, 14, 13, errTextC) if errCode != 0: raise Exception(f"RI_SDK_LinkLedToController failed with error code : ") def cleanup(lib): lib.RI_SDK_DestroySDK.argtypes = [c_bool, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_DestroySDK(True, errTextC) if errCode != 0: raise Exception(f"RI_SDK_DestroySDK failed with error code : ") def led_flicker(lib, led, r, g, b, duration, qty, async_mode): lib.RI_SDK_exec_RGB_LED_Flicker.argtypes = [c_int, c_int, c_int, c_int, c_int, c_int, c_bool, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_exec_RGB_LED_Flicker(led, r, g, b, duration, qty, async_mode, errTextC) if errCode != 0: raise Exception(f"RI_SDK_exec_RGB_LED_Flicker failed with error code : ") def led_pulse(lib, led, r, g, b, duration, async_mode): lib.RI_SDK_exec_RGB_LED_SinglePulse.argtypes = [c_int, c_int, c_int, c_int, c_int, c_bool, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_exec_RGB_LED_SinglePulse(led, r, g, b, duration, async_mode, errTextC) if errCode != 0: raise Exception(f"RI_SDK_exec_RGB_LED_SinglePulse failed with error code : ") def led_pulse_pause(lib, led, r, g, b, duration, pause, limit, async_mode): lib.RI_SDK_exec_RGB_LED_FlashingWithPause.argtypes = [c_int, c_int, c_int, c_int, c_int, c_int, c_int, c_bool, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_exec_RGB_LED_FlashingWithPause(led, r, g, b, duration, pause, limit, async_mode, errTextC) if errCode != 0: raise Exception(f"RI_SDK_exec_RGB_LED_FlashingWithPause failed with error code : ") def led_pulse_frequency(lib, led, r, g, b, frequency, limit, async_mode): lib.RI_SDK_exec_RGB_LED_FlashingWithFrequency.argtypes = [c_int, c_int, c_int, c_int, c_int, c_int, c_bool, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_exec_RGB_LED_FlashingWithFrequency(led, r, g, b, frequency, limit, async_mode, errTextC) if errCode != 0: raise Exception(f"RI_SDK_exec_RGB_LED_FlashingWithFrequency failed with error code : ") def led_cleanup(lib, led): lib.RI_SDK_DestroyComponent.argtypes = [c_int, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_DestroyComponent(led, errTextC) if errCode != 0: raise Exception(f"RI_SDK_DestroyComponent failed with error code : ") if __name__ == "__main__": try: i2c = c_int() pwm = c_int() led = c_int() lib = init(i2c, pwm) # add_led(lib, led, pwm, 15, 14, 13) add_led(lib, led, pwm, 14, 15, 13) print("Start pulse. ") led_pulse(lib, led, 255, 0, 0, 1500, False) led_pulse(lib, led, 0, 255, 0, 1500, False) led_pulse(lib, led, 0, 0, 255, 1500, False) print("Start flicker. ") led_flicker(lib, led, 255, 0, 0, 500, 5, False) led_flicker(lib, led, 0, 255, 0, 500, 5, False) led_flicker(lib, led, 0, 0, 255, 500, 5, False) print("Start pulse_pause. ") led_pulse_pause(lib, led, 255, 0, 0, 1000, 200, 3, False) led_pulse_pause(lib, led, 0, 255, 0, 1000, 200, 3, False) led_pulse_pause(lib, led, 0, 0, 255, 1000, 200, 3, False) print("Start pulse_frequency. ") led_pulse_frequency(lib, led, 255, 0, 0, 10, 10, False) led_pulse_frequency(lib, led, 0, 255, 0, 20, 10, False) led_pulse_frequency(lib, led, 0, 0, 255, 30, 10, False) led_cleanup(lib, led) cleanup(lib) except Exception as e: print(traceback.format_exc() + "===> ", str(e)) sys.exit(2) 

Инициализация

В самом начале этой программы определены переменные i2c и pwm, необходимые для инициализации контроллера Robointellect Controller 001, а также переменная led для работы со светодиодом:

i2c = c_int() pwm = c_int() led = c_int() lib = init(i2c, pwm) 

Инициализация выполняется функцией init, которой передаются переменные i2c и pwm:

def init(i2c, pwm): platform_os = platform.system() try: if platform_os == "Windows": lib = cdll.LoadLibrary("C:\Windows\system32\librisdk.dll") if platform_os == "Linux": lib = cdll.LoadLibrary("/usr/local/robohand_remote_control/librisdk.so") except OSError as e: raise Exception("Failed to load: " + str(e)) lib.RI_SDK_InitSDK.argtypes = [c_int, c_char_p] lib.RI_SDK_CreateModelComponent.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_int), c_char_p] lib.RI_SDK_LinkPWMToController.argtypes = [c_int, c_int, c_uint8, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_InitSDK(3, errTextC) if errCode != 0: raise Exception(f"RI_SDK_InitSDK failed with error code : ") errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "i2c_adapter".encode(), "ch341".encode(), i2c, errTextC) if errCode != 0: raise Exception(f"RI_SDK_CreateModelComponent failed with error code : ") errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "pwm".encode(), "pca9685".encode(), pwm, errTextC) if errCode != 0: raise Exception(f"RI_SDK_CreateModelComponent failed with error code : ") errCode = lib.RI_SDK_LinkPWMToController(pwm, i2c, 0x40, errTextC) if errCode != 0: raise Exception(f"RI_SDK_LinkPWMToController failed with error code : ") return lib 

Для инициализации RISDK вызывается функция RI_SDK_InitSDK. В качестве первого параметра ей передается уровень глубины логирования (0 — только верхний уровень сообщений, 1, 2 и 3 — более подробная трассировка).

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

errTextC = create_string_buffer(1000) 

Заметим, что такая строка используется для записи текста сообщения об ошибке во всех функциях RISDK.

На следующем этапе инициализации вызывается функция RI_SDK_CreateModelComponent, создающие компоненты для моста USB-I2C (микросхема ch341) и PWM-модуляция (микросхема pca9685).

В качестве первого параметра функции RI_SDK_CreateModelComponent нужно передать тип компонента — «executor», «connector» или «sensor». В нашем примере мы указываем тип «connector».

Второй параметр позволяет указать устройство компонента. Это могут быть такие устройства: «i2c», «pwm», «servodrive», «servodrive_rotate», «led» или, «voltage_sensor».

Третий параметр задает модель компонента. В библиотеке RISDK определены компоненты следующих типов:

  • контроллеры ch341, cp2112, pca9685;
  • сервоприводы mg90s, a0090, mg996, corona_ds929mg, corona_sb9039, corona_ds843mg, corona_ds238mg, mg996r;
  • светодиод ky016;
  • измеритель тока ina219

В четвертом параметре нужно указать ссылку на переменную, в которую будет записан объект созданного компонента.

Наша функция init вызывает функцию RI_SDK_CreateModelComponent три раза, создавая компоненты для моста ch341, а также контроллеров ch341 и pca9685.

И, наконец, через последний параметр нужно передать ссылку на буфер для записи сообщения об ошибке.

Последний этап инициализации заключается в присоединении ШИМ-модулятора к адаптеру i2c с помощью функции RI_SDK_LinkPWMToController библиотеки RISDK.

Через первый и второй параметры этой функции нужно передать дескрипторы ШИМ и адаптера i2c, участвующие в присоединении.

Третий параметр задает адрес адаптера на шине i2c.

Последний параметр предназначен для получения текста ошибки (если она возникнет).

Добавление светодиода

Прежде чем программа сможет работать со светодиодом RGB, она должна добавить его к контроллеру, указав тип светодиода и номера каналов ШИМ на плате контроллера Robointellect Controller 001, к которому подключен светодиод.

Ниже приведен код функции add_led, выполняющий операцию добавления:

def add_led(lib, led, pwm, r, g, b): lib.RI_SDK_CreateModelComponent.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_int), c_char_p] lib.RI_SDK_LinkLedToController.argtypes = [c_int, c_int, c_int, c_int, c_int, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_CreateModelComponent("executor".encode(), "led".encode(), "ky016".encode(), led, errTextC) if errCode != 0: raise Exception(f"RI_SDK_CreateModelComponent failed with error code : ") errCode = lib.RI_SDK_LinkLedToController(led, pwm, r, g, b, errTextC) if errCode != 0: raise Exception(f"RI_SDK_LinkLedToController failed with error code : ") 

Эта функция создает компонент светодиода функцией RI_SDK_CreateModelComponent, а затем подключает этот компонент к контроллеру, вызывая RI_SDK_LinkLedToController.

Через первый и второй параметры функции передаются соответственно дескриптор светодиода и контроллера ШИМ, созданные на этапе инициализации.

Следующие параметры задают порты подключения на шине ШИМ контроллера красного, зеленого и синего светодиодов (установленных внутри светодиода RGB), соответственно.

Последний параметр нужен для передачи текста ошибки.

Наша программа добавляет светодиод следующим образом:

# add_led(lib, led, pwm, 15, 14, 13) add_led(lib, led, pwm, 14, 15, 13) 

Обратите внимание, что вместо последовательности (15,14, 13) здесь указано (14, 15, 13). В экземпляре контроллера, который был у автора этой статьи, в светодиоде RGB оказались перепутаны контакты. Поэтому пришлось при добавлении светодиода сделать коррекцию.

Операции со светодиодом

Когда светодиод добавлен, можно с ним работать. Сначала программа вызывает функцию led_pulse, включающую светодиод с помощью функции RI_SDK_exec_RGB_LED_SinglePulse библиотеки RISDK:

led_pulse(lib, led, 255, 0, 0, 1500, False) led_pulse(lib, led, 0, 255, 0, 1500, False) led_pulse(lib, led, 0, 0, 255, 1500, False) 

Здесь программа последовательно зажигает светодиод красным, зеленым и голубым цветом на полторы секунды.

Код функции led_pulse приведен ниже:

def led_pulse(lib, led, r, g, b, duration, async_mode): lib.RI_SDK_exec_RGB_LED_SinglePulse.argtypes = [c_int, c_int, c_int, c_int, c_int, c_bool, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_exec_RGB_LED_SinglePulse(led, r, g, b, duration, async_mode, errTextC) if errCode != 0: raise Exception(f"RI_SDK_exec_RGB_LED_SinglePulse failed with error code : ") 

Через первый параметр функции RI_SDK_exec_RGB_LED_SinglePulse передается дескриптор светодиода, полученный от функции add_led.

Второй, третий и четвертый параметр задают яркость для красного, зеленого и голубого каналов светодиода, соответственно. Можно указывать значения в диапазоне от 0 до 255.

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

В синхронном режиме вызывающая программа ожидает завершение выполнения команды, запущенной функцией.

В асинхронном режиме ожидания не происходит, и функция сразу возвращает управление. Команда выполняется одновременно с дальнейшей работой программы.

После вызова led_pulse программа вызывает еще три функции:

led_flicker(lib, led, 255, 0, 0, 500, 5, False) led_flicker(lib, led, 0, 255, 0, 500, 5, False) led_flicker(lib, led, 0, 0, 255, 500, 5, False) led_pulse_pause(lib, led, 255, 0, 0, 1000, 200, 3, False) led_pulse_pause(lib, led, 0, 255, 0, 1000, 200, 3, False) led_pulse_pause(lib, led, 0, 0, 255, 1000, 200, 3, False) led_pulse_frequency(lib, led, 255, 0, 0, 10, 10, False) led_pulse_frequency(lib, led, 0, 255, 0, 20, 10, False) led_pulse_frequency(lib, led, 0, 0, 255, 30, 10, False) 

Функция led_flicker реализована с помощью функции RI_SDK_exec_RGB_LED_Flicker и вызывает мерцание светодиода и постепенным изменением яркости от нулевой до значения, указанного третьим, четвертым и пятым параметрами.

Шестой параметр задает длительность мерцания в мс, а седьмой — количество мерцаний.

Таким образом, приведенный выше фрагмент кода с функцией led_flicker вызывает последовательное мерцание светодиода красным, зеленым и голубым цветом.

Функция led_pulse_pause реализована при помощи функции RI_SDK_exec_RGB_LED_FlashingWithPause.

Здесь светодиод мигает цветом, заданным при помощи третьего, четвертого и пятого параметров. Шестой параметр задает длительность одного импульса в мс, седьмой — паузу между импульсами в мс, а восьмой — количество миганий.

Если нужно мигать светодиодом с заданной частотой, используйте функцию led_pulse_frequency, реализованную с помощью RI_SDK_exec_RGB_LED_FlashingWithFrequency.

Третий, четвертый и пятый параметры задают цвет мигания, шестой — частоту мигания в Гц, а седьмой — количество миганий.

Последние параметры всех перечисленных функций позволяют указать необходимость работы в синхронном или асинхронном режиме.

Освобождение ресурсов

Перед завершением работы программа должна освободить ресурсы, занятые светодиодом и библиотекой RISDK. Для этого она вызывает функции led_cleanup и cleanup:

led_cleanup(lib, led) cleanup(lib 

Функция led_cleanup вызывает функцию RI_SDK_DestroyComponent библиотеки RISDK. Она удаляет компонент, созданный для светодиода RGB.

Что касается функции cleanup, то она вызывает функции RI_SDK_sigmod_PWM_ResetAll, RI_SDK_DestroyComponent и RI_SDK_DestroySDK.

Функция RI_SDK_sigmod_PWM_ResetAll устанавливает скважность, равную нулю на всех портах ШИМ модулятора. С помощью функции RI_SDK_DestroyComponent удаляется компонент i2c. И, наконец, функция RI_SDK_DestroySDK освобождает память, выделенную RISDK.

Асинхронное управление светодиодом

Библиотека RISDK может работать в асинхронном режиме. При этом асинхронные функции возвращают управление в вызывающую программу немедленно, а вызванный ими процесс будет продолжен до завершения или отмены.

В листинге 3 мы привели в сокращенном виде пример программы risdk_led_demo_async.py асинхронного управления светодиодом RGB.

… if __name__ == "__main__": try: i2c = c_int() pwm = c_int() led = c_int() lib = init(i2c, pwm) # add_led(lib, led, pwm, 15, 14, 13) add_led(lib, led, pwm, 14, 15, 13) print_led_state(lib, led) print("Start pulse. ") led_pulse(lib, led, 255, 0, 0, 1500, True) time.sleep(0.3) print_led_state(lib, led) time.sleep(2) led_pulse(lib, led, 0, 255, 0, 1500, True) time.sleep(0.3) print_led_state(lib, led) time.sleep(2) led_pulse(lib, led, 0, 0, 255, 1500, True) time.sleep(0.3) print_led_state(lib, led) time.sleep(2) print("Start flicker. ") led_flicker(lib, led, 255, 0, 0, 500, 5, True) time.sleep(2) led_flicker(lib, led, 0, 255, 0, 500, 5, True) time.sleep(2) led_flicker(lib, led, 0, 0, 255, 500, 5, True) time.sleep(2) print("Start pulse_pause. ") led_pulse_pause(lib, led, 255, 0, 0, 1000, 200, 3, True) time.sleep(2) led_pulse_pause(lib, led, 0, 255, 0, 1000, 200, 3, True) time.sleep(2) led_pulse_pause(lib, led, 0, 0, 255, 1000, 200, 3, True) time.sleep(2) print("Start pulse_frequency. ") led_pulse_frequency(lib, led, 255, 0, 0, 10, 10, True) time.sleep(2) led_pulse_frequency(lib, led, 0, 255, 0, 10, 10, True) time.sleep(2) led_pulse_frequency(lib, led, 0, 0, 255, 10, 10, True) time.sleep(2) led_stop(lib) led_cleanup(lib, led) cleanup(lib) except Exception as e: print(traceback.format_exc() + "===> ", str(e)) sys.exit(2) 

Обратите внимание, что в качестве последнего параметра мы передаем функциям, управляющим светодиодом, значение True, а не False, как это было в предыдущем примере (листинг 2). В результате все функции RISDK вызываются в асинхронном режиме.

После вызова метода led_pulse добавлены две задержки. Первая вызывается перед функцией print_led_state, которая выводит на консоль состояние светодиода, а вторая — после вывода этого состояния.

Если бы задержек не было, то программа завершила свою работу очень быстро и вы бы не заметили миганий светодиода. Задержки фактически превращают программу в синхронную, так как с их помощью программа останавливается, пока выполняются действия со светодиодом.

Для получения состояния и текущих компонентов цвета светодиода RGB здесь вызывается функция led_get_state, основанная на вызове функции RI_SDK_exec_RGB_LED_GetState библиотеки RISDK.

Функция RI_SDK_exec_RGB_LED_GetState записывает в переменную, адрес которой указан во втором параметре, код состояния для светодиода, дескриптор которого указан в первом параметре.

Возможны такие значения состояния:

  • 0 — компонент ожидает вызова действий, светодиод не выполняет никакую команду;
  • 1 — компонент выполняет действие;
  • 2 — простое свечение, светодиод выполняет команду простого свечения;
  • 3 — мигание, светодиод выполняет одну из 2-х команд мигания;
  • 4 — мерцание, светодиод выполняет команду мерцания

Текущий цвет светодиода возвращается функцией led_get_color, которая, в свою очередь, вызывает функцию RI_SDK_exec_RGB_LED_GetColor библиотеки RISDK.

Также обратите внимание на функцию led_stop, полезную в асинхронном режиме и останавливающую выполнение текущей операции для светодиода. Она вызывает функцию RI_SDK_exec_RGB_LED_Stop.

Управление сервоприводами с удержанием угла

Для управления сервоприводами с удержанием угла была создана программа risdk_servo_mg90s.py. Исходный текст этой программы приведен в листинге 4 (в сокращенном виде).

… i2c = c_int() pwm = c_int() mg90s = c_int() lib = init(i2c, pwm) servo_add(lib, pwm, mg90s, "mg90s", 0) print_servo_state(lib, mg90s) print("\nMG90S поворот в крайние положения") servo_rotate(lib, mg90s, 0, 200, False) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) print_servo_state(lib, mg90s) servo_rotate(lib, mg90s, 1, 200, False) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_set_middle(lib, mg90s) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) print("\nMG90S управление через длительность импульсов") servo_turn_by_pulse(lib, mg90s, 2650) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_turn_by_pulse(lib, mg90s, 365) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_turn_by_pulse(lib, mg90s,1500) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) print("\nMG90S Минимальный шаг") servo_set_middle(lib, mg90s) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_rotate_min_step(lib, mg90s, 1, 100, False) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_rotate_min_step(lib, mg90s, 0, 100, False) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) print("\nMG90S управление через Duty") servo_turn_by_duty(lib, mg90s, 75) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_turn_by_duty(lib, mg90s, 300) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_turn_by_duty(lib, mg90s, 540) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) print("\nMG90S поворот на заданный угол") servo_set_middle(lib, mg90s) time.sleep(2) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_turn_by_angle(lib, mg90s, 90, 200, False) time.sleep(1) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) servo_turn_by_angle(lib, mg90s, -90, 300, False) time.sleep(1) print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) cleanup_servo(lib, mg90s) cleanup(lib) … 

Инициализация

На этапе инициализации с помощью функции init программа risdk_servo_mg90s.py создает переменные i2c, pwm и mg90s:

i2c = c_int() pwm = c_int() mg90s = c_int() lib = init(i2c, pwm) 

Работа этой функции уже была описана ранее в предыдущем разделе (листинге 2).

Добавление сервопривода

Для работы с сервоприводом его нужно добавить функцией servo_add:

servo_add(lib, pwm, mg90s, "mg90s", 0) 

В качестве третьего параметра функции servo_add нужно передать переменную для сохранения дескриптора сервопривода, в качестве четвертого — имя модели сервопривода, а в качестве пятого — номер канала ШИМ контроллера Robointellect Controller 001, к которому подключен сервопривод.

Функция servo_add вначале вызывает функцию RI_SDK_CreateModelComponent для создания компонента уровня устройства, а затем — функцию RI_SDK_LinkServodriveToController для привязки контроллера к ШИМ модулятору:

def servo_add(lib, pwm, servo, servo_type, channel): lib.RI_SDK_CreateModelComponent.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_int), c_char_p] lib.RI_SDK_LinkPWMToController.argtypes = [c_int, c_int, c_uint8, c_char_p] errTextC = create_string_buffer(1000) errCode = lib.RI_SDK_CreateModelComponent("executor".encode(), "servodrive".encode(), servo_type.encode(), servo, errTextC) if errCode != 0: raise Exception(f"RI_SDK_CreateModelComponent failed with error code : ") errCode = lib.RI_SDK_LinkServodriveToController(servo, pwm, channel, errTextC) if errCode != 0: raise Exception(f"RI_SDK_LinkServodriveToController failed with error code : ") 

Определение текущего состояния сервопривода

После добавления сервопривода программа вызывает функцию print_servo_state чтобы вывести на консоль состояние сервопривода:

print_servo_state(lib, mg90s) 

Функция print_servo_state определена так:

def print_servo_state(lib, servo): print(f"Servo state: : ") 

Она получает состояние с помощью функции servo_get_state. Эта функция, в свою очередь, вызывает функцию RI_SDK_exec_ServoDrive_GetState.

Функция RI_SDK_exec_ServoDrive_GetState может вернуть одно из двух значений:

  • 0 — сервопривод ожидает вызова действий, ничего не делает и готов к работе;
  • 1 — компонент выполняет действие. Сервопривод в данный момент осуществляет движение

Таким образом, если функция servo_get_state возвращает нулевое значение, сервопривод находится в состоянии ожидания, если же значение единицы — вал сервопривода находится в движении.

Поворот в крайние положения

В программе risdk_servo_mg90s.py есть функция servo_rotate для поворота вала сервопривода в крайние положения, а также функция servo_set_middle для установки вала в среднее положение:

servo_rotate(lib, mg90s, 0, 200, False) servo_rotate(lib, mg90s, 1, 200, False) servo_set_middle(lib, mg90s) 

Функции servo_rotate, реализованная с помощью функции RI_SDK_exec_ServoDrive_Rotate, в качестве первого параметра нужно передать направление вращения. Значение 0 соответствует вращению по часовой стрелке, а значение 1 — против часовой стрелки.

Второй параметр функции servo_rotate задает угловую скорость поворота (градусы в секунду).

Функция servo_set_middle работает с помощью функции RI_SDK_exec_ServoDrive_SetPositionToMidWorkingRange. Она устанавливает вал сервопривода в среднее положение (в середину рабочего диапазона углов поворота).

Определение текущего угла поворота

При выполнении операций с сервоприводом программа risdk_servo_mg90s.py после выполнения тех или иных операций выводит на консоль текущий угол поворота вала сервопривода:

print("mg90s angle: " + str(servo_get_angle(lib, mg90s))) 

Текущий угол поворота определяется функцией servo_get_angle, вызывающей функцию RI_SDK_exec_ServoDrive_GetCurrentAngle библиотеки RISDK. Это значение вычисляется на основе подсчета управляющих импульсов.

Перед измерением угла поворота добавлена задержка, чтобы сервопривод успел выполнить команду.

Управление через длительность импульсов

Функция servo_turn_by_pulse позволяет управлять вращением вала сервопривода, задавая длительность управляющих импульсов в мс:

servo_turn_by_pulse(lib, mg90s, 2650) servo_turn_by_pulse(lib, mg90s, 365) servo_turn_by_pulse(lib, mg90s, 1500) 

Длительность передается этим функциям в качестве последнего параметра.

Функция servo_turn_by_pulse вызывает функцию RI_SDK_exec_ServoDrive_TurnByPulse библиотеки RISDK. В качестве первого параметра этой функции передается дескриптор сервопривода, в качестве второго — необходимая длительность импульсов, а в качестве третьего — ссылка на буфер для записи строки сообщения об ошибке.

Управление через минимальный шаг

Если нужно перемещать вал сервопривода минимальными шагами, по одному градусу, пригодится функция servo_rotate_min_step, созданная на базе функции RI_SDK_exec_ServoDrive_MinStepRotate.

Фрагмент программы, приведенный ниже, вначале устанавливает вал сервопривода в среднее положение, а затем поворачивает его на один градус сначала по часовой стрелке, а затем — против часовой стрелке:

servo_set_middle(lib, mg90s) servo_rotate_min_step(lib, mg90s, 1, 100, False) servo_rotate_min_step(lib, mg90s, 0, 100, False) 

Угловая скорость поворота задана как 100⁰ в секунду.

В качестве первого параметра функции RI_SDK_exec_ServoDrive_MinStepRotate нужно передать дескриптор сервопривода.

Второй и третий параметры задают, соответственно, направление и угловую скорость поворота (градусы в секунду).

Направление движения задается так:

  • 0 — по часовой стрелке;
  • 1 — против часовой стрелки

Управление через скважность импульсов Duty

Функция servo_turn_by_duty, реализованная с помощью функции библиотеки RISDK RI_SDK_exec_ServoDrive_TurnByDutyCycle, позволяет задавать угол поворота вала сервопривода через скважность управляющих импульсов:

servo_turn_by_duty(lib, mg90s, 75) servo_turn_by_duty(lib, mg90s, 300) servo_turn_by_duty(lib, mg90s, 540) 

В качестве третьего параметра этой функции нужно передать количество шагов для ШИМ преобразователя.

Поворот на заданный угол

Функция servo_turn_by_angle позволяет поворачивать вал сервопривода на заданный угол по часовой стрелке или против часовой стрелке. Она вызывает функцию RI_SDK_exec_ServoDrive_Turn библиотеки RISDK.

Ниже приведен фрагмент программы, который вначале устанавливает вал сервопривода в среднее положение, а затем поворачивает его почасовой стрелке на 90⁰ и вслед за этим против часовой стрелки на -90⁰:

servo_set_middle(lib, mg90s) servo_turn_by_angle(lib, mg90s, 90, 200, False) servo_turn_by_angle(lib, mg90s, -90, 300, False) 

Освобождение ресурсов

Перед завершением своей работы программа освобождает ресурсы, выделенные для сервопривода и для библиотеки RISDK:

cleanup_servo(lib, mg90s) cleanup(lib) 

Функция cleanup_servo вызывает функцию RI_SDK_DestroyComponent библиотеки RISDK для освобождения ресурсов, выделенных сервоприводу. Дескриптор сервопривода передается этой функции в качестве первого параметра.

Функция cleanup обращается к функции RI_SDK_DestroySDK, передавая ей в качестве первого параметра значение True для полного очищения реестра.

Подключение нестандартного сервопривода

Библиотека RISDK позволяет вам работать с нестандартными сервоприводами, названия и параметры которых не определены в этой библиотеке.

В листинге 5 показана в сокращенном виде программа risdk_servo_sg90.py, которая демонстрирует такую поддержку для широко распространенного и недорогого сервопривода SG90.

Отличия от предыдущей программы (листинг 4) есть при инициализации, а также в параметрах для функций, выполняющих поворот вала по длительности управляющего импульса и через скважность.

Инициализация выполняется функцией add_custom_servo:

sg90 = add_custom_servo(lib, pwm, sg90, 2350, 365, 200, 180, 0) 

Параметры нестандартного сервопривода передаются функции RI_SDK_exec_ServoDrive_CustomDeviceInit.

Через первый параметр функция RI_SDK_exec_ServoDrive_CustomDeviceInit получает указатель на переменную, в которую будет записан дескриптор нестандартного сервопривода после инициализации.

В качестве второго и третьего параметров передаются максимальная и минимальная длительности управляющих импульсов в мс, соответственно.

Диапазон изменения длительности вы можете узнать из документации на сервопривод или определить в процессе его калибровки.

Четвертый параметр задает максимально допустимую угловую скорость вращения сервопривода (градусы в секунду).

Пятый параметр определяет максимальный угол поворота вала сервопривода в градусах.

И, наконец, в шестом параметре необходимо указать номер канала ШИМ контроллера Robointellect Controller 001, к которому подключен сервопривод.

Ниже мы привели в сокращенном виде фрагмент программы, выполняющий повороты вала сервопривода в крайние положения, и управляющие сервоприводом через длительность импульсов:

servo_rotate(lib, sg90, 0, 200, False) servo_rotate(lib, sg90, 1, 200, False) servo_set_middle(lib, sg90) servo_turn_by_pulse(lib, sg90, 2350) servo_turn_by_pulse(lib, sg90, 365) servo_turn_by_pulse(lib, sg90,1500) 

Управление сервоприводами постоянного вращения

В библиотеке RISDK имеются функции, предназначенные для управления стандартными и нестандартными сервоприводами постоянного вращения.

Стандартные сервоприводы

В листинге 6 вы найдете в сокращенном виде код программы управления сервоприводом постоянного вращения risdk_servo_mg996r.py.

… i2c = c_int() pwm = c_int() mg996r = c_int() lib = init(i2c, pwm) rservo_add(lib, pwm, mg996r,"mg996r", 0) print_rservo_state(lib, mg996r) rservo_rotate_by_pulse(lib, mg996r, 1050, True) print_rservo_state(lib, mg996r) time.sleep(3) rservo_rotate_by_pulse(lib, mg996r, 2100, True) print_rservo_state(lib, mg996r) time.sleep(3) rservo_rotate_by_pulse(lib, mg996r, 1570, True) print_rservo_state(lib, mg996r) time.sleep(3) rservo_rotate_at_speed(lib, mg996r, 0, 50, True) time.sleep(3) rservo_rotate_at_speed(lib, mg996r, 1, 100, True) time.sleep(3) stop_rservo(lib, mg996r) print_rservo_state(lib, mg996r) cleanup_servo(lib, mg996r) cleanup(lib) 

После инициализации функцией init программа добавляет сервопривод постоянного вращения с помощью функции rservo_add . Она вызывает функции RI_SDK_CreateModelComponent и RI_SDK_LinkRServodriveToController.

Чтобы добавить сервопривод вращения типа mg996r программа вызывает функцию rservo_add:

rservo_add(lib, pwm, mg996r,"mg996r", 0) 

Дескриптор добавленного сервопривода добавляется в переменную, ссылка на которую передается через третий параметр.

В качестве четвертого параметра функции передается тип сервопривода, а в качестве пятого — номер порта ШИМ контроллера Robointellect Controller 001, к которому подключен этот сервопривод.

Для управления скоростью и направлением вращения вала сервопривода используется функция rservo_rotate_by_pulse, вызывающий функцию RI_SDK_exec_RServoDrive_RotateByPulse библиотеки RISDK:

rservo_rotate_by_pulse(lib, mg996r, 1050, True) rservo_rotate_by_pulse(lib, mg996r, 2100, True) rservo_rotate_by_pulse(lib, mg996r, 1570, True) 

В качестве третьего параметра методу передается длительность управляющего импульса в мс.

Обратите внимание, что функция RI_SDK_exec_RServoDrive_RotateByPulse библиотеки RISDK запускает вращение вала, и оно не остановится д выдачи новой команды или до остановки сервопривода. Поэтому этот метод пригоден только для асинхронного режима.

Чтобы включить асинхронные режим, программа risdk_servo_mg996r.py передает значение True функции rservo_rotate_by_pulse.

Также обратите внимание на использование функции print_rservo_state, которая выводит на консоль текущее состояние серводвигателя. Она вызывает функцию RI_SDK_exec_RServoDrive_GetState, возвращающую одно из двух значений:

  • 0 — сервопривод ожидает вызова действий, ничего не делает и готов к работе;
  • 1 — компонент выполняет действие. Сервопривод в данный момент осуществляет движение

Функция rservo_rotate_at_speed, основанная на вызове функции библиотеки RISDK с именем RI_SDK_exec_RServoDrive_RotateWithRelativeSpeed, позволяет запустить вращение вала сервопривода в заданном направлении и с заданной скоростью:

rservo_rotate_at_speed(lib, mg996r, 0, 50, True) rservo_rotate_at_speed(lib, mg996r, 1, 100, True) 

Третий параметр функции rservo_rotate_at_speed задает направление вращения. Нулевое значение соответствует вращению по часовой стрелке, значение единицы — вращению против часовой стрелки.

Четвертый параметр задает скорость вращения в процентах от максимальной.

Для остановки вала сервопривода вызывается функция stop_rservo:

stop_rservo(lib, mg996r) 

Она обращается к функции RI_SDK_exec_RServoDrive_Stop библиотеки RISDK.

Синхронные функции для сервоприводов вращения

В листинге 7 приведен код программы risdk_servo_mg996r_sync.py (в сокращенном виде), управляющая сервоприводами вращения в синхронном режиме.

… rservo_rotate_by_pulse_over_time(lib, mg996r, 1050, 2000, False) rservo_rotate_by_pulse_over_time(lib, mg996r, 2100, 2000, False) rservo_rotate_by_pulse_over_time(lib, mg996r, 1570, 2000, False) rservo_rotate_at_speed_over_time(lib, mg996r, 0, 50, 2000, False) rservo_rotate_at_speed_over_time(lib, mg996r, 1, 100, 2000, False) … 

Эта программа вызывает функции rservo_rotate_by_pulse_over_time и rservo_rotate_at_speed_over_time, аналогичные по назначению только что рассмотренным функциям rservo_rotate_by_pulse и rservo_rotate_at_speed.

Отличие в том, что они вызывают функции RI_SDK_exec_RServoDrive_RotateByPulseOverTime и RI_SDK_exec_RServoDrive_RotateWithRelativeSpeedOverTime. Обе эти функции позволяют указать длительность вращения в мс. Вал сервопривода будет остановлен после истечения указанного времени, что можно использовать в синхронных программах.

Нестандартные сервоприводы

При необходимости вы можете управлять с помощью библиотеки RISDK нестандартными сервоприводами непрерывного вращения, параметры которых не определены в этой библиотеке.

Пример программы risdk_servo_ds04-nfs.py, подключающей сервопривод DS04-NFS, показан в листинге 8 (в сокращенном виде).

… i2c = c_int() pwm = c_int() ds04_fns = c_int() lib = init(i2c, pwm) ds04_fns = add_custom_rservo(lib, pwm, 1050, 2100, 1050, 2100, 0) print_rservo_state(lib, ds04_fns) rservo_rotate_by_pulse(lib, ds04_fns, 1050, True) print_rservo_state(lib, ds04_fns) time.sleep(3) rservo_rotate_by_pulse(lib, ds04_fns, 2100, True) print_rservo_state(lib, ds04_fns) time.sleep(3) rservo_rotate_by_pulse(lib, ds04_fns, 1570, True) print_rservo_state(lib, ds04_fns) time.sleep(3) rservo_rotate_at_speed(lib, ds04_fns, 0, 50, True) time.sleep(3) rservo_rotate_at_speed(lib, ds04_fns, 1, 100, True) time.sleep(3) stop_rservo(lib, ds04_fns) print_rservo_state(lib, ds04_fns) cleanup_servo(lib, ds04_fns) cleanup(lib) 

Добавление сервопривода осуществляется функцией add_custom_rservo:

ds04_fns = add_custom_rservo(lib, pwm, 1050, 2100, 1050, 2100, 0) 

Здесь в качестве третьего и четвертого параметров функции add_custom_rservo передаются минимальная и максимальная длительность управляющих импульсов для поворота вала сервопривода по часовой стрелке.

Пятый и шестой параметры определяет минимальную и максимальную длительность импульсов для поворота вала против часовой стрелке.

И, наконец, седьмой параметр задает номер канала ШИМ контроллера Robointellect Controller 001, к которому подключен сервопривод.

Напомним, что, если подать управляющие импульсы длительностью 1 мс, вал сервопривода DS04-NFS будет вращаться с полной скоростью в направлении против часовой стрелки.

Импульсы длительностью 2 мс вызовут вращение вала сервопривода с полной скоростью в направлении по часовой стрелке.

И, наконец, для того чтобы остановить вращение вала, нужно подать на его управляющий контакт импульсы длительностью 1.5 мс.

Промежуточные значения длительности импульсов от 1 мс до 1.5 мс и от 1.5 мс до 2 мс можно использовать для управления скоростью вращения вала.

Установка RISDK для Repka OS на микрокомпьютере Repka Pi

До сих пор мы работали с контроллером Robointellect Controller 001, подключив его через USB к ноутбуку или настольному компьютеру с ОС Microsoft Windows. Теперь подключите его к Repka Pi, на которой установлена Repka OS (рис. 16).

Рис. 16. Подключение контроллера Robointellect Controller 001 к Repka Pi

Также подключите к контроллеру сервоприводы.

Загрузите Repka OS и с помощью команды lsusb проверьте, что в системе определяется контроллер QinHeng Electronics CH341, установленный на плате Robointellect Controller 001:

# lsusb Bus 008 Device 002: ID 1a86:5512 QinHeng Electronics CH341 in EPP/MEM/I2C mode, EPP/I2C adapter Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 

Если подключение через USB выполнено правильно и контроллер CH341 виден, продолжайте установку.

Вам нужно открыть страницу и скачать файл установки robointellect_sdk_linux_arm64.deb (рис. 17).

Рис. 17. Скачивание файла установки пульта управления

Скачайте файл robointellect_sdk_linux_arm64.deb:

# wget --no-check-certificate https://download.robointellect.ru/robointellect_sdk_linux_arm64.deb 

Далее установите необходимые пакеты:

# apt install gcc libgtk-3-0 libayatana-appindicator3-1 make i2c-tools dkms python3 

После установки сделайте текущим каталог, в который был загружен файл robointellect_sdk_linux_arm64.deb и установите его следующим образом:

# dpkg -i robointellect_sdk_linux_arm64.deb 

Через некоторое время на консоли появится запрос подтверждения установки драйвера:

… /lib/systemd/system/ri_translator.service. Хотите ли установить драйвер для CH341 y/n 

Подтвердите установку, для чего введите символ «y» с клавиатуры.

Проверьте, что после установки появился файл библиотеки RISDK /usr/local/robointellect_sdk/ri_sdk/librisdk.so.

Далее установите репозиторий с классами RiController, RiServo, RiRotateServo, RiLed и примеров программ на Python:

# git clone https://github.com/AlexandreFrolov/ri-controller-001-risdk 

После установки библиотеки RISDK в Repka OS испытайте работу всех приведенных в этом репозитории программ.

Итоги

Из этой статьи вы узнали о том, как устроен контроллер Robointellect Controller 001, плата которого объединяет сразу четыре устройства. Вы научились управлять серводвигателями с удержанием угла, серводвигателями постоянного вращения, подключенными к контроллеру, а также светодиодом RGB, установленным на плате контроллера.

Вы изучили библиотеку RISDK и научились работать с ней из программ, составленных на языке Python.

Примеры программ вы запускали на компьютере с Microsoft Windows, а также на микрокомпьютере Repka Pi с установленной Repka OS. В обоих случаях контроллер Robointellect Controller 001 был подключен через USB.

Также приводим ссылки на ресурсы проекта Repka Pi:

  • Официальный сайт проекта Repka Pi и там же куча дополнительной информации, прошивки, чертежи, исходники, бинарники DT, блог и что важно — интернет-магазин с ценами на все комплектации Репки ощутимо ниже, чем на маркетплейсах.
  • Официальный Телеграм канал проекта Repka Pi.
  • Группа обсуждения и комментариев к постам официального канала в Телеграм проекта Repka Pi — там можно задать актуальные вопросы и пообщаться с единомышленниками, которые тоже увлекаются одноплатными компьютерами вообще и Репкой в частности.
  • Официальное сообщество в ВК компании разработчика, где периодически появляются новости проектов разработчика проекта, в том числе и Репки.
  • Предыдущая статья серии статей про сервоприводы, где было рассказано о том, как устроены сервоприводы, какими они бывают, и как управлять сервоприводами с помощью импульсных генераторов, а также через микрокомпьютер Repka Pi
  • Сервопривод цифровой A0090 9g — Купить
  • Сервопривод MG90S Micro Servo, 2 шт. — Купить
  • Сервопривод MG90S Micro Servo, 4 шт. — Купить
  • RoboIntellect controller m1 — Купить
  • Конструктор RoboIntellect RM001 — Купить
  • Конструктор Робот Вертер — Купить

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *