Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Сборка беспроводного манипулятора Arduino, управляемого со смартфона

Обзор проекта

Роботизированная рука 5 степеней свободы, управляется через Bluetooth (HC-05) с Android-приложения (MIT App Inventor). Режимы: ручное (слайдеры) и автоматическое (запись/воспроизведение последовательности поз).

Сборка беспроводного манипулятора Arduino, управляемого со смартфона

3D-модель и печать

Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона

Печаталось на Creality CR-10 (90% предсборка). Качество отличное за цену.

Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона

Механическая сборка

  1. База: серво MG996R → круглый рог → верхняя часть (2 болта).
  2. Плечо: серво → рог → следующее звено. Важно: на оси плеча резинка/пружина для компенсации веса.
  3. Локоть: аналогично.
  4. Запястье ролл/питч и захват: SG90, мелкая сборка на болтах M4.
Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона

Электрическая схема

Сборка беспроводного манипулятора Arduino, управляемого со смартфона

Компоненты

Прошивка Arduino

Библиотеки: SoftwareSerial (Bluetooth), Servo.h. Массивы для хранения до 50 поз.

#include <SoftwareSerial.h>
#include <Servo.h>

Servo servo01, servo02, servo03, servo04, servo05, servo06;
SoftwareSerial Bluetooth(3, 4); // RX, TX (Arduino←HC05_TX, Arduino→HC05_RX через делитель!)

int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos;
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos;
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50];
int speedDelay = 20, index = 0;
String dataIn = "";

void setup() {
  servo01.attach(5); servo02.attach(6); servo03.attach(7);
  servo04.attach(8); servo05.attach(9); servo06.attach(10);
  Bluetooth.begin(38400); Bluetooth.setTimeout(1); delay(20);

  // Начальная поза
  servo1PPos=90;  servo01.write(servo1PPos);
  servo2PPos=150; servo02.write(servo2PPos);
  servo3PPos=35;  servo03.write(servo3PPos);
  servo4PPos=140; servo04.write(servo4PPos);
  servo5PPos=85;  servo05.write(servo5PPos);
  servo6PPos=80;  servo06.write(servo6PPos);
}

Основной цикл: парсинг команд от приложения

void loop() {
  if (Bluetooth.available() > 0) {
    dataIn = Bluetooth.readString(); // Читаем строку

    // Серво 1 (основа) - префикс "s1"
    if (dataIn.startsWith("s1")) {
      int pos = dataIn.substring(2).toInt();
      moveServoSlow(servo01, servo1PPos, pos, 20);
      servo1PPos = pos;
    }
    // Серво 2 (плечо) - "s2"
    if (dataIn.startsWith("s2")) {
      int pos = dataIn.substring(2).toInt();
      moveServoSlow(servo02, servo2PPos, pos, 50);
      servo2PPos = pos;
    }
    // Серво 3 (локоть) - "s3"
    if (dataIn.startsWith("s3")) {
      int pos = dataIn.substring(2).toInt();
      moveServoSlow(servo03, servo3PPos, pos, 30);
      servo3PPos = pos;
    }
    // Серво 4 (запястье ролл) - "s4"
    if (dataIn.startsWith("s4")) {
      int pos = dataIn.substring(2).toInt();
      moveServoSlow(servo04, servo4PPos, pos, 30);
      servo4PPos = pos;
    }
    // Серво 5 (запястье питч) - "s5"
    if (dataIn.startsWith("s5")) {
      int pos = dataIn.substring(2).toInt();
      moveServoSlow(servo05, servo5PPos, pos, 30);
      servo5PPos = pos;
    }
    // Серво 6 (захват) - "s6"
    if (dataIn.startsWith("s6")) {
      int pos = dataIn.substring(2).toInt();
      moveServoSlow(servo06, servo6PPos, pos, 30);
      servo6PPos = pos;
    }

    // Кнопка SAVE - запомнить текущую позу
    if (dataIn.startsWith("SAVE")) {
      servo01SP[index] = servo1PPos;
      servo02SP[index] = servo2PPos;
      servo03SP[index] = servo3PPos;
      servo04SP[index] = servo4PPos;
      servo05SP[index] = servo5PPos;
      servo06SP[index] = servo6PPos;
      index++;
    }

    // Кнопка RUN - автоматический режим
    if (dataIn.startsWith("RUN")) {
      runServoSequence();
    }

    // Кнопка RESET - очистить запись
    if (dataIn == "RESET") {
      memset(servo01SP, 0, sizeof(servo01SP));
      memset(servo02SP, 0, sizeof(servo02SP));
      memset(servo03SP, 0, sizeof(servo03SP));
      memset(servo04SP, 0, sizeof(servo04SP));
      memset(servo05SP, 0, sizeof(servo05SP));
      memset(servo06SP, 0, sizeof(servo06SP));
      index = 0;
    }

    // Скорость - префикс "ss"
    if (dataIn.startsWith("ss")) {
      speedDelay = dataIn.substring(2).toInt();
    }
  }
}

Функция плавного движения сервы

void moveServoSlow(Servo &s, int from, int to, int stepDelay) {
  if (from > to) {
    for (int j = from; j >= to; j--) { s.write(j); delay(stepDelay); }
  } else if (from < to) {
    for (int j = from; j <= to; j++) { s.write(j); delay(stepDelay); }
  }
}

Автоматическое воспроизведение последовательности

void runServoSequence() {
  while (dataIn != "RESET") {
    for (int i = 0; i <= index - 2; i++) {
      // Проверка команд во время движения
      if (Bluetooth.available() > 0) {
        dataIn = Bluetooth.readString();
        if (dataIn == "PAUSE") {
          while (dataIn != "RUN") {
            if (Bluetooth.available() > 0) {
              dataIn = Bluetooth.readString();
              if (dataIn == "RESET") break;
            }
          }
        }
        if (dataIn.startsWith("ss")) {
          speedDelay = dataIn.substring(2).toInt();
        }
      }

      // Движение каждой сервы к следующей сохранённой позиции
      moveServoSlow(servo01, servo01SP[i], servo01SP[i+1], speedDelay);
      moveServoSlow(servo02, servo02SP[i], servo02SP[i+1], speedDelay);
      moveServoSlow(servo03, servo03SP[i], servo03SP[i+1], speedDelay);
      moveServoSlow(servo04, servo04SP[i], servo04SP[i+1], speedDelay);
      moveServoSlow(servo05, servo05SP[i], servo05SP[i+1], speedDelay);
      moveServoSlow(servo06, servo06SP[i], servo06SP[i+1], speedDelay);
    }
  }
}

Android-приложение (MIT App Inventor)

Сборка беспроводного манипулятора Arduino, управляемого со смартфона
Сборка беспроводного манипулятора Arduino, управляемого со смартфона

Файлы для скачивания: .aia (проект App Inventor) и .apk (готовое приложение).

Полный код Arduino (для копирования)

/* DIY Arduino Robot Arm Smartphone Control by Dejan, www.HowToMechatronics.com */
#include <SoftwareSerial.h>
#include <Servo.h>

Servo servo01, servo02, servo03, servo04, servo05, servo06;
SoftwareSerial Bluetooth(3, 4); // Arduino RX=3, TX=4 → HC-05 TX, RX

int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos;
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos;
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50];
int speedDelay = 20, index = 0;
String dataIn = "";

void setup() {
  servo01.attach(5); servo02.attach(6); servo03.attach(7);
  servo04.attach(8); servo05.attach(9); servo06.attach(10);
  Bluetooth.begin(38400); Bluetooth.setTimeout(1); delay(20);
  servo1PPos=90;  servo01.write(servo1PPos);
  servo2PPos=150; servo02.write(servo2PPos);
  servo3PPos=35;  servo03.write(servo3PPos);
  servo4PPos=140; servo04.write(servo4PPos);
  servo5PPos=85;  servo05.write(servo5PPos);
  servo6PPos=80;  servo06.write(servo6PPos);
}

void loop() {
  if (Bluetooth.available() > 0) {
    dataIn = Bluetooth.readString();

    if (dataIn.startsWith("s1")) { int pos=dataIn.substring(2).toInt(); moveServoSlow(servo01, servo1PPos, pos, 20); servo1PPos=pos; }
    if (dataIn.startsWith("s2")) { int pos=dataIn.substring(2).toInt(); moveServoSlow(servo02, servo2PPos, pos, 50); servo2PPos=pos; }
    if (dataIn.startsWith("s3")) { int pos=dataIn.substring(2).toInt(); moveServoSlow(servo03, servo3PPos, pos, 30); servo3PPos=pos; }
    if (dataIn.startsWith("s4")) { int pos=dataIn.substring(2).toInt(); moveServoSlow(servo04, servo4PPos, pos, 30); servo4PPos=pos; }
    if (dataIn.startsWith("s5")) { int pos=dataIn.substring(2).toInt(); moveServoSlow(servo05, servo5PPos, pos, 30); servo5PPos=pos; }
    if (dataIn.startsWith("s6")) { int pos=dataIn.substring(2).toInt(); moveServoSlow(servo06, servo6PPos, pos, 30); servo6PPos=pos; }

    if (dataIn.startsWith("SAVE")) { servo01SP[index]=servo1PPos; servo02SP[index]=servo2PPos; servo03SP[index]=servo3PPos; servo04SP[index]=servo4PPos; servo05SP[index]=servo5PPos; servo06SP[index]=servo6PPos; index++; }
    if (dataIn.startsWith("RUN")) { runServoSequence(); }
    if (dataIn == "RESET") { memset(servo01SP,0,sizeof(servo01SP)); memset(servo02SP,0,sizeof(servo02SP)); memset(servo03SP,0,sizeof(servo03SP)); memset(servo04SP,0,sizeof(servo04SP)); memset(servo05SP,0,sizeof(servo05SP)); memset(servo06SP,0,sizeof(servo06SP)); index=0; }
    if (dataIn.startsWith("ss")) { speedDelay = dataIn.substring(2).toInt(); }
  }
}

void moveServoSlow(Servo &s, int from, int to, int stepDelay) {
  if (from > to) for (int j=from; j>=to; j--) { s.write(j); delay(stepDelay); }
  else if (from < to) for (int j=from; j<=to; j++) { s.write(j); delay(stepDelay); }
}

void runServoSequence() {
  while (dataIn != "RESET") {
    for (int i=0; i<=index-2; i++) {
      if (Bluetooth.available() > 0) {
        dataIn = Bluetooth.readString();
        if (dataIn == "PAUSE") {
          while (dataIn != "RUN") {
            if (Bluetooth.available() > 0) { dataIn = Bluetooth.readString(); if (dataIn == "RESET") break; }
          }
        }
        if (dataIn.startsWith("ss")) speedDelay = dataIn.substring(2).toInt();
      }
      moveServoSlow(servo01, servo01SP[i], servo01SP[i+1], speedDelay);
      moveServoSlow(servo02, servo02SP[i], servo02SP[i+1], speedDelay);
      moveServoSlow(servo03, servo03SP[i], servo03SP[i+1], speedDelay);
      moveServoSlow(servo04, servo04SP[i], servo04SP[i+1], speedDelay);
      moveServoSlow(servo05, servo05SP[i], servo05SP[i+1], speedDelay);
      moveServoSlow(servo06, servo06SP[i], servo06SP[i+1], speedDelay);
    }
  }
}

Заключение

Полный цикл: 3D-печать, механика, электроника, прошивка, Android-приложение. Проект демонстрирует интеграцию механики, встраиваемых систем и мобильной разработки. Можно расширить: добавить датчики силы, обратную связь по положению, запись траекторий по обучению (teaching pendant).

Производственный процесс

  1. Умная копилка: управление монетоприёмником на Arduino Nano
  2. Умный вольтметр на Arduino и смартфоне — простое DIY-проект
  3. Удаленное IoT-управление самодельной манипулятором
  4. Робот-ускользатор на сервоприводе: сборка на Arduino и HC-SR04
  5. Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
  6. Роботизированная рука 6 степеней свободы на Arduino Mega с управлением через Nunchuk
  7. Управление двумя шаговыми двигателями через джойстик на Arduino Nano — простой урок (Visuino)
  8. MobBob: Самостоятельная сборка Arduino-робота под управлением Android-смартфона
  9. LittleArm 2C: 3D-печатаемый робот-манипулятор на Arduino для STEM-обучения
  10. Yama Seiki GA-2000CR: компактный токарный центр с роботом-манипулятором и паллетной системой