Опубликовано

Ходовая часть мобильных роботов

По материалам книги “Мобильные роботы на базе Arduino, 3-е изд.“, 3-е изд. (автор Михаил Момот) (глава 5. Ходовая часть)

Мобильные роботы на базе Arduino, 3-е изд.

Выбор двигателей

Итак, когда структура ходовой части выбрана, следует определить, какие двигатели будет использовать наш робот. На выбор: коллекторные двигатели постоянного тока с редуктором, сервопривод MG995 3600 постоянного вращения (скорость вращения задается сигналом на входе управления), шаговые двигатели. Их параметры представлены в табл. 5.1.

Таблица 5.1. Сравнительные параметры различных типов двигателей

Сравниваемые параметры Двигатель
постоянного тока с понижающим редуктором
Сервопривод MG995 3600 Шаговый
двигатель
Количество задействованных портов микроконтроллера для управления 2–3 1 2–3
Скорость реакции на поступившую команду, сек (чем больше, тем хуже) ~1/100 ~1/50 ~1/1000
Скорость вращения (с учетом понижающего редуктора), об/мин 10–240 1–60 0,1–300
Стоимость (за единицу принята стоимость двигателя постоянного тока с редуктором), сравниваются двигатели, равные по мощности 1 4 6
Минимальное количество портов управления ходовой частью для проекта колесного робота с двумя ведущими колесами 4 2 4+1
дополнительный контакт требуется для отключения всех моторов

Что мы здесь видим?

  • Коллекторные моторы с пластиковым редуктором — самые простые и самые дешевые.
  • Сервопривод MG995 3600 — наиболее экономичный по ресурсам контроллера Arduino. При его использовании хорошо регулируется скорость движения робота, если скорость колес нужно менять постоянно и держать в заданных пределах. Скорость оборота колеса, вращаемого сервоприводом, зависит только от установленного на порту управления значения сигнала, и при увеличении сопротивления (когда, например, робот движется в гору) меняется слабо, в то время как двигатель постоянного тока без обратной связи по скорости изменяет скорость своего вращения в зависимости от нагрузки.
  • Шаговый двигатель следует применять там, где нужна точность, и если это необходимо, обратитесь к книге «Мобильные роботы на базе ESP32 в среде Arduino IDE»[1], там как раз используются шаговые моторы в качестве ходовой части. Шаговым двигателем также можно держать постоянную скорость.

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

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

Драйверы двигателей

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

Таблица 5.2. Специализированные микросхемы драйверов двигателей (на платах)

Характеристики TB6612FNG
(рис. 5.6)
MX1508
(рис. 5.7)
L298N
(рис. 5.8)
Максимальный ток на канал, А 1,2 1,2 2
Количество подключаемых коллектроных моторов 2 2 2
Максимальное напряжение питания, В 13,5 10 35
Минимальное напряжение питания, В 2,5 2,5 6
Встроенная диодная защита от паразитных токов Есть Есть Есть

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

Драйверы_2

Рис. 5.6. Плата драйвера TB6612FNG

Драйверы TB6612 и L298N имеют отдельные входы управления мощностью моторов (PWMA–PWMB и ENA–ENB соответственно), но если на эти входы подать высокое логическое напряжение (5 вольт), то управление драйверами TB6612, L298N и MX1508 будет осуществляться схоже по входам AIN1–AIN2 и BIN1–BIN2 — для TB6612, а также IN1–IN2 и IN3–IN4 — для L298N и MX1508. Именно такие режимы работы мы и будем использовать, чтобы наша программа вела себя одинаково и независимо от того, какой драйвер моторов вы решили использовать в своей модели.

5

Рис. 5.7. Плата драйвера MX1508

5

Рис. 5.8. Плата драйвера L298N

 

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

Таблица 5.3. Значения сигналов на входах и соответствующая реакция двигателя

IN1 (AIN1) IN2 (AIN2) Мотор A (направление вращения условное)
0 0 Отключен
0 1 Вал вращается против часовой стрелки
1 0 Вал вращается по часовой стрелке
1 1 Отключен

Таблица 5.3 (окончание)

IN3 (BIN1) IN4 (BIN2) Мотор B (направление вращения условное)
0 0 Отключен
0 1 Вал вращается против часовой стрелки
1 0 Вал вращается по часовой стрелке
1 1 Отключен

 

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

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

Управляем двигателем без Arduino

Возьмем драйвер L298N (или MX1508), двигатели постоянного тока, аккумуляторы с боксом, провода, керамические конденсаторы 0,1 мкФ (маркируются числом 104) — они нужны для исключения электромагнитных наводок, которые возникают при работе двигателей и могут стать причиной сбоев в работе электроники робота, и паяльник. При пайке легко испортить поверхность стола, поэтому используйте фанеру или постелите на место работы с паяльником пару листов бумаги.

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

2017-01-28 12-10-46

Рис. 5.9. Двигатель постоянного тока, керамический конденсатор и провода

Обмотаем ножки конденсатора вокруг залуженных кончиков проводов, как показано на рис. 5.10, — теперь ножки конденсатора хорошо держатся на проводе, и их легко можно припаять (рис. 5.11).

2017-01-28 12-13-24 2017-01-28 12-14-34 (2)
Рис. 5.10. Ножки конденсатора обмотаны
вокруг оголенных концов провода
Рис. 5.11. Пайка конденсатора

Далее припаяем кончики проводов к залуженным контактам двигателя (рис. 5.12). Если лужение контактов двигателя проходит плохо, аккуратно зачистите контакты перочинным ножом или обработайте паяльной кислотой (после паяльной кислоты нужно промыть контакты спиртом или водой).

Готовый к работе двигатель показан на рис. 5.13.

2017-01-28 12-16-20

Рис. 5.12. Припаивание проводов к контактам двигателя

5

Рис. 5.13. Двигатель с припаянными проводами и конденсатором

Картинка мотор+аккумул_bb

Рис. 5.14. Схема тестирования двигателя

Качество пайки можно проверить, присоединив двигатель к аккумуляторам (рис. 5.14), — если двигатель не работает, значит, пайка выполнена некачественно (предварительно проверьте наличие напряжения на контактах аккумуляторного бокса!).

Теперь, когда двигатели готовы, приступим к сборке схемы, изображенной на рис. 5.15. Перемычки на контактах ENA и ENB драйвера не убираем!

Картинка драйвер +мотор_стенд_bb

Рис. 5.15. Схема управления двигателями без контроллера Arduino

Двигатели подключаются к драйверу через винтовые зажимы, также подключается и аккумуляторный бокс, для контактов IN1–IN4 драйвера L298N лучше использовать провода с готовыми клеммами Dupont (см. главу 2), а для MX1508 требуется пайка.

Подключая 5 вольт к различным контактам IN1–IN4, можно проследить, как изменяется вращение двигателей M1 и M2 (используйте данные табл. 5.4).

Подсказка

Контакты IN1 и IN2 отвечают за работу двигателя М1, а IN3 и IN4 — двигателя М2.

Широтно-импульсная модуляция

Проведем наглядный эксперимент: отключим контакт IN1 мотора М1, а контакт IN2 будем руками быстро подключать к напряжению 5 вольт и отключать от него, — мотор станет вращаться с заметными рывками.

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

Мы в наших проектах будем использовать шкалу мощности от 0 до 255, где число — это относительная длительность импульса включения мотора за период (рис. 5.16). А чтобы иметь возможность изменять направление вращения, задействуем и отрицательную шкалу: –255…0…255, при этом изменяя вход драйвера, на который подается сигнал (при положительном вращении — на IN1, при отрицательном — на IN2 для мотора М1 и IN3/IN4 — для мотора М2).

рис 5_14

Рис. 5.16. Принцип работы ШИМ

Подключаем контроллер Arduino

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

Добавим к собранной схеме контроллер Arduino и научим его управлять двига-
телями. Дополнительно нам потребуется несколько проводов с клеммами Dupont.

l298nMP

Рис. 5.17. Схема управления двигателями для драйверов L298N и MX1508

На рис. 5.17 показана схема подключения драйверов L298N и MX1508, на рис. 5.18 и 5.19 — схема подключения TB6612FNG (она несколько сложнее).

Дело в том, что подключение драйвера TB6612FNG потребует немного больше соединений, т. к. нужно подать логическую единицу (5 вольт от Arduino) на контакты VCC, PWMA, PWMB и STBY, в остальном же схема схожа с подключением L298N и MX1508. Чтобы исключить на рисунках пересечение соединений и неверную их трактовку, схема подключения драйвера TB6612FNG разбита на две части: подключение силовой части (рис. 5.18) и логической части (рис. 5.19).

Удобно при этом задействовать дополнительные платы, которые упрощают реализацию соединений, — например Arduino Sensor shield V5.0 (для Arduino Uno) или NANO V3.0 Shield (для Arduino Nano).

Далее приведены примеры управления вращением двигателей при помощи программы, работающей на контроллерах Arduino UNO, Arduino Nano и Arduino Pro Mini.

23_tb6612fngPower_МП

Рис. 5.18. Схема управления двигателями для драйвера TB6612FNG (силовая часть)

23_tb6612fngCom_МП

Рис. 5.19. Схема управления двигателями для драйвера TB6612FNG (логическая часть)

Подключаем библиотеку mobrob3.zip и пишем тестовую программу

Специально для этого издания книги ее автор разработал библиотеку mobrob3.zip.
В ней, в частности, содержится модуль управления мощностью пары моторов
(см. далее).


Электронный архив

Электронный архив, включающий библиотеку mobrob3.zip, можно скачать с сервера издательства «БХВ» по ссылке https://zip.bhv.ru/9785977517034.zip или со страницы книги на сайте https://bhv.ru/ (см. приложение).


Перед использованием библиотеку mobrob3.zip нужно добавить в Arduino IDE стандартным способом: Скетч | Подключить библиотеку | Добавить .ZIP библиотеку, и выбрать с диска файл mobrob3.zip. В результате все модули и примеры из этой книги (по главам) станут доступны в Arduino IDE. Для управления моторами в библиотеку включен модуль mobrob3xmotor.h, в котором учтены некоторые особенности управления моторами для генерации ШИМ, заключающиеся в том, что в качестве левых моторов будущего робота можно использовать только контакты GPIO 2 и 3 (менять их местами можно), а для правого мотора — только 4 и 5 (их также можно менять местами, чтобы добиться вращения в нужную сторону). Подобное ограничение связано с тем, что генерация ШИМ возможна только на контактах 3 и 5 GPIO.

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

В бесконечном цикле:

  1. Отключаем оба двигателя.
  2. Ждем 1 секунду.
  3. Подключаем двигатель 1 на полную мощность по часовой стрелке.
  4. Ждем 1 секунду.
  5. Отключаем двигатель 1.
  6. Ждем 1 секунду.
  7. Подключаем двигатель 1 на полную мощность против часовой стрелки.
  8. Ждем 1 секунду.
  9. Отключаем двигатель 1.
  10. Возвращаемся на пункт 1.

Самостоятельно измените эту программу для управления двигателем 2.

Листинг 5.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
26
27
28
29
// Контакты управления левого мотора только 2 и 3.
# define GPIO_1F 2
# define GPIO_1B 3
// Контакты управления правого мотора только 4 и 5.
# define GPIO_2F 4
# define GPIO_2B 5
 
// Подключаем библиотеку управления моторами.
#include < mobrob3xmotor.h>
void setup()
{
// Вызываем функцию инициализации моторов.
motor_setup();
}
 
// Основная программа.
void loop()
{
motors_power(0, 0); // Отключены оба.
delay(1000);
motors_power(255, 0); // Включен мотор 1 +
delay(1000);
motors_power(0, 0); // Отключены оба.
delay(1000);
motors_power(-255, 0); // Включен мотор 1 -
delay(1000);
// Проделайте те же операции для двигателя 2 самостоятельно.
// ....
}

Добавляем регулирование на основе ШИМ

Рассмотренная и подключенная в предыдущем разделе библиотека mobrob3.zip уже содержит модуль mobrob3xmotor.h, который может регулировать мощность моторов при помощи ШИМ.

Напомню, что значения ШИМ в Arduino могут изменяться от 0 до 255. На практике вал двигателя не сразу начнет вращаться — сначала (при малых значениях) двигатель станет гудеть и лишь по достижении определенного значения ШИМ начнет медленно увеличивать обороты, что связано с недостатком мощности для компенсации сил трения.

Тестовая программа управления двигателями с регуляцией на основе ШИМ

Логика работы этой тестовой программы (листинг 5.2) следующая.

В бесконечном цикле:

  1. Отключаем оба двигателя.
  2. Ждем 1 секунду.
  3. Далее в цикле через 100 миллисекунд увеличиваем мощность от 70 до 255 для обоих моторов.
  4. Далее в цикле через 100 миллисекунд уменьшаем мощность от 255 до 70 для обоих моторов.
  5. Возвращаемся к пункту 1.

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

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

Листинг 5.2. Тестовая программа управления двигателями с регуляцией на основе ШИМ

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
// Зададим номера контактов управления моторами.
// Контакты управления левого мотора только 2 и 3.
# define GPIO_1F 2
# define GPIO_1B 3
// Контакты управления правого мотора только 4 и 5.
# define GPIO_2F 4
# define GPIO_2B 5
// Подключаем библиотеку управления моторами.
#include <mobrob3xmotor.h>
void setup()
{
// Вызываем функцию инициализации моторов.
motor_setup();
}
//=================================================================
// Основная программа.
void loop()
{
motors_power(0, 0);
delay(500);
for (int i = 70; i < 255; i++)
{
motors_power(i, i);
delay(100);
}
for (int i = 255; i > 70; i--)
{
motors_power(i, i);
delay(100);
}
}

Выводы

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

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

  1. См. https://bhv.ru/product/mobilnye-roboty-na-baze-esp32-v-srede-arduino-ide/.
Опубликовано

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

По материалам книги “Arduino. Большая книга рецептов“, 3-е изд. (авторы Джепсон Брайан, Марголис Майкл, Уэлдин Николас Роберт) (глава 8. Управление
электродвигателями)

Arduino. Большая книга рецептов, 3-издание

ЗАДАЧА

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

РЕШЕНИЕ

Двигатели для этого решения подключаются так же, как показано на рис. 8.10, но к схеме добавлены два фоторезистора (или фототранзистора — подробную информацию по фототранзисторам см. в разд. 1.6), как показано в схеме на рис. 8.12. Конденсаторы номиналом 0,1 мкФ на электродвигателях должны быть керамическими.

C:\Users\acer\Documents\#Electronics\Магазин электроники\фрагменты из книг\2788. Arduino Cookbook. Recipes to Begin, Expand, and Enhance\verstka\pic\08\8.12.png

Рис. 8.12. Управление двумя щеточными электродвигателями с помощью датчиков

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

Листинг 8.12. Управление двумя электродвигателями с помощью фотодатчиков

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
* Скетч Brushed_H_Bridge_Direction
* Управляет электродвигателями на основании сигналов фотодатчиков,
* направляя шасси робота к источнику света
*/
 
int leftPins[] = {5,7,4}; // Один контакт для ШИМ (скорость),
// два контакта для направления левого двигателя
int rightPins[] = {6,3,2}; // То же, для правого двигателя
const int MIN_PWM = 64; // Это значение может быть в диапазоне от 0 до MAX_PWM
const int MAX_PWM = 128; // Это значение может быть в диапазоне от 50 до 255
const int leftSensorPin = A0; // Контакты для подключения фотодатчиков
const int rightSensorPin = A1;
 
int sensorThreshold = 0; // Пороговый уровень освещенности на датчике
// для вращения электродвигателя
void setup()
{
 
for(int i=1; i < 3; i++)
{
pinMode(leftPins[i], OUTPUT);
pinMode(rightPins[i], OUTPUT);
}
}
 
void loop()
{
int leftVal = analogRead(leftSensorPin);
int rightVal = analogRead(rightSensorPin);
if(sensorThreshold == 0) // Датчики откалиброваны?
{
// Если нет, калибруем до уровня освещенности несколько выше
// среднего уровня освещенности окружающей среды
sensorThreshold = ((leftVal + rightVal) / 2) + 100 ;
}
if( leftVal > sensorThreshold || rightVal > sensorThreshold)
{
// Если уровень освещенности достаточно высокий
// для движения вперед
setSpeed(rightPins, map(rightVal,0,1023, MIN_PWM, MAX_PWM));
setSpeed(leftPins, map(leftVal ,0,1023, MIN_PWM, MAX_PWM));
}
}
 
void setSpeed(int pins[], int speed )
{
if(speed < 0)
{
digitalWrite(pins[1],HIGH);
digitalWrite(pins[2],LOW);
speed = -speed;
}
else
{
digitalWrite(pins[1],LOW);
digitalWrite(pins[2],HIGH);
}
analogWrite(pins[0], speed);
}

Обсуждение работы решения и возможных проблем

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

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

Сигнал с фотодатчиков подается на аналоговые контакты A0 и A1 платы Arduino,
с которых он считывается функцией analogRead() (эта функция подробно рассматривается в разд. 6.3). В начале исполнения скетча измеряется уровень фоновой освещенности, и это пороговое значение используется для определения минимального уровня освещенности, необходимого, чтобы начинать движение шасси. К измеренному пороговому уровню освещенности добавляется запас величиной в 100 еди­ниц, чтобы небольшие изменения уровня фоновой освещенности не вызывали движения. Значение уровня освещенности, возвращенное функцией analogRead(), преобразовывается с помощью функции map() в значение ШИМ. Константе MIN_PWM следует задать приблизительное значение ШИМ, при котором шасси должно начинать движение (слишком низкие значения не дадут достаточного крутящего момента. Точное значение надо будет определить экспериментальным путем). А константе MAX_PWM нужно задать значение (до 255), определяющее максимальную скорость шасси.

Скорость вращения электродвигателей управляется функцией setSpeed(). Для управления направлением вращения каждого электродвигателя используются два контакта платы Arduino и еще один контакт — для управления скоростью вращения. Номера этих контактов хранятся в массивах leftPins и rightPins для левого и правого двигателей соответственно. В первом элементе массива хранится номер контакта для управления скоростью вращения, а в двух других — для управления направлением.

В любом из решений, в котором используется микросхема H-моста L293, вместо нее можно альтернативно применить микросхему TB6612FNG. На рис. 8.13 показано подключение к плате Arduino микросхемы H-моста TB6612 (установленной на адаптерной плате артикул 713 компании Pololu).

C:\Users\acer\Documents\#Electronics\Магазин электроники\фрагменты из книг\2788. Arduino Cookbook. Recipes to Begin, Expand, and Enhance\verstka\pic\08\8.13.png

Рис. 8.13. Подключение адаптерной платы микросхемы H-моста TB6612 производства компании Pololu

Количество контактов платы Arduino, задействованных для управления схемой, можно уменьшить, добавив в схему дополнительный компонент для управления контактами направления H-моста. Такой компонент представляет собой транзистор или логический элемент для инвертирования логического уровня, подаваемого на другой ввод H-моста, позволяя использовать только один контакт платы Arduino для управления направлением вращения электродвигателя. Соответствующую принципиальную схему можно найти на веб-сайте Arduino, но также существуют и готовые решения — например, шилд H-моста Arduino Motor Shield (артикул 7630049200371, https://store.arduino.cc/arduino-motor-shield-rev3) или шилд Ardumoto компании SparkFun (артикул DEV-09213). Оба эти шилда используют микросхему L298, которая является более мощной альтернативой микросхеме L293. Эти шилды вставляются в гнездовые разъемы платы Arduino и требует только подключения к электродвигателю и его источнику питания.

В листинге 8.13 приводится скетч для управления электродвигателями с помощью шилда Arduino Motor Shield (контакты A0 и A1 платы Arduino задействованы для измерения тока, поэтому для управления в скетче используются контакты A2 и A3).

Листинг 8.13. Управление электродвигателями с помощью шилда Arduino Motor Shield

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
* Скетч Brushed_H_Bridge_Direction sketch for motor shield
* Управляет электродвигателями на основании сигналов фотодатчиков,
* направляя шасси робота к источнику света
*/
int leftPins[] = {3,12}; // Один контакт для ШИМ-сигнала (скорость),
// один — для направления
int rightPins[] = {11,13};
const int MIN_PWM = 64; // Это значение может быть в диапазоне
// от 0 до MAX_PWM
const int MAX_PWM = 128; // Это значение может быть в диапазоне от 50 до 255
const int leftSensorPin = A2; // Аналоговые контакты для подключения фотодатчиков
const int rightSensorPin = A3;
int sensorThreshold = 0; // Пороговый уровень освещенности на датчике
// для вращения электродвигателя
void setup()
{
pinMode(leftPins[1], OUTPUT);
pinMode(rightPins[1], OUTPUT);
}
 
void loop(){
int leftVal = analogRead(leftSensorPin);
int rightVal = analogRead(rightSensorPin);
if(sensorThreshold == 0) // Датчики откалиброваны?
{
// Если нет, калибруем до уровня освещенности несколько выше
// среднего уровня освещенности окружающей среды
sensorThreshold = ((leftVal + rightVal) / 2) + 100 ;
}
if( leftVal > sensorThreshold || rightVal > sensorThreshold)
{
// Если уровень освещенности достаточно высокий для движения вперед
setSpeed(rightPins, map(rightVal,0,1023, MIN_PWM, MAX_PWM));
setSpeed(leftPins, map(leftVal, 0,1023, MIN_PWM, MAX_PWM));
}
}
void setSpeed(int pins[], int speed )
{
if(speed < 0)
{
digitalWrite(pins[1], HIGH);
speed = -speed;
}
else
{
digitalWrite(pins[1], LOW);
}
analogWrite(pins[0], speed);
}

Функция loop() здесь идентична этой функции скетча из листинге 8.12. Функция setSpeed() скетча содержит меньший объем кода, чем ее предыдущая версия, поскольку аппаратное обеспечение шилда позволяет использовать только один контакт платы Arduino для управления направлением вращения электродвигателя.
В шилде Ardumoto используются другие контакты, поэтому для работы с ним код скетча нужно откорректировать следующим образом:

1
2
3
int leftPins[] = {3, 2}; // Один контакт для ШИМ-сигнала (скорость),
// один — для направления
int rightPins[] = {11, 4};

В листинге 8.14 приводится код скетча, реализующий эту же функциональность на основе шилда Adafruit Motor Shield V2 (https://oreil.ly/kFygk), подключение которого показано на рис. 8.14. В скетче используется библиотека Adafruit_MotorShield, которая устанавливается стандартным способом с помощью Менеджера библиотек.

Шилд Adafruit Motor Shield V2 поддерживает подключение четырех электродвигателей, но в скетче из листинге 8.14 предусмотрено, что два электродвигателя подключены к разъемам шилда 3 и 4.

Листинг 8.14. Управление электродвигателями с помощью шилда Adafruit Motor Shield V2

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
* Скетч Brushed_H_Bridge_Direction sketch for Adafruit Motor shield
* Управляет электродвигателями на основании сигналов фотодатчиков,
* направляя шасси робота к источнику света
*/
#include <Wire.h>
#include <Adafruit_MotorShield.h> // Подключаем библиотеку Adafruit_MotorShield
// Создаем экземпляр объекта шилда
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *leftMotor = AFMS.getMotor(1);
Adafruit_DCMotor *rightMotor = AFMS.getMotor(2);
const int MIN_PWM = 64; // Это значение может быть в диапазоне от 0 до MAX_PWM
const int MAX_PWM = 128; // Это значение может быть в диапазоне от 50 до 255
const int leftSensorPin = A0; // Аналоговые контакты для подключения фотодатчиков
const int rightSensorPin = A1;
int sensorThreshold = 0; // Пороговый уровень освещенности на датчике
// для вращения электродвигателя
void setup()
{
AFMS.begin(); // Инициализируем экземпляр шилда частотой
// по умолчанию 1,6 КГц
}
 
void loop()
{
int leftVal = analogRead(leftSensorPin);
int rightVal = analogRead(rightSensorPin);
if(sensorThreshold == 0) // Датчики откалиброваны?
{
// Если нет, калибруем до уровня освещенности несколько выше
// среднего уровня освещенности окружающей среды
sensorThreshold = ((leftVal + rightVal) / 2) + 100 ;
}
if( leftVal > sensorThreshold || rightVal > sensorThreshold)
{
// Если уровень освещенности достаточно высокий для движения вперед
setSpeed(rightMotor, map(rightVal,0,1023, MIN_PWM, MAX_PWM));
setSpeed(leftMotor, map(leftVal ,0,1023, MIN_PWM, MAX_PWM));
}
}
void setSpeed(Adafruit_DCMotor *motor, int speed )
{
if(speed < 0)
{
motor->run(BACKWARD);
speed = -speed;
}
else
{
motor->run(FORWARD);
}
motor->setSpeed(speed);
}

C:\Users\acer\Documents\#Electronics\Магазин электроники\фрагменты из книг\2788. Arduino Cookbook. Recipes to Begin, Expand, and Enhance\verstka\pic\08\8.14.png

Рис. 8.14. Подключение шилда Adafruit Motor Shield V2

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

Дополнительная информация

Подробная информация по адаптерной плате компании Pololu для H-моста TB6612FNG приводится в справочном листке на нее (https://oreil.ly/bD_83).

Дополнительная информация по шилду Ardumoto компании SparkFun приводится на его веб-странице (https://oreil.ly/XZTCY).

Дополнительная информация по шилду Arduino Motor Shield приводится на его веб-странице (https://oreil.ly/2gKoX).

Дополнительная информация по шилду Adafruit Motor Shield V2 приводится на его веб-странице (https://oreil.ly/T19_o).

Опубликовано

Подключение к Интернету с помощью платы расширения Arduino Ethernet shield

По материалам книги В. Петина “Проекты с использованием контроллера Arduino. 4-е изд.” (глава 13. Arduino и Интернет вещей)

Проекты с использованием контроллера Arduino. 4-е изд.

Самый распространенный метод обеспечить доступ платы Arduino к сети Интернет — использование платы Ethernet shield (рис. 13.1). Ethernet shield — это плата расширения, которая устанавливается на плату Arduino сверху. Она дает ей возможность выступать в роли сетевого устройства и общаться по проводной сети с аналогичными устройствами, с обычными компьютерами, принтерами, сервисами в Интернете и прочими сетевыми ресурсами. Последняя версия платы Ethernet Shield Rev3 полностью совместима с Arduino Mega2560.

Плата Ethernet shield основана на микросхеме Wiznet W5100, которая поддерживает как TCP-, так и UDP-протоколы. Одновременно открытыми могут быть до четырех подключений.

Плата обладает стандартным Ethernet-портом для подключения к сети с помощью патч-корда витой пары и набором контактов для подключения к Arduino. Для общения между собой Ethernet shield и Arduino задействуют контакты 4-й и с 10-го по 13-й, поэтому их использование в других целях в присутствии платы расширения невозможно.

Для программирования сетевого взаимодействия подключается библиотека Ethernet из стандартного дистрибутива. При использовании этой библиотеки необходимо указывать MAC-адрес платы (уникальный идентификатор любого сетевого устройства). В более новых версиях Ethernet-шилда MAC-адрес можно увидеть на наклейке на плате. Если такой наклейки нет, то просто введите любую похожую комбинацию, — главное, чтобы в вашей сети не было устройств с совпадающими MAC-адресами.
На плате размещен слот для карты памяти формата microSD, которая может быть использована для хранения ресурсов, раздаваемых по сети. Для взаимодействия с такой картой следует подключить, например, библиотеку sdfatlib.
Для отправки данных в облачные сервисы в примерах этого раздела мы воспользуемся веб-клиентом на основе платы Arduino c установленной на нее платой расширения Ethernet shield.

ris_04_04

Рис. 13.1. Плата Ethernet shield Rev3

13.1.1. Получение IP-адреса по DHCP

Соединим Ethernet shield с платой Arduino и создадим простой пример получения ими IP-адреса по DHCP. Соединяется Ethernet shield с платой Arduino так же просто, как и любой другой шилд, — просто состыкуйте их вместе. Cледует учесть, что установка других шилдов поверх Ethernet shield весьма затруднительна. Это связано с большими размерами имеющегося на плате Ethernet shield разъема RJ-45, служащего для подключения сетевого кабеля, поэтому, если вы хотите использовать совместно с Arduino еще и другие шилды, лучше их размещать между Arduino и Ethernet shield.

Итак, подключим плату Arduino к USB-порту компьютера, а Ethernet shield подсоединим c помощью сетевого кабеля к маршрутизатору, имеющему выход в Интернет (рис. 13.2).

Скетч, обеспечивающий получение IP-адреса по DHCP, представлен в листинге 13.1, а пример назначения статического IP-адреса — в листинге 13.2.

ris_04_05

Рис. 13.2. Подключение к плате Arduino платы расширения Ethernet shield Rev3

Листинг 13.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
26
27
28
29
30
31
// Получение IP-адреса по DHCP
// MAC-адрес Ethernet shield (можно увидеть на наклейке на плате) или
// произвольный уникальный в сети
 
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02};
void setup() {
 
// Open serial communications and wait for port to open:
 
Serial.begin(9600);
}
 
// запуск Ethernet-соединения
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
for (;;)
;
}
 
// печать в последовательный порт полученного по DHCP адреса
Serial.print("My IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
}
 
void loop() {;}

Электронный архив

Полный вариант рассмотренного скетча находится в папке examples\13\_13_01 сопровождающего книгу электронного архива (см. приложение 2).


Листинг 13.2

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
// Получение статического IP-адреса
// MAC-адрес Ethernet shield (можно увидеть на наклейке на плате) или
// произвольный уникальный в сети
 
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02};
 
// IP-адрес, назначаемый Ethernet shield:
byte ip[] = { 192, 168, 0, 111 };
// IP-адрес dns сервера:
byte sdns[] = { 192, 168, 1, 1 };
// адрес шлюза:
byte gateway[] = { 192, 168, 0, 1 };
// маска:
byte subnet[] = { 255, 255, 255, 0 };
 
void setup() {
Serial.begin(9600);
// запуск Ethernet-соединения
Ethernet.begin(mac, ip, sdns, gateway, subnet);
delay(1000);
Serial.println(Ethernet.localIP());
}
 
void loop() {;}

Электронный архив
Полный вариант рассмотренного скетча находится в папке examples\13\_13_02 сопровождающего книгу электронного архива (см. приложение 2).