Загрузка данных
#include <Servo.h>
// =====================================================
// ПИНЫ ДЖОЙСТИКОВ
// =====================================================
#define JOY1_X A0
#define JOY1_Y A1
#define JOY2_X A2
#define JOY2_Y A3
#define JOY3_X A4
#define JOY3_Y A5
// =====================================================
// ПИНЫ СЕРВОПРИВОДОВ
// =====================================================
#define SERVO_BASE 3
#define SERVO_MIDDLE_1 5
#define SERVO_MIDDLE_2 6
#define SERVO_GRIP_1 9
#define SERVO_GRIP_2 10
// =====================================================
// СОЗДАЁМ ОБЪЕКТЫ СЕРВО
// =====================================================
Servo servoBase;
Servo servoMiddle1;
Servo servoMiddle2;
Servo servoGrip1;
Servo servoGrip2;
// =====================================================
// ТЕКУЩИЕ ПОЛОЖЕНИЯ СЕРВО
// =====================================================
float posBase = 90;
float posMiddle1 = 90;
float posMiddle2 = 90;
float posGrip1 = 90;
float posGrip2 = 90;
// =====================================================
// ЦЕЛЕВЫЕ ПОЛОЖЕНИЯ
// =====================================================
float targetBase = 90;
float targetMiddle1 = 90;
float targetMiddle2 = 90;
float targetGrip1 = 90;
float targetGrip2 = 90;
// =====================================================
// ОГРАНИЧЕНИЯ СЕРВО
// =====================================================
// ОБЯЗАТЕЛЬНО настрой их после первого запуска,
// чтобы механика не упиралась в крайние положения.
int BASE_MIN = 10;
int BASE_MAX = 170;
int MIDDLE1_MIN = 20;
int MIDDLE1_MAX = 160;
int MIDDLE2_MIN = 20;
int MIDDLE2_MAX = 160;
int GRIP1_MIN = 20;
int GRIP1_MAX = 160;
int GRIP2_MIN = 20;
int GRIP2_MAX = 160;
// =====================================================
// ЦЕНТР ДЖОЙСТИКА
// =====================================================
// У большинства джойстиков около 512.
// Если робот начинает двигаться сам,
// поменяй значения после калибровки.
int center1X = 512;
int center1Y = 512;
int center2X = 512;
int center2Y = 512;
int center3X = 512;
int center3Y = 512;
// =====================================================
// МЁРТВАЯ ЗОНА ДЖОЙСТИКА
// =====================================================
const int DEADZONE = 70;
// =====================================================
// СКОРОСТЬ ДВИЖЕНИЯ
// =====================================================
// Чем больше значение — тем быстрее робот.
float MAX_SPEED = 2.0;
// =====================================================
// НАПРАВЛЕНИЕ СЕРВО
// =====================================================
// false = обычное направление
// true = инвертированное направление
bool invertBase = false;
bool invertMiddle1 = false;
bool invertMiddle2 = true;
bool invertGrip1 = false;
bool invertGrip2 = true;
// =====================================================
// ФУНКЦИЯ ПОЛУЧЕНИЯ СКОРОСТИ ОТ ДЖОЙСТИКА
// =====================================================
float joystickSpeed(int value, int center)
{
int difference = value - center;
// Мёртвая зона
if (abs(difference) < DEADZONE)
{
return 0;
}
// Убираем мёртвую зону
if (difference > 0)
{
difference -= DEADZONE;
}
else
{
difference += DEADZONE;
}
// Преобразуем диапазон в скорость
float speed = (float)difference / (512 - DEADZONE);
speed *= MAX_SPEED;
// Ограничение
if (speed > MAX_SPEED)
speed = MAX_SPEED;
if (speed < -MAX_SPEED)
speed = -MAX_SPEED;
return speed;
}
// =====================================================
// ОБНОВЛЕНИЕ СЕРВО
// =====================================================
void updateServo(
Servo &servo,
float &position,
float target,
int minAngle,
int maxAngle
)
{
// Плавное приближение
position += (target - position) * 0.15;
// Ограничение
if (position < minAngle)
position = minAngle;
if (position > maxAngle)
position = maxAngle;
servo.write((int)position);
}
// =====================================================
// SETUP
// =====================================================
void setup()
{
Serial.begin(115200);
// Подключаем сервоприводы
servoBase.attach(SERVO_BASE);
servoMiddle1.attach(SERVO_MIDDLE_1);
servoMiddle2.attach(SERVO_MIDDLE_2);
servoGrip1.attach(SERVO_GRIP_1);
servoGrip2.attach(SERVO_GRIP_2);
// =================================================
// НАЧАЛЬНОЕ ПОЛОЖЕНИЕ
// =================================================
servoBase.write(90);
servoMiddle1.write(90);
servoMiddle2.write(90);
servoGrip1.write(90);
servoGrip2.write(90);
delay(1000);
Serial.println("ROBOT ARM STARTED");
}
// =====================================================
// LOOP
// =====================================================
void loop()
{
// ===================================================
// ЧИТАЕМ ДЖОЙСТИКИ
// ===================================================
int joy1X = analogRead(JOY1_X);
int joy1Y = analogRead(JOY1_Y);
int joy2X = analogRead(JOY2_X);
int joy2Y = analogRead(JOY2_Y);
int joy3X = analogRead(JOY3_X);
int joy3Y = analogRead(JOY3_Y);
// ===================================================
// ПОЛУЧАЕМ СКОРОСТЬ
// ===================================================
float speed1X = joystickSpeed(joy1X, center1X);
float speed1Y = joystickSpeed(joy1Y, center1Y);
float speed2X = joystickSpeed(joy2X, center2X);
float speed2Y = joystickSpeed(joy2Y, center2Y);
float speed3X = joystickSpeed(joy3X, center3X);
float speed3Y = joystickSpeed(joy3Y, center3Y);
// ===================================================
// ДЖОЙСТИК №1
//
// X = вращение основания
// Y = первое среднее серво
// ===================================================
if (invertBase)
targetBase -= speed1X;
else
targetBase += speed1X;
if (invertMiddle1)
targetMiddle1 -= speed1Y;
else
targetMiddle1 += speed1Y;
// ===================================================
// ДЖОЙСТИК №2
//
// X = второе среднее серво
// Y = дополнительное управление
// ===================================================
if (invertMiddle2)
targetMiddle2 -= speed2X;
else
targetMiddle2 += speed2X;
// Здесь Y второго джойстика пока используется
// для совместного движения двух средних сервоприводов.
targetMiddle1 += speed2Y * 0.5;
targetMiddle2 += speed2Y * 0.5;
// ===================================================
// ДЖОЙСТИК №3
//
// X = клешня
// Y = дополнительная функция
// ===================================================
if (invertGrip1)
targetGrip1 -= speed3X;
else
targetGrip1 += speed3X;
if (invertGrip2)
targetGrip2 -= speed3X;
else
targetGrip2 += speed3X;
// Y третьего джойстика пока не используется.
// ===================================================
// ОГРАНИЧЕНИЯ
// ===================================================
targetBase = constrain(
targetBase,
BASE_MIN,
BASE_MAX
);
targetMiddle1 = constrain(
targetMiddle1,
MIDDLE1_MIN,
MIDDLE1_MAX
);
targetMiddle2 = constrain(
targetMiddle2,
MIDDLE2_MIN,
MIDDLE2_MAX
);
targetGrip1 = constrain(
targetGrip1,
GRIP1_MIN,
GRIP1_MAX
);
targetGrip2 = constrain(
targetGrip2,
GRIP2_MIN,
GRIP2_MAX
);
// ===================================================
// ДВИГАЕМ СЕРВО
// ===================================================
updateServo(
servoBase,
posBase,
targetBase,
BASE_MIN,
BASE_MAX
);
updateServo(
servoMiddle1,
posMiddle1,
targetMiddle1,
MIDDLE1_MIN,
MIDDLE1_MAX
);
updateServo(
servoMiddle2,
posMiddle2,
targetMiddle2,
MIDDLE2_MIN,
MIDDLE2_MAX
);
updateServo(
servoGrip1,
posGrip1,
targetGrip1,
GRIP1_MIN,
GRIP1_MAX
);
updateServo(
servoGrip2,
posGrip2,
targetGrip2,
GRIP2_MIN,
GRIP2_MAX
);
// ===================================================
// НЕБОЛЬШАЯ ЗАДЕРЖКА
// ===================================================
delay(15);
}