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!
Комментарии
Отправить комментарий