Датчик, действие которого основано на принципе сонара – посылая пучок ультразвука и получая его отражение, он определяет расстояние до объекта по длительности временного интервала между этими событиями.
Инфракрасный датчик обхода препятствий применяется когда нужно определить наличие объекта, а точное расстояние до него знать необязательно. Датчик состоит из инфракрасного излучателя и фотоприемника. Компаратор LM393 делает выход модуля цифровым.
Пороговое значение регулируется с помощью потенциометра (по часовой стрелке — увеличиваем расстояние, против часовой — уменьшаем).
Несмотря на название данный сенсор реагирует скорее на легкие толчки, чем на вибрацию. Основной элемент датчика – металлическая пружина гибкой структуры, расположенная во внутренней части трубки из пластика. При наличии воздействий на сенсор она начинает колебаться.
Лидар — лазерный измеритель расстояния. Среди прочего очень полезен в системах навигации роботов. Данная модель недорогого (~120 долларов) лидара имеет очень неплохие характеристики:
Официальный репозиторий производителя с большим количеством примеров: ссылка на гитхаб.
Совместная работа лидара и сервопривода. Используются библиотеки Servo.h и Wire.h. Серва делает поворот на 180 градусов. Данные о расстоянии и соответствующем угле поворота выводятся в последовательный порт.
#include <Wire.h> // Для I2C протокола лидара
#define LIDARLite_ADDRESS 0x62 // I2C адрес лидара по-умолчанию
#define RegisterMeasure 0x00 // Register to write to initiate ranging.
#define MeasureValue 0x04 // Value to initiate ranging.
#define RegisterHighLowB 0x8f // Register to get both High and Low bytes in 1 call.
#include <Servo.h>
Servo myservo;
int pos = 0; // Position of the servo (degress, [0, 180])
int distance = 0; // Distance measured
void setup()
{
// Serial output
Serial.begin(9600);
Serial.println("< START >");
// Servo control
myservo.attach(5);
// LIDAR control
Wire.begin(); // join i2c bus
}
// Get a measurement from the LIDAR Lite
int lidarGetRange(void)
{
int val = -1;
Wire.beginTransmission((int)LIDARLite_ADDRESS); // transmit to LIDAR-Lite
Wire.write((int)RegisterMeasure); // sets register pointer to (0x00)
Wire.write((int)MeasureValue); // sets register pointer to (0x00)
Wire.endTransmission(); // stop transmitting
delay(20); // Wait 20ms for transmit
Wire.beginTransmission((int)LIDARLite_ADDRESS); // transmit to LIDAR-Lite
Wire.write((int)RegisterHighLowB); // sets register pointer to (0x8f)
Wire.endTransmission(); // stop transmitting
delay(20); // Wait 20ms for transmit
Wire.requestFrom((int)LIDARLite_ADDRESS, 2); // request 2 bytes from LIDAR-Lite
if(2 <= Wire.available()) // if two bytes were received
{
val = Wire.read(); // receive high byte (overwrites previous reading)
val = val << 8; // shift high byte to be high 8 bits
val |= Wire.read(); // receive low byte as lower 8 bits
}
return val;
}
void serialPrintRange(int pos, int distance)
{
Serial.print("Position (deg): ");
Serial.print(pos);
Serial.print("\t\tDistance (cm): ");
Serial.println(distance);
}
void loop()
{
for(pos = 0; pos <= 180; pos += 1)
{
myservo.write(pos);
distance = lidarGetRange();
serialPrintRange(pos, distance);
delay(20);
}
for(pos = 180; pos>=0; pos-=1)
{
myservo.write(pos);
distance = lidarGetRange();
serialPrintRange(pos, distance);
delay(20);
}
}
Сервопривод — это мотор с редуктором, который под действием управляющего сигнала микроконтроллера может поворачиваться на определенный угол и удерживать свое положение. Широко применяется в роботах и радиоуправляемых моделях.
Удобный в подключении и програмировании модуль беспроводной связи для ардуино проектов. Может быть полезен для контроля состояния датчиков, для изменения параметров системы без перезагрузки контроллера, для управляемых со смартфона роботов.
Данные оптические энкодеры очень удобны в подключении к ардуино, т.к. имеют на борту всю развязку, позволяющую питать их от 3,3 до 5 вольт. Благодаря наличию в схеме триггера Шмитта, выходной сигнал полностью «цифровой». Также есть светодиод для индикации размыкания линии. Он будет полезен при настройке взаимного положения энкодера и крыльчатки оси двигателя.
Данный сонар стоит значительно дороже известного датчика HC-SR04 и позиционируется как высокоточный, дальнобойный и легко подключаемый сенсор. Данные могут считываться с аналогового выхода, выхода с ШИМ сигналом или через последовательный интерфейс.
Радиус действия от 15 см до 6,5 метров. Питание от 2.5-5.5 вольт. Имеется возможность подключить несколько датчиков, которые будут работать последовательно, не создавая помех друг другу.
Дешевая плата защиты от перезаряда/перезаряда литивого аккумулятора. Данная плата не является полноценной BMS, т.к. не балансирует отдельные ячейки. Можно подключить до четырех ячеек.
Функционал ограничивается отключением нагрузки при достижении напряжения в ячейках в 3,5V и зарядного устройства при напряжении 4,2V.
Заявляется, что без радиатора может питать нагрузку до 10А, с радиатором — до 15А и кратковременного допускается ток в 30А.
С помощью модуля управления моторами RKP-01A на микросхеме L298N можно контролировать вращение двух независимых коллекторных моторов постоянного тока (DC-моторов) или одного двухобмоточного четырехпроводного шагового двигателя.
потребление моторов до 2А
питание моторов от +6V до +12V (при надетом джампере, питание силовой и управляющей частей совместное)
питание моторов от +6V до +35V (при снятом джампере, питание силовой и управляющей частей раздельное). ВАЖНО: не забыть снять джампер, иначе при напряжении больше 12V стабилизатор питания управляющей части сгорит.
для регулировки скорости моторов на выходы «EN» подается ШИМ сигнал или ставится джампер, если регулировка не требуется
выводы INT1 и INT2 (первый двигатель), INT3 и INT4 (второй двигатель) задают направление вращение двигателями
Подключение к ардуино
При подключении нужно иметь в виду, что ШИМ на Ардуино Уно имеется только на ножках 3, 5, 6, 9, 10, 11. Ниже представлена схема раздельного питания силовой и управляющей части драйвера (джампер снят).
Код для ардуино
В данном скетче используется один двигатель, подключенный к пинам 3, 4, 5. Управляем скоростью вращения, меняя скважность посылаемого ШИМ сигнала. Значения скважности задаются функцией analogWrite (pin, число) , где число изменяется от 0 до 255.
int IN3 = 5; // Input3 подключен к выводу 5
int IN4 = 4;
int ENB = 3;
void setup()
{
pinMode (ENB, OUTPUT);
pinMode (IN3, OUTPUT);
pinMode (IN4, OUTPUT);
}
void loop()
{
// На пару выводов "IN" поданы разноименные сигналы, мотор готов к вращению
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
// подаем на вывод ENB управляюший ШИМ сигнал
analogWrite(ENB,55);
delay(2000);
analogWrite(ENB,105);
delay(2000);
analogWrite(ENB,255);
delay(2000);
// Останавливаем мотор подаем на вывод ENB сигнал низкого уровня.
// Состояние выводов "IN" роли не играет.
analogWrite(ENB,0);
delay(5000);
}
Следующий пример управляет двумя двигателями. Вращение в обе стороны с плавным нарастанием скорости.
int IN1 = 8;
int IN2 = 9;
int IN3 = 12;
int IN4 = 13;
int ENA = 10;
int ENB = 11;
int i;
void setup()
{
pinMode (ENA, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN4, OUTPUT);
pinMode (IN3, OUTPUT);
}
void loop()
{
digitalWrite (IN2, HIGH);
digitalWrite (IN1, LOW);
digitalWrite (IN4, HIGH);
digitalWrite (IN3, LOW);
for (i = 50; i <= 180; ++i)
{
analogWrite(ENA, i);
analogWrite(ENB, i);
delay(30);
}
analogWrite (ENA, 0);
analogWrite (ENB, 0);
delay(500);
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
for (i = 50; i <= 180; ++i)
{
analogWrite(ENA, i);
analogWrite(ENB, i);
delay(30);
}
analogWrite (ENA, 0);
analogWrite (ENB, 0);
delay(8000);
}