Arduino Uno c LCD Keypad Shield (LCD Shield) удобно использовать для управления сервоприводом по нескольким причинам: на нем есть кнопки для управления и экран для отображения статуса привода, через него можно подключиться к цифровым пинам и портам питания Arduino, его использование сводит к минимуму количество соединений и избавляет от необходимости задействовать монтажную плату.
Существует несколько версий LCD Shield. Насколько я понимаю, они являются клонами плат от DFRobot: версия 1.1, версия 1.0. В этих платах все кнопки через резисторы R2 - R6 подключены к аналоговому входу А0.
У меня оказался клон версии 1.0, у которого уровни сигнала на входе А0 при нажатии кнопок заметно отличались от тех, которые указаны в примерах использования LCD Shield, поэтому пришлось определить их самостоятельно.
Для этого можно воспользоваться встроенным примером AnalogReadSerial.
Для этого можно воспользоваться встроенным примером AnalogReadSerial.
Достаточно загрузить его в Arduino Uno с установленным LCD Shield и открыть монитор порта: в нем отображается уровень сигнала со входа А0 - как раз то, что, нужно. Остается только нажать кнопки по очереди.
В моем случае кнопкам соответствуют следующие уровни сигнала на пине А0:
****************************************************************************
- SELECT - 640;
- LEFT - 410;
- DOWN - 256;
- UP - 100;
- RIGHT - 0;
- Кнопка не нажата - 1023.
Еще одно замечание по поводу LCD Shield. С помощью пина D10 можно управлять яркостью подсветки дисплея - для этого нужен PWM сигнал. При использовании библиотеки Servo такая возможность пропадает (PWM на пине D10 перестает работать).
Теперь можно переходить к управлению сервоприводом. Пример подключения привода к связке Arduino Uno - LCD Shield с использованием внешнего блока питания привода:
В общем случае, питание сервопривода можно подавать напрямую от платы Arduino через LCD Shield, подключив красный провод привода к пину 5V. Так как сервопривод MG996R достаточно мощный и в режиме удержания потребляет ток до 1.4 А, чтобы полностью раскрыть его потенциал я использую внешний источник для его питания. В этом случае провода VCC (красный) и GND (коричневый) сервопривода подключаются к выходу внешнего блока питания. Управляющий провод сервопривода (желтый) подключается к пину D2 LCD Shield (можно использовать любой другой цифровой пин). Для согласования уровня управляющего сигнала провод GND также должен быть подключен к LCD Shield.
В качестве примера я использую захват робо-руки Moveo - в этом случае работа сервопривода видна очень наглядно.
Для работы с захватом в зависимости от ситуации можно использовать два режима:
1. "захватил/отпустил" - в этом случае сервопривод перемещается между двумя заранее заданными положениями;
2. управление расстоянием между пальцами захвата - поворот сервопривода на произвольный угол.
Режим "захватил/отпустил". Скетч для данного режима.
****************************************************************************
В качестве примера я использую захват робо-руки Moveo - в этом случае работа сервопривода видна очень наглядно.
1. "захватил/отпустил" - в этом случае сервопривод перемещается между двумя заранее заданными положениями;
2. управление расстоянием между пальцами захвата - поворот сервопривода на произвольный угол.
Режим "захватил/отпустил". Скетч для данного режима.
****************************************************************************
#include <Servo.h>
#include <LiquidCrystal.h>
// Создание объекта для управления дисплеем
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// Определение переменных и идентификаторов для работы с кнопками
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
// Функция для определения нажатия кнопки
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // чтение данных со входа А0
// уровни для кнопок на моей плате: 0, 100, 256, 410, 640
// добавляю к этим значениям около 50 и проверяю какому из этих уровней соответствует входящий сигнал
if (adc_key_in > 1000) return btnNONE; // не нажата ни одна из кнопок, для ускорения работы проверка этого условия стоит на первом месте
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 150) return btnUP;
if (adc_key_in < 300) return btnDOWN;
if (adc_key_in < 460) return btnLEFT;
if (adc_key_in < 690) return btnSELECT;
return btnNONE; // если нет совпадений, возвращается отсутсвие нажатия
}
// Создание объекта для управления сервоприводом
Servo myservo;
// Переменная статуса сервопривода
bool Servo_state;
// Функция для освобождения захвата
void Servo_release() {
myservo.write(60); // перемещение сервопривода в позицию 60 градусов
Servo_state = false;
}
// Функция для активации захвата
void Servo_hold() {
myservo.write(170); // перемещение сервопривода в позицию 170 градусов
Servo_state = true;
}
void setup() {
// Инициализация сервопривода на пине D2 в позиции "отпустить"
myservo.attach(2);
Servo_release();
// Инициализация дисплея с указанием кол-ва символов и строк
lcd.begin(16, 2);
// Вывод сообщения на дисплей
lcd.setCursor(0,0);
lcd.print("Press SELECT");
lcd.setCursor(0,1);
lcd.print("Servo: FREE");
}
void loop() {
lcd_key = read_LCD_buttons(); // определение нажатия кнопки
if (lcd_key == btnSELECT) { // если нажата кнопка SELECT
lcd.setCursor(7,1); // установка курсора на 8 символ 2 строки
if (!Servo_state) { // если привод в позиции "отпустить" - переводим в позицию "захватить" и выводим соответствующее сообщение
Servo_hold();
lcd.print("HOLD");
}
else { // если привод в позиции "захватить" - переводим в позицию "отпустить"
Servo_release();
lcd.print("FREE");
}
delay(200); // 200 мс на обработку команды
}
}
Видео с демонстрацией работы скетча.
Вне зависимости от размеров объекта захват будет их удерживать, стремясь сомкнуть пальцы. В этом режиме привод перемещается с максимальной скоростью.
Второй режим - управление расстояния между пальцами захвата. Скетч для этого режима.
****************************************************************************
#include <Servo.h>
#include <LiquidCrystal.h>
// Создание объекта для управления дисплеем
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// Определение переменных и идентификаторов для работы с кнопками
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
// Функция для определения нажатия кнопки
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // чтение данных со входа А0
// уровни для кнопок на моей плате: 0, 100, 256, 410, 640
// добавляю к этим значениям около 50 и проверяю какому из этих уровней соответствует входящий сигнал
if (adc_key_in > 1000) return btnNONE; // не нажата ни одна из кнопок, для ускорения работы проверка этого условия стоит на первом месте
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 150) return btnUP;
if (adc_key_in < 300) return btnDOWN;
if (adc_key_in < 460) return btnLEFT;
if (adc_key_in < 690) return btnSELECT;
return btnNONE; // если нет совпадений, возвращается отсутсвие нажатия
}
// Создание объекта для управления сервоприводом
Servo myservo;
// Переменная для хранения позиции сервопривода
int pos = 60;
void setup() {
// Инициализация сервопривода на пине D2 и перевод в начальную позицию
myservo.attach(2);
myservo.write(pos);
// Инициализация дисплея с указанием кол-ва символов и строк
lcd.begin(16, 2);
// Вывод сообщения на дисплей
lcd.setCursor(0,0);
lcd.print("Press UP/DOWN");
lcd.setCursor(0,1);
lcd.print("Position: 60");
}
void loop() {
lcd_key = read_LCD_buttons(); // определение нажатия кнопки
if (lcd_key == btnUP) // если нажата кнопка UP
if (pos < 180) pos++; // если текущий угол меньше 180 градусов, увеличиваем его
if (lcd_key == btnDOWN) // если нажата кнопка DOWN
if (pos > 0) pos--; // если текущий угол больше 0 градусов, уменьшаем его
myservo.write(pos); // перемещение привода в новую позицию
// вывод данных на дисплей
lcd.setCursor(10,1);
lcd.print(pos);
if (pos < 100) {
lcd.setCursor(12,1);
lcd.print(" ");
}
if (pos < 10) {
lcd.setCursor(11,1);
lcd.print(" ");
}
delay(15); // время на перевод привода в заданную позицию
}
Последняя команда delay в цикле loop определяет скорость работы привода.
Видео с демонстрацией работы скетча (задержка 15 мс).
А это с задержкой 45 мс.
Спасибо за внимание! Let`s go design!





Заметила, что ни одна ссылка на документы у вас нерабочая (по крайней мере у меня не открылся ни один документ - я про ваш обновленный BOM, доработанные stl файлы, в данном посте про скетч). Есть ли возможность их обновить?
ОтветитьУдалить