산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇

부품 및 소모품

Runt Rover Half-pint 섀시 × 1
아두이노 UNO × 1
V5 쉴드 × 1
Female/Female 점퍼 와이어 × 1
L9110S 모터 드라이버 × 1
90° 싱글 앵글 채널 브라켓 (585424) × 1
경량 서보 허브, Futaba × 1
표준 그리퍼 키트 A (637094) × 1
MG995 서보 × 1
표준 서보 플레이트 × 1
90° 싱글 앵글 채널 브라켓 × 1
5슬롯 AA 홀더 × 1
AA 충전식 배터리 × 5
.750" 8-32 나일론 스페이서 × 2
.500" 6-32 나사 및 너트 × 8
.3125" 6-32 나사 × 8

앱 및 온라인 서비스

아두이노 IDE

프로젝트 소개

몇 달 전 아들이 원격 조종 로봇을 만들어달라고 했습니다. 원하는 목록을 줬는데, 관리 가능한 수준으로 좁혔죠 :) 결국 이렇게 만들었습니다...

이 프로젝트에서는 직접 섀시를 만들거나 다른 4WD 섀시를 써도 됩니다.

1단계: 필요한 소프트웨어

다운로드할 것들:

2단계: 하드웨어 자재 리스트

필요한 부품:

부품 다수는 이베이나 Sparkfun, Adafruit, ServoCity 같은 공급처에서 구매 가능합니다.

구매, 수집, 다운로드가 모두 끝났다면 빌드 시작!

3단계: 조립 - 섀시

섀시 동봉 설명서나 영상 따라 조립. 완료 후 이미지 같은 모습이어야 합니다. 컨트롤러 홀더 플레이트를 봇에 올릴 때 중간 구멍에 장착해 앞뒤 공간을 확보하세요.

주의: 더 이상 진행하기 전, 모터 손상 방지를 위해 4개 바퀴를 모두 분리하세요.

4단계: 그리퍼 조립

이 영상 지침 따라 그리퍼 조립. 완료 후 이미지 같은 모습.

5단계: 그리퍼 장착 - 1단계

90도 브라켓, 경량 서보 허브, .3125" 나사 4개 준비:

필요시 사진 참조.

정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇

6단계: 그리퍼 장착 - 2단계

완료 후 두 서보 와이어를 평평한 브라켓 구멍으로 통과시켜 봇 내부로 뺌.

자세한 건 사진 참조.

정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇

7단계: 전자장치 장착

정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇
정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇

8단계: 배선 - 모터

로봇 앞쪽이 자신을 향하지 않게 두고, 왼쪽 측 와이어들:

오른쪽 측 와이어들:

서보:

9단계: 블루투스 모듈 배선

10단계: 전원 연결

5 'AA' (또는 다른 6V 팩) 배터리 팩 전원선을 센서 쉴드 전원 스크류 터미널에 연결:

11단계: HC05/HC06 블루투스 모듈 설정

PC의 OS "제어판" 또는 "시스템" 패널에서 블루투스 장치 설정으로 들어가거나 구글 검색.

가능한 OS별 블루투스 설정 정보:

할당된 시리얼 포트 장치 이름 또는 번호를 메모해두세요.

12단계: 코드 업로드

배선 재확인 후, 코드 업로드. 아두이노 사이트의 IDE 설치 지침 참조.

IDE 설치 후 L9110 모터 드라이버 라이브러리 설치. STEP 1의 L9110Driver.zip 다운로드 후 아두이노 라이브러리 폴더에 압축 해제하거나 라이브러리 추가 방법 참조.

이제 IDE와 모터 드라이버 라이브러리 설치됐으니, STEP 1의 blue_t_slave.zip에서 로봇 코드를 아두이노 IDE로 로드. 이 단계에도 파일 포함돼 있습니다.

PC와 아두이노 USB 연결. Tools→Board 메뉴에서 보드 선택 (Uno). Tools→Port에서 COM 포트 선택. 업로드 버튼 클릭. 잘 됐다면 코드 업로드 완료, 안 되면 IDE 문제 해결 참조.

13단계: 파이썬 제어 애플리케이션 실행

이 단계의 zip 파일을 다운로드해 원하는 위치에 압축 해제. 명령 셸(터미널, cmd.exe 등)을 열고 압축 푼 디렉토리로 이동. python rover.py 입력하면 이미지 같은 창이 뜹니다. 안 뜨면 파이썬 에러 확인(라이브러리 누락 등). 파이썬 사이트 참고.

앱 실행되면 준비 완료.

봇 전원 켜기. 어댑터의 COM 포트 입력 후 "Connect" 버튼 클릭. 몇 초 후 다른 컨트롤들이 활성화되고 Connect 버튼이 비활성화되면 연결 성공. 블루투스 어댑터 연결 안 되면 구글 신의 도움 받으세요!

제어 앱은 마우스/키보드 모두 지원하며 사용법 간단.

키보드 컨트롤:

전진/후진 명령은 지속적(새 방향 명령이나 정지 명령까지 계속 이동). 90°/45° 회전은 일시적(딜레이 후 정지).

그리퍼 슬라이더는 자동 실행 안 됨. 해당 "Set" 버튼이나 키를 눌러야 실제 실행. 슬라이더 범위 0-180.

"Disconnect" 버튼으로 프로그램 중단. 봇 정지 및 그리퍼 홈 명령 전송.

정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇

코드

파이썬 드라이버 GUI Python
#!/usr/bin/env python
# Linux, BSD, Mac OSX에서는 chmod +x로 실행 가능하게 설정
###########
# Rover control app
# Written by Scott Beasley - 2015
# Free to use or modify. Enjoy.
###########
import sys
import serial
import time
from Tkinter import *
import tkFont
import tkMessageBox

class App(Frame):
    def createWidgets(self):
        self.connected = False
        self.message = StringVar()
        helv6 = tkFont.Font(family='Helvetica', size=6, weight='normal')
        self.frame = Frame(self.master)
        self.frame.pack()
        self.f1 = Frame(self.frame)
        self.l1 = Label(self.f1, text="Comm Port: ")
        self.l1.pack(side=LEFT)
        self.comm_entry = Entry(self.f1, bd=5, name="comm_entry")
        self.comm_entry.pack(side=LEFT)
        self.connectButton = Button(self.f1, text="Connect", command=self.SerialConnect, name="b_connect")
        self.connectButton.pack(side=LEFT)
        self.disconnectButton = Button(self.f1, text="Disconnect", command=self.SerialDisconnect, name="b_disconnect")
        self.disconnectButton.pack(side=RIGHT)
        self.f1.grid(row=0, column=0)
        self.f2 = LabelFrame(self.frame, bd=3, relief="groove", text="Ground Control")
        self.g_vert_fm = Frame(self.f2)
        self.grip_vert = Scale(self.g_vert_fm, from_=0, to=180)
        self.grip_vert.grid(row=0, column=0, rowspan=4, sticky=W)
        self.grip_vert_set = Button(self.g_vert_fm, text="Set", command=self.GripperY, name="b_grip_vert_set", width=1, height=2, font=helv6)
        self.grip_vert_set.grid(row=5, column=0, sticky=W)
        self.master.bind("y", self.GripperY)
        self.g_vert_fm.grid(row=0, column=0, rowspan=4, sticky=W)
        self.leftforwardButton = Button(self.f2, text="\\", command=self.TurnLeft45, name="b_left_forward")
        self.leftforwardButton.grid(row=0, column=1)
        self.master.bind("a", self.TurnLeft45)
        self.leftButton = Button(self.f2, text="<", command=self.TurnLeft, name="b_left")
        self.leftButton.grid(row=1, column=1)
        self.master.bind("", self.TurnLeft)
        self.rightforwardButton = Button(self.f2, text="/", command=self.TurnRight45, name="b_right_forward")
        self.rightforwardButton.grid(row=0, column=3)
        self.master.bind("s", self.TurnRight45)
        self.haltButton = Button(self.f2, text="Halt!", command=self.Halt, name="b_halt")
        self.haltButton.grid(row=1, column=2)
        self.master.bind("h", self.Halt)
        self.rightButton = Button(self.f2, text=">", command=self.TurnRight, name="b_right")
        self.rightButton.grid(row=1, column=3)
        self.master.bind("", self.TurnRight)
        self.upButton = Button(self.f2, text="^", command=self.Forward, name="b_forward")
        self.upButton.grid(row=0, column=2)
        self.master.bind("", self.Forward)
        self.leftdownButton = Button(self.f2, text="/", command=self.TurnRight45, name="b_left_down")
        self.leftdownButton.grid(row=2, column=1)
        self.downButton = Button(self.f2, text="V", command=self.Reverse, name="b_reverse")
        self.downButton.grid(row=2, column=2)
        self.master.bind("", self.Reverse)
        self.f2.grid(row=1, column=0, pady=25)
        self.rightdownButton = Button(self.f2, text="\\", command=self.TurnLeft45, name="b_right_down")
        self.rightdownButton.grid(row=2, column=3)
        self.g_horz_fm = Frame(self.f2)
        self.grip_horz = Scale(self.g_horz_fm, from_=0, to=180, orient=HORIZONTAL)
        self.grip_horz.grid(row=0, column=0, columnspan=7, sticky=E)
        self.grip_horz_set = Button(self.g_horz_fm, text="Set", command=self.GripperX, name="b_grip_horz_set", width=1, height=2, font=helv6)
        self.grip_horz_set.grid(row=0, column=8)
        self.master.bind("u", self.GripperX)
        self.g_horz_fm.grid(row=4, column=0, columnspan=7, sticky=E)
        self.master.bind("c", self.GripperHome)
        self.f3 = Frame(self.frame)
        self.l2 = Label(self.f3, text="Last action: ")
        self.l2.pack(side=LEFT)
        self.l3 = Label(self.f3, text=" ", textvariable=self.message)
        self.l3.pack(side=RIGHT)
        self.f3.grid(row=3, column=0, pady=8)

    def CtrlButtonsState(self, bstate):
        self.leftforwardButton.config(state=bstate)
        self.leftButton.config(state=bstate)
        self.rightforwardButton.config(state=bstate)
        self.rightButton.config(state=bstate)
        self.upButton.config(state=bstate)
        self.leftdownButton.config(state=bstate)
        self.downButton.config(state=bstate)
        self.rightdownButton.config(state=bstate)
        self.haltButton.config(state=bstate)
        self.disconnectButton.config(state=bstate)
        self.grip_horz.config(state=bstate)
        self.grip_vert.config(state=bstate)
        self.grip_horz_set.config(state=bstate)
        self.grip_vert_set.config(state=bstate)

    def ConnCtrlsState(self, bstate):
        self.connectButton.config(state=bstate)
        self.comm_entry.config(state=bstate)

    def SerialConnect(self):
        try:
            self.ser = serial.Serial(self.comm_entry.get(), 9600)
        except IOError:
            tkMessageBox.showerror("Invalid comm port", "Comm port not found.")
            return
        self.ConnCtrlsState(DISABLED)
        self.CtrlButtonsState(NORMAL)
        self.message.set("SerialConnect")
        self.connected = True
        time.sleep(3)

    def SerialDisconnect(self):
        try:
            self.send_cmd('h', "Halt!")
            time.sleep(1)
            self.ser.close()
        except IOError:
            print("Could not close port...")
        self.message.set("SerialDisconnect")
        self.ConnCtrlsState(NORMAL)
        self.CtrlButtonsState(DISABLED)
        self.connected = False
        time.sleep(2)

    def send_cmd(self, action, msg):
        if self.connected == True:
            for val in action:
                self.ser.write(val)
            self.ser.flush()
            self.message.set(msg)

    def TurnLeft(self, event=None):
        self.send_cmd('a', "Left")

    def TurnLeft45(self, event=None):
        self.send_cmd('q', "Left45")

    def TurnRight(self, event=None):
        self.send_cmd('s', "Right")

    def TurnRight45(self, event=None):
        self.send_cmd('e', "Right45")

    def Forward(self, event=None):
        self.send_cmd('w', "Up")

    def Reverse(self, event=None):
        self.send_cmd('z', "Down")

    def Halt(self, event=None):
        self.send_cmd('h', "Halt!")

    def GripperX(self, event=None):
        grp_change = ('>', chr(self.grip_horz.get()), chr(255))
        self.send_cmd(grp_change, "Gripper X")

    def GripperY(self, event=None):
        grp_change = ('^', chr(self.grip_vert.get()), chr(255))
        self.send_cmd(grp_change, "Gripper Y")

    def GripperHome(self, event=None):
        self.send_cmd(('c', chr(255)), "Gripper Home")

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()
        self.CtrlButtonsState(DISABLED)

def main():
    root = Tk()
    root.geometry("450x350")
    root.wm_title("Rover Control Center (RCC)")
    app = App(master=root)
    app.mainloop()

if __name__ == '__main__':
    main()
로버 코드 Arduino
/* Bluetooth Rover. 목표: 공중(또는 USB)을 통해 마법처럼 전달된 명령 따르기!
   Written by Scott Beasley - 2015
   Free to use or modify. Enjoy.
*/
/* L9110S 라이브러리 사용. L9110S H-브릿지와 호환.
   https://github.com/jscottb/L9110Driver 에서 다운로드하거나
   https://github.com에서 zip 클론 후 아카이브 파일명에서 '-master' 제거해 라이브러리 추가
*/
#include <L9110Driver.h>
#include <Servo.h>

#define SERVO_Y 2        // 그리퍼 Y 서보 핀
#define SERVO_CLAW 7     // 그리퍼 클로 서보 핀
#define pinAIN1 5        // I1 인터페이스
#define pinAIN2 6        // I2 인터페이스
#define pinBIN1 3        // I3 인터페이스
#define pinBIN2 11       // I4 인터페이스

// 속도 정의
#define MAXFORWARDSPEED 225
#define MAXBACKWARDSPEED 225
#define TOPSPEED 255     // 카펫/거친 표면에서 회전 보조용

// 각종 시간 지연
#define TURNDELAY 475
#define TURNDELAY45 235
#define BACKUPDELAY 400
#define SERVOMOVEDELAY 200
#define SERVOSEARCHDELAY 85

/* 전역 영역 */
L9110_Motor motor_left(pinAIN1, pinAIN2);
L9110_Motor motor_right(pinBIN1, pinBIN2);
Servo grip_y_servo;
Servo grip_servo;

void setup() {
  Serial.begin(9600);
  grip_y_servo.attach(SERVO_Y);
  grip_y_servo.write(90);
  grip_servo.attach(SERVO_CLAW);
  grip_servo.write(90);
  delay(500);
}

void loop() {
  byte command = 0, val = 0;
  if (Serial.available() > 0) {
    command = Serial.read();
  }
  switch (command) {
    case 'w': go_forward(); break;
    case 'z': go_backward(); break;
    case 'a': go_left(); delay(TURNDELAY); halt(); break;
    case 's': go_right(); delay(TURNDELAY); halt(); break;
    case 'q': go_left(); delay(TURNDELAY45); halt(); break;
    case 'e': go_right(); delay(TURNDELAY45); halt(); break;
    case 'h': halt(); break;
    case '>':
      val = Serial.read();
      grip_servo.write(constrain(val, 64, 179));
      break;
    case '^':
      val = Serial.read();
      grip_y_servo.write(constrain(val, 53, 179));
      break;
    case 'c':
      grip_y_servo.write(90);
      grip_servo.write(90);
      break;
    case 255:
      Serial.flush();
      break;
  }
  Serial.flush();
  delay(125);
}

void go_forward() {
  ramp_it(MAXFORWARDSPEED, FORWARD, FORWARD);
  motor_left.setSpeed(MAXFORWARDSPEED);
  motor_right.setSpeed(MAXFORWARDSPEED);
  motor_left.run(FORWARD|RELEASE);
  motor_right.run(FORWARD|RELEASE);
}

void go_backward() {
  ramp_it(MAXBACKWARDSPEED, BACKWARD, BACKWARD);
  motor_left.setSpeed(MAXBACKWARDSPEED);
  motor_right.setSpeed(MAXBACKWARDSPEED);
  motor_left.run(BACKWARD|RELEASE);
  motor_right.run(BACKWARD|RELEASE);
}

void go_left() {
  ramp_it(TOPSPEED, BACKWARD, FORWARD);
  motor_left.setSpeed(TOPSPEED);
  motor_right.setSpeed(TOPSPEED);
  motor_left.run(BACKWARD|RELEASE);
  motor_right.run(FORWARD|RELEASE);
}

void go_right() {
  ramp_it(TOPSPEED, FORWARD, BACKWARD);
  motor_left.setSpeed(TOPSPEED);
  motor_right.setSpeed(TOPSPEED);
  motor_left.run(FORWARD|RELEASE);
  motor_right.run(BACKWARD|RELEASE);
}

void halt() {
  motor_left.setSpeed(0);
  motor_right.setSpeed(0);
  motor_left.run(BRAKE);
  motor_right.run(BRAKE);
}

void ramp_it(uint8_t speed, uint8_t lf_dir, uint8_t rt_dir) {
  uint8_t ramp_val = 0, step_val = 0;
  step_val = abs(speed / 4);
  if (!speed) step_val = -step_val;
  for (uint8_t i = 0; i < 4; i++) {
    ramp_val += step_val;
    motor_left.setSpeed(ramp_val);
    motor_right.setSpeed(ramp_val);
    motor_left.run(lf_dir|RELEASE);
    motor_right.run(rt_dir|RELEASE);
    delay(25);
  }
}
L9110 드라이버

아두이노용 L9110 모터 드라이버: GitHub

커스텀 파트 및 인클로저

4wdgripperbt2.fzz

회로도

정밀 핸들링을 위한 고급 원격 제어 그리퍼 로봇

4wdgripperbt2.fzz

제조공정

  1. 스마트 홈 연동을 위한 다중 위치 온도 센서 시스템
  2. 862D+ 납땜 인두 컨트롤러 DIY: 정밀함과 신뢰성
  3. MotionSense: 아두이노와 ESP8266으로 만드는 스마트 침입 감지 시스템
  4. 3D 프린터 화재 예방: 스마트 센서 안전 시스템
  5. 아두이노 기반 척력 자기 부상: 간단 회로 & DIY 가이드
  6. 고성능 아두이노 기상 관측용 데이터 로거 제작 가이드
  7. ArduFarmBot 2부: 원격 IoT 제어 스테이션 구축하기
  8. CoroFence 열화상 감지기: Panasonic Grid-EYE & PIR 센서 IoT 연동
  9. 클라우드 모니터링: 실시간 자산 관리를 위한 원격 제어 시스템
  10. 현대 산업을 위한 원격 생산 제어의 5가지 핵심 이점