====== Электронное приложение к набору «IO.KIT Робот Ампи: Захват» ======
На этой странице ты найдёшь все нужные материалы для проектов набора [[amp>product/io-kit-robot-ampie-gripper?utm_source=man&utm_campaign=io-kit-robot-ampie-gripper&utm_medium=wiki|Робот Ампи: Захват]] из серии [[amp>collection/io-kits?utm_source=man&utm_campaign=io-kit-robot-ampie-gripper&utm_medium=wiki|IO.KIT]]:
* Схему подключения модулей.
* Исходный код программ (копируй его в редактор Arduino IDE).
* Дополнительные материалы: программные библиотеки, даташиты и т. п.
**Обрати внимание**
Для сборки и функционирования руки робота Ампи тебе понадобится [[amp>product/io-kit-basic?utm_source=man&utm_campaign=io-kit-robot-ampie-gripper&utm_medium=wiki|IO.KIT Базовый]]!
===== Схема =====
{{ :kits:io-kit:robot-ampie-gripper:io-kit-robot-ampie-gripper-drawing-wiring.png?nolink |}}
===== Проекты =====
Прежде чем приступать к экспериментам, нужно подготовить свой компьютер:
* Установи среду программирования [[https://amperka.ru/page/arduino-ide?utm_source=announce&utm_campaign=io-kit-robot-ampie-gripper&utm_medium=wiki|Arduino IDE]] и копируй туда готовый код проектов.
* Установи [[#библиотеки|дополнительные библиотеки]] для Arduino IDE, пользуясь [[программирование:библиотеки|нашим руководством]].
**Драйвер чипа CH340**
Установи [[articles:driver-ch340|драйвер CH340 для Windows]] или [[projects:installing-the-ch340-on-linux|Linux]], чтобы твой компьютер мог корректно распознать и прошить плату Iskra Nano.
==== №1. Инициализация захвата ====
// Подключаем библиотеку для работы с сервоприводом
#include
// Создаём объект сервопривода с клешнёй захвата
Servo servoGripper;
// Даём понятное имя светодиоду на пине 10
constexpr uint8_t LED_PIN = 10;
// Даём понятное имя пину A1 с сервоприводом клешни
constexpr uint8_t SERVO_GRIPPER_PIN = A1;
// Задаём максимально доступные углы поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_OPEN = 30;
constexpr int ANGLE_GRIPPER_CLOSED = 90;
// Вычисляем средний угол поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_MID = (ANGLE_GRIPPER_OPEN + ANGLE_GRIPPER_CLOSED) / 2;
// Создаём константу для хранения паузы сервопривода при каждом градусе поворота
constexpr int DELAY_SWEEP = 20;
// Создаём константу для хранения паузы сервопривода между поворотами
constexpr int DELAY_STOP = 1000;
// Прототип функции плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep = 20);
void setup() {
// Настраиваем пин со светодиодом в режим выхода
pinMode(LED_PIN, OUTPUT);
// Включаем световую индикацию старта работы
ledStart();
// Подключаем сервопривод с клешнёй захвата
servoGripper.attach(SERVO_GRIPPER_PIN);
// Устанавливаем начальное состояние клешни в среднее положение
servoGripper.write(ANGLE_GRIPPER_MID);
// Выжидаем паузу после инициализации клешни
delay(1000);
// Устанавливаем плавно состояние клешни в закрытое положение
servoWriteSmooth(ANGLE_GRIPPER_CLOSED);
}
void loop() {
}
// Функция светодиодной индикации старта работы
void ledStart() {
// Перебираем значения от 0 до 2
for (int i = 0; i < 3; i++) {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Ждём 300 мс
delay(300);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Ждём 300 мс
delay(300);
}
}
// Функция плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep) {
// Считываем текущий угол сервопривода
int angleNow = servoGripper.read();
// Если текущий угол меньше нового
if (angleNow < angleNew) {
// Увеличиваем значения угла от текущего до нового
for (int angle = angleNow; angle <= angleNew; angle++) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow > angleNew) {
// Если текущий угол меньше нового
// Уменьшаем значения угла от текущего до нового
for (int angle = angleNow; angle >= angleNew; angle--) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow == angleNew) {
// Если текущий угол совпадает с новым
// Ничего не делаем и выходим из функции
return true;
}
}
==== №2. Захват с размахом ====
// Подключаем библиотеку для работы с сервоприводом
#include
// Создаём объект сервопривода с клешнёй захвата
Servo servoGripper;
// Даём понятное имя светодиоду на пине 10
constexpr uint8_t LED_PIN = 10;
// Даём понятное имя пину A1 с сервоприводом клешни
constexpr uint8_t SERVO_GRIPPER_PIN = A1;
// Задаём максимально доступные углы поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_OPEN = 30;
constexpr int ANGLE_GRIPPER_CLOSED = 90;
// Вычисляем средний угол поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_MID = (ANGLE_GRIPPER_OPEN + ANGLE_GRIPPER_CLOSED) / 2;
// Создаём константу для хранения паузы сервопривода при каждом градусе поворота
constexpr int DELAY_SWEEP = 20;
// Создаём константу для хранения паузы сервопривода между поворотами
constexpr int DELAY_STOP = 1000;
// Прототип функции плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep = 20);
void setup() {
// Настраиваем пин со светодиодом в режим выхода
pinMode(LED_PIN, OUTPUT);
// Включаем световую индикацию старта работы
ledStart();
// Подключаем сервопривод с клешнёй захвата
servoGripper.attach(SERVO_GRIPPER_PIN);
// Устанавливаем начальное состояние клешни в среднее положение
servoGripper.write(ANGLE_GRIPPER_MID);
// Выжидаем паузу после инициализации клешни
delay(1000);
}
void loop() {
// Устанавливаем плавно состояние клешни в открытое положение
servoWriteSmooth(ANGLE_GRIPPER_OPEN, DELAY_SWEEP);
// Выжидаем паузу
delay(DELAY_STOP);
// Устанавливаем плавно состояние клешни в закрытое положение
servoWriteSmooth(ANGLE_GRIPPER_CLOSED, DELAY_SWEEP);
// Выжидаем паузу
delay(DELAY_STOP);
}
// Функция светодиодной индикации старта работы
void ledStart() {
// Перебираем значения от 0 до 2
for (int i = 0; i < 3; i++) {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Ждём 300 мс
delay(300);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Ждём 300 мс
delay(300);
}
}
// Функция плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep) {
// Считываем текущий угол сервопривода
int angleNow = servoGripper.read();
// Если текущий угол меньше нового
if (angleNow < angleNew) {
// Увеличиваем значения угла от текущего до нового
for (int angle = angleNow; angle <= angleNew; angle++) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow > angleNew) {
// Если текущий угол меньше нового
// Уменьшаем значения угла от текущего до нового
for (int angle = angleNow; angle >= angleNew; angle--) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow == angleNew) {
// Если текущий угол совпадает с новым
// Ничего не делаем и выходим из функции
return true;
}
}
==== №3. Захват с кнопкой ====
// Подключаем библиотеку для работы с сервоприводом
#include
// Подключаем библиотеку для работы с кнопкой
#include
// Создаём объект сервопривода с клешнёй захвата
Servo servoGripper;
// Создаём объект кнопки на пине 2
TroykaButton button(2);
// Даём понятное имя светодиоду на пине 10
constexpr uint8_t LED_PIN = 10;
// Даём понятное имя пину A1 с сервоприводом клешни
constexpr uint8_t SERVO_GRIPPER_PIN = A1;
// Задаём максимально доступные углы поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_OPEN = 30;
constexpr int ANGLE_GRIPPER_CLOSED = 90;
// Вычисляем средний угол поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_MID = (ANGLE_GRIPPER_OPEN + ANGLE_GRIPPER_CLOSED) / 2;
// Создаём константу для хранения паузы сервопривода при каждом градусе поворота
constexpr int DELAY_SWEEP = 20;
// Создаём константу для хранения паузы сервопривода между поворотами
constexpr int DELAY_STOP = 1000;
// Создаём перечисление состояний захвата с соответствующей переменной
enum {
GRIPPER_OPEN, // Захват открыт
GRIPPER_CLOSED, // Захват закрыт
} gripperState;
// Прототип функции плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep = 20);
void setup() {
// Инициализируем кнопку
button.begin();
// Настраиваем пин со светодиодом в режим выхода
pinMode(LED_PIN, OUTPUT);
// Включаем световую индикацию старта работы
ledStart();
// Подключаем сервопривод с клешнёй захвата
servoGripper.attach(SERVO_GRIPPER_PIN);
// Устанавливаем начальное состояние клешни в среднее положение
servoGripper.write(ANGLE_GRIPPER_MID);
// Выжидаем паузу после инициализации клешни
delay(1000);
// Устанавливаем режим «Захват открыт»
gripperState = GRIPPER_OPEN;
}
void loop() {
// Считываем данные с кнопки
button.read();
// Определяем нажатие кнопки
if (button.justPressed()) {
// Если установлен режим «Захват открыт»
if (gripperState == GRIPPER_OPEN) {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Устанавливаем плавно состояние клешни в закрытое положение
servoWriteSmooth(ANGLE_GRIPPER_CLOSED, DELAY_SWEEP);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Устанавливаем режим «Захват закрыт»
gripperState = GRIPPER_CLOSED;
} else if (gripperState == GRIPPER_CLOSED) {
// Если установлен режим «Захват закрыт»
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Устанавливаем плавно состояние клешни в открытое положение
servoWriteSmooth(ANGLE_GRIPPER_OPEN, DELAY_SWEEP);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Устанавливаем режим «Захват открыт»
gripperState = GRIPPER_OPEN;
}
}
}
// Функция светодиодной индикации старта работы
void ledStart() {
// Перебираем значения от 0 до 2
for (int i = 0; i < 3; i++) {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Ждём 300 мс
delay(300);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Ждём 300 мс
delay(300);
}
}
// Функция плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep) {
// Считываем текущий угол сервопривода
int angleNow = servoGripper.read();
// Если текущий угол меньше нового
if (angleNow < angleNew) {
// Увеличиваем значения угла от текущего до нового
for (int angle = angleNow; angle <= angleNew; angle++) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow > angleNew) {
// Если текущий угол меньше нового
// Уменьшаем значения угла от текущего до нового
for (int angle = angleNow; angle >= angleNew; angle--) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow == angleNew) {
// Если текущий угол совпадает с новым
// Ничего не делаем и выходим из функции
return true;
}
}
==== №4. Ловкий захват ====
// Подключаем библиотеку для работы с сервоприводом
#include
// Создаём объект сервопривода с клешнёй захвата
Servo servoGripper;
// Даём понятное имя светодиоду на пине 10
constexpr uint8_t LED_PIN = 10;
// Даём понятное имя потенциометру на пине A0
constexpr uint8_t POT_PIN = A0;
// Даём понятное имя пину A1 с сервоприводом клешни
constexpr uint8_t SERVO_GRIPPER_PIN = A1;
// Задаём максимально доступные углы поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_OPEN = 30;
constexpr int ANGLE_GRIPPER_CLOSED = 90;
// Вычисляем средний угол поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_MID = (ANGLE_GRIPPER_OPEN + ANGLE_GRIPPER_CLOSED) / 2;
// Создаём константу для хранения паузы сервопривода при каждом градусе поворота
constexpr int DELAY_SWEEP = 20;
// Создаём константу для хранения паузы сервопривода между поворотами
constexpr int DELAY_STOP = 1000;
// Прототип функции плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep = 20);
void setup() {
// Настраиваем пин со светодиодом в режим выхода
pinMode(LED_PIN, OUTPUT);
// Настраиваем пин с потенциометром в режим входа
pinMode(POT_PIN, INPUT);
// Включаем световую индикацию старта работы
ledStart();
// Подключаем сервопривод с клешнёй захвата
servoGripper.attach(SERVO_GRIPPER_PIN);
// Устанавливаем начальное состояние клешни в среднее положение
servoGripper.write(ANGLE_GRIPPER_MID);
// Выжидаем паузу после инициализации клешни
delay(1000);
}
void loop() {
// Контролируем клешню с помощью потенциометра
remoteHandlerGripperPot();
}
// Функция контроля клешнёй с помощью потенциометра
void remoteHandlerGripperPot() {
// Считываем аналоговый сигнал с потенциометра
int rotation = analogRead(POT_PIN);
// Преобразуем диапазон значений с потенциометра [0; 1023]
// в диапазон значений угла сервопривода клешни [ANGLE_GRIPPER_OPEN; ANGLE_GRIPPER_CLOSED]
int angle = map(rotation, 0, 1023, ANGLE_GRIPPER_OPEN, ANGLE_GRIPPER_CLOSED);
// Выдаём результат на клешню
servoGripper.write(angle);
}
// Функция светодиодной индикации старта работы
void ledStart() {
// Перебираем значения от 0 до 2
for (int i = 0; i < 3; i++) {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Ждём 300 мс
delay(300);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Ждём 300 мс
delay(300);
}
}
// Функция плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep) {
// Считываем текущий угол сервопривода
int angleNow = servoGripper.read();
// Если текущий угол меньше нового
if (angleNow < angleNew) {
// Увеличиваем значения угла от текущего до нового
for (int angle = angleNow; angle <= angleNew; angle++) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow > angleNew) {
// Если текущий угол меньше нового
// Уменьшаем значения угла от текущего до нового
for (int angle = angleNow; angle >= angleNew; angle--) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow == angleNew) {
// Если текущий угол совпадает с новым
// Ничего не делаем и выходим из функции
return true;
}
}
==== №5. Захват с пультом ====
// Подключаем библиотеку для работы с сервоприводом
#include
// Подключаем библиотеку для работы с кнопкой
#include
// Создаём объект сервопривода с клешнёй захвата
Servo servoGripper;
// Создаём объект кнопки на пине 2
TroykaButton button(2);
// Даём понятное имя светодиоду на пине 10
constexpr uint8_t LED_PIN = 10;
// Даём понятное имя потенциометру на пине A0
constexpr uint8_t POT_PIN = A0;
// Даём понятное имя пину A1 с сервоприводом клешни
constexpr uint8_t SERVO_GRIPPER_PIN = A1;
// Задаём максимально доступные углы поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_OPEN = 30;
constexpr int ANGLE_GRIPPER_CLOSED = 90;
// Вычисляем средний угол поворота сервопривода клешни
constexpr int ANGLE_GRIPPER_MID = (ANGLE_GRIPPER_OPEN + ANGLE_GRIPPER_CLOSED) / 2;
// Создаём константу для хранения паузы сервопривода при каждом градусе поворота
constexpr int DELAY_SWEEP = 20;
// Создаём константу для хранения паузы сервопривода между поворотами
constexpr int DELAY_STOP = 1000;
// Создаём перечисление состояний захвата с соответствующей переменной
enum {
GRIPPER_ON, // Захват включен
GRIPPER_OFF, // Захват выключен
} gripperState;
// Прототип функции плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep = 20);
void setup() {
// Инициализируем кнопку
button.begin();
// Настраиваем пин со светодиодом в режим выхода
pinMode(LED_PIN, OUTPUT);
// Настраиваем пин с потенциометром в режим входа
pinMode(POT_PIN, INPUT);
// Включаем световую индикацию старта работы
ledStart();
// Подключаем сервопривод с клешнёй захвата
servoGripper.attach(SERVO_GRIPPER_PIN);
// Устанавливаем начальное состояние клешни в среднее положение
servoGripper.write(ANGLE_GRIPPER_MID);
// Выжидаем паузу после инициализации клешни
delay(1000);
// Устанавливаем режим «Захват выключен»
gripperState = GRIPPER_OFF;
}
void loop() {
// Если захват включен
if (gripperState == GRIPPER_ON) {
// Переходим в функцию обработки режима «Захват включен»
handleGripperOn();
}
// Если захват выключен
if (gripperState == GRIPPER_OFF) {
// Переходим в функцию обработки режима «Захват выключен»
handleGripperOff();
}
}
// Функция обработки режима «Захват выключен»
void handleGripperOff() {
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Ожидаем нажатие на кнопку
do {
// Считываем состояние с кнопки
button.read();
} while (!button.isClick());
// Устанавливаем режим «Захват включен»
gripperState = GRIPPER_ON;
}
// Функция обработки режима «Захват включен»
void handleGripperOn() {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Плавно устанавливаем состояние клешни из положения потенциометра
remoteHandlerGripperPotSmooth();
// Ожидаем нажатие на кнопку
do {
// Устанавливаем состояние клешни из положения потенциометра
remoteHandlerGripperPot();
// Считываем состояние с кнопки
button.read();
} while (!button.isClick());
// Устанавливаем плавно состояние клешни в закрытое положение
servoWriteSmooth(ANGLE_GRIPPER_CLOSED);
// Устанавливаем режим «Захват выключен»
gripperState = GRIPPER_OFF;
}
// Функция установки состояние клешни из положения потенциометра
void remoteHandlerGripperPot() {
// Считываем аналоговый сигнал с потенциометра
int rotation = analogRead(POT_PIN);
// Преобразуем диапазон значений с потенциометра [0; 1023]
// в диапазон значений угла сервопривода клешни [ANGLE_GRIPPER_OPEN; ANGLE_GRIPPER_CLOSED]
int angle = map(rotation, 0, 1023, ANGLE_GRIPPER_OPEN, ANGLE_GRIPPER_CLOSED);
// Выдаём результат на клешню
servoGripper.write(angle);
}
// Функция плавной установки состояние клешни из положения потенциометра
void remoteHandlerGripperPotSmooth() {
// Считываем аналоговый сигнал с потенциометра
int rotation = analogRead(POT_PIN);
// Преобразуем диапазон значений с потенциометра [0; 1023]
// в диапазон значений угла сервопривода клешни [ANGLE_GRIPPER_OPEN; ANGLE_GRIPPER_CLOSED]
int angle = map(rotation, 0, 1023, ANGLE_GRIPPER_OPEN, ANGLE_GRIPPER_CLOSED);
// Выдаём результат на клешню
servoWriteSmooth(angle);
}
// Функция светодиодной индикации старта работы
void ledStart() {
// Перебираем значения от 0 до 2
for (int i = 0; i < 3; i++) {
// Зажигаем светодиод
digitalWrite(LED_PIN, HIGH);
// Ждём 300 мс
delay(300);
// Гасим светодиод
digitalWrite(LED_PIN, LOW);
// Ждём 300 мс
delay(300);
}
}
// Функция плавной установки угла сервопривода
void servoWriteSmooth(int angleNew, int delaySweep) {
// Считываем текущий угол сервопривода
int angleNow = servoGripper.read();
// Если текущий угол меньше нового
if (angleNow < angleNew) {
// Увеличиваем значения угла от текущего до нового
for (int angle = angleNow; angle <= angleNew; angle++) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow > angleNew) {
// Если текущий угол меньше нового
// Уменьшаем значения угла от текущего до нового
for (int angle = angleNow; angle >= angleNew; angle--) {
// Отправляем текущий угол на сервопривод
servoGripper.write(angle);
// Выжидаем паузу на каждом градусе поворота
delay(delaySweep);
}
} else if (angleNow == angleNew) {
// Если текущий угол совпадает с новым
// Ничего не делаем и выходим из функции
return true;
}
}
===== Оглавление =====
* [[amp>collection/io-kits?utm_source=man&utm_campaign=io-kit-robot-ampie-chassis&utm_medium=wiki|Наборы IO.KIT]] в магазине
* [[kits:io-kit|Электронные материалы IO.KIT]]
===== Ресурсы =====
==== Софт ====
* [[amp>page/arduino-ide?utm_source=announce&utm_campaign=arduino&utm_medium=wiki |Страница загрузки Arduino IDE]]
==== Библиотеки ====
* [[https://www.arduino.cc/reference/en/libraries/servo/|Servo]]
* [[https://github.com/amperka/TroykaButton|TroykaButton]]