Посмотрим на примере использования ультразвукового дальномера и серво-машинки, как могут взаимодействовать между собой подключенные к Ардуино периферийные устройства.
Предположим, что есть необходимость повернуть колеса транспортного механизма при приближении его к препятствию. Или прикрыть заслонку, регулирующую воздушный поток, при приближении к ней человека. Эти задачи может решать устройство, которое отслеживает расстояние до объекта и, в зависимости от этого расстояния, поворачивает вал серво-машинки на угол, пропорциональный расстоянию до объекта.
Соберем такое устройство на макетной плате:
Помимо земли и напряжения питания, подключим вывод управления серво-машинкой к выводу D4 Ардуино, а выводы Trig и Echo ультразвукового датчика – к выводам D2 и В3 соответственно.
Принцип работы ультразвукового дальномера основан на излучении ультразвука и приема отраженного сигнала от находящегося на пути его распространения препятствия. Зная время возвращения звука от препятствия и скорость распространения звукового сигнала в воздухе, можно рассчитать расстояние до объекта, отражающего звук.
Датчик работает следующим образом:
С помощью микроконтроллера на вывод "Trig" подается импульс продолжительностью 10-15 мкс.
Внутри дальномера входной импульс преобразуется в 8 импульсов, модулированных частотой 40 КГц и излучается трансмиттером, обозначенным "T".
Излученный сигнал отражается от препятствия, принимается ресивером "R", и преобразуется в положительный импульс, длительность которого прямо пропорциональна расстоянию до препятствия.
Этот импульс передается в микроконтроллер с вывода "Echo".
На стороне контроллера длительность полученного сигнала пересчитывается в расстояние.
Серво-машинка (или серво-привод) состоит из корпуса, в котором заключен электромотор, редуктор, потенциометр обратной связи и управляющая электроника. С помощью управляющей схемы осуществляется обратная связь между потенциометром и двигателем, которые имеют механическую связь через редуктор.
Потенциометр обратной связи находится прямо на выходном валу, благодаря чему блок управления серво-машинки отслеживает точное положение вала: сопротивление потенциометра изменяется пропорционально углу поворота. Считав сопротивление, блок управления сравнивает это значение с тем, которое должно быть при заданном положении вала. Если эти значения отличаются, блок управления дает команду двигателю повернуть вал в заданном направлении, уменьшая разницу значений. Достигнув положения вала, когда значение с потенциометра совпадает с заданным значением, двигатель останавливается. Считывание значения с потенциометра и его сравнение происходит с большой частотой, поэтому выходной вал будет стремиться занять заданное положение даже при изменении его положения извне.
В качестве управляющего сигнала используется импульсный сигнал с периодом 20 мс и с длительностью от 0,8 до 2,2 мс. Это практически сложившийся стандарт управления серво-машинками. Чем шире положительный импульс, тем на больший угол повернется вал серво-машинки.
В качестве управляющего всей системой устройства будем использовать Aduino-Nano MB NANO – малогабаритную версию этой популярной платформы.
Для программирования нам понадобятся библиотеки серво-машинки (эта библиотека называется Servo.h и входит в стандартную поставку среды программирования ArdinoIDE), и ультразвукового датчика (будем использовать подходящую библиотеку Ultrasonic.h). В библиотеке Ultrasonicочень удобно реализовано управление датчиком и вычисление дистанции в сантиметрах и дюймах.
Скетч проекта с подробными комментариями приведен ниже:
//--------------------------------------------------------
#include <Ultrasonic.h> // присоединяем библиотеку ультразвукового датчика
#include <Servo.h> // присоединяем библиотеку серво-машинки
#define coef 7 //коэффициент пересчета расстояния в угол поворота
#define min_dist 4 // минимальное расстояние в см
#define max_dist 30 // максимальное расстояние в см
int trigPin = 2; // trigger pin
int echoPin = 3; // echo pin
int servoPin = 4; // servo pin
int ledPin = 13; // встроенныйсветодиод
long imp_long; // назначаем переменную для хранения длительности входящего импульса
float distance_sm; // назначаем переменную для хранения расстояния
Ultrasonic ultrasonic(trigPin,echoPin); // инициализируем ультразвуковой модуль
Servo myservo; // инициализируем серво-машинку
void setup()
{
pinMode(ledPin, OUTPUT); // инициализируем ledPIN как выход
pinMode(trigPin, OUTPUT); // инициализируем trigPin как выход для подачи запускающего импульса
pinMode(echoPin, INPUT); // инициализируем echoPin как вход для приема сигнала с модуля
myservo.attach(servoPin); // инициализируем сервомашинку на выводе servoPin
}
void loop()
{
imp_long = ultrasonic.timing(); // получаем длительность отраженного импульса
distance_sm = ultrasonic.CalcDistance(imp_long,Ultrasonic::CM); // вычисляемрасстояние
if (distance_sm >= min_dist && distance_sm <= max_dist)
{
myservo.write(coef * (distance_sm - min_dist)); // поворачиваемвалсерво-машинки
digitalWrite(ledPin,LOW); // если расстояние в пределах допустимого, поворачиваем серву на
} // соответствующий угол и гасим светодиод
else if (distance_sm < min_dist) // если дистанция меньше min_dist, ставим серву в положении ноль градусов
{ // и зажигаем светодиод
myservo.write(0);
digitalWrite(ledPin,HIGH);
}
else
{
myservo.write(180);
digitalWrite(ledPin,HIGH);
}
delay(55); // рекомендуемая производителем задержка между измерениями расстояния
}
//--------------------------------------------------------