⚡ คำสั่งและสูตรลัดที่ใช้บ่อย
รวมคำสั่ง Python, Terminal, ขีดจำกัด, ตาราง GPIO และเทคนิคที่ใช้บ่อยกับ myCobot 280 JN เปิดดูข้างๆ ตอนเขียนโค้ดได้เลย
การเชื่อมต่อ (Setup)
เริ่มต้นเชื่อมต่อ boilerplate ทุกสคริปต์
from pymycobot import MyCobot280
import time
mc = MyCobot280('/dev/ttyTHS1', 1000000)
time.sleep(0.5) # รอ serial พร้อม
print(mc.is_power_on()) # ทดสอบว่าเชื่อมต่อได้
mc.power_on() # ปลดล็อก servo
time.sleep(0.5)
# ... ทำงานของคุณ ...
mc.release_all_servos() # ปล่อยทุก servo (manual mode)
# หรือ mc.power_off() — ตัดไฟ servo (ป้องกันร้อน)
เลือก Serial Port ที่ถูก
| Jetson Nano (มาตรฐาน) | /dev/ttyTHS1 |
|---|---|
| Jetson Nano (USB-UART) | /dev/ttyUSB0 |
| Raspberry Pi | /dev/ttyAMA0 |
| macOS | /dev/tty.usbserial-* |
| Windows | COM3 / COM4 ... |
| Baudrate | 1000000 เสมอ (1 Mbps) |
การเคลื่อนไหว (Motion API)
ส่งแขนกลับตำแหน่ง Home (zero pose)
mc.send_angles([0, 0, 0, 0, 0, 0], 50)
# [angle×6 (องศา)], speed 1-100
ส่งทีละข้อต่อ
mc.send_angle(1, 90, 30)
# joint_id (1-6), angle, speed
อ่านตำแหน่งปัจจุบัน
angles = mc.get_angles()
# → [j1, j2, j3, j4, j5, j6] องศา
coords = mc.get_coords()
# → [x, y, z, rx, ry, rz] mm + องศา
เคลื่อนที่ในพิกัด Cartesian
mc.send_coords(
[150, 0, 200, -180, 0, 0],
40, # speed 1-100
1 # 0=angular, 1=linear
)
รอจนถึงตำแหน่ง
while mc.is_moving() == 1:
time.sleep(0.1)
# หรือ: mc.sync_send_angles([...], 50)
หยุดทันที (Emergency Stop)
mc.stop()
# หยุดการเคลื่อนที่ปัจจุบันแบบ soft-stop
⚠️
เรื่องสำคัญ Speed
ค่า speed เป็น 1-100 ไม่ใช่ deg/sec.
ตอน demo ใช้ 30-50 ปลอดภัย; ค่า 80+ เร็วมากและกระตุก
ขีดจำกัดข้อต่อ (Joint Limits)
| ข้อต่อ | ชื่อ | ขีดจำกัด (องศา) | หมายเหตุ |
|---|---|---|---|
| J1 | Base (หมุนตัว) | −165 ถึง +165 | หมุนแกนตั้ง |
| J2 | Shoulder | −165 ถึง +165 | เงยขึ้น/ก้มลง |
| J3 | Elbow | −165 ถึง +165 | พับศอก |
| J4 | Wrist 1 | −165 ถึง +165 | หมุนข้อมือแกน 1 |
| J5 | Wrist 2 | −165 ถึง +165 | หมุนข้อมือแกน 2 |
| J6 | Flange | −175 ถึง +175 | หน้าจานหมุน |
💡
เช็คก่อนส่งคำสั่ง
ใส่ guard ในโค้ดเสมอ แขนจะ ฝืน ค่าเกินขีดจำกัดและรายงาน error
def safe_send(angles):
limits = [165, 165, 165, 165, 165, 175]
for i, a in enumerate(angles):
if abs(a) > limits[i]:
raise ValueError(f"J{i+1}={a} เกินขีดจำกัด ±{limits[i]}")
mc.send_angles(angles, 50)
พื้นที่ทำงาน (Workspace)
| Reach สูงสุด | 280 mm (จากฐาน) |
|---|---|
| Payload (รวม end-effector) | 250 g |
| ความแม่นยำซ้ำ | ±0.5 mm |
| น้ำหนักแขน | 1,030 g |
หัวจับและปั๊มดูด (Gripper / Vacuum)
Adaptive Gripper (ขับด้วย I2C)
mc.set_gripper_state(0, 50) # เปิด, speed 50
mc.set_gripper_state(1, 50) # ปิด
# ปรับ % การปิด
mc.set_gripper_value(20, 50) # 0=ปิดสุด, 100=เปิดสุด
Vacuum Pump (ขับด้วย GPIO)
import Jetson.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
PUMP_PIN = 20 # หรือพินที่ต่อจริง
VALVE_PIN = 21
GPIO.setup(PUMP_PIN, GPIO.OUT)
GPIO.setup(VALVE_PIN, GPIO.OUT)
# ⚠️ Logic Invert: 0 = ON, 1 = OFF
GPIO.output(PUMP_PIN, 0) # เริ่มดูด
GPIO.output(VALVE_PIN, 0)
time.sleep(2)
GPIO.output(PUMP_PIN, 1) # หยุดดูด (ปล่อยของ)
GPIO.cleanup()
🚨
Logic Invert คือกับดักใหญ่
Vacuum Pump ของ myCobot ทำงานแบบ active-low เขียน 0 = ปั๊มทำงาน, 1 = ปั๊มหยุด
ถ้าทดลองแล้วปั๊มทำงานตอน boot โดยไม่ได้สั่ง อย่าแปลกใจ มันคือพฤติกรรมปกติ ต้องเขียน GPIO.output(pin, 1) ก่อนเริ่มงานเสมอ
ตาราง GPIO Pin (BCM Numbering)
Pin บนหัวอ่าน 40-pin ของ Jetson Nano ที่ใช้บ่อย:
| Physical Pin | BCM | หน้าที่ | หมายเหตุ |
|---|---|---|---|
| 1, 17 | 3.3V Power | จ่ายไฟ logic | |
| 2, 4 | 5V Power | จ่ายไฟ servo/pump | |
| 6, 9, 14, 20, 25, 30, 34, 39 | GND | กราวด์ | |
| 8 | 14 | UART TX | /dev/ttyTHS1 |
| 10 | 15 | UART RX | /dev/ttyTHS1 |
| 38 | 20 | Pump Control | 0=ON, 1=OFF |
| 40 | 21 | Valve Control | 0=ON, 1=OFF |
ℹ️
BCM vs Physical Pin
BCM = Broadcom numbering (ใช้ใน GPIO.setmode(GPIO.BCM)) เลขจะตรงกับโค้ดส่วนใหญ่
Physical = ตำแหน่ง pin จริงบน header (นับ 1-40) ใช้ใน GPIO.setmode(GPIO.BOARD)
LED & Atom Board
เปลี่ยนสี LED ที่ปลายแขน (Atom)
# RGB 0-255
mc.set_color(255, 0, 0) # แดง
mc.set_color(0, 255, 0) # เขียว
mc.set_color(0, 0, 255) # น้ำเงิน
mc.set_color(255, 255, 0) # เหลือง
mc.set_color(255, 255, 255) # ขาว
mc.set_color(0, 0, 0) # ดับ
| สี LED Default | ความหมาย |
|---|---|
| 🔵 น้ำเงิน | กำลังบูตหรือยังไม่ได้ initialize |
| 🟢 เขียว | พร้อมใช้งาน เชื่อมต่อ serial สำเร็จ |
| 🟡 เหลือง | กำลังทำงาน / รอคำสั่ง |
| 🔴 แดง | Error หรือเกินขีดจำกัด |
คำสั่ง Terminal ที่ใช้บ่อย
เช็ค Serial Port
ls /dev/ttyTHS*
ls /dev/ttyUSB*
# ดูทั้งหมด
dmesg | grep tty
เปิดสิทธิ์ Serial Port
sudo chmod 666 /dev/ttyTHS1
# ถาวร — เพิ่มเข้า dialout group
sudo usermod -a -G dialout $USER
# ออกแล้วเข้าใหม่
ติดตั้ง pymycobot
pip3 install pymycobot --upgrade
# เช็คเวอร์ชัน
python3 -c "import pymycobot; print(pymycobot.__version__)"
Requirement already up-to-date: pymycobot (4.0.4) + dependency เช่น pyserial (3.4)เปิดกล้อง USB
# list อุปกรณ์
v4l2-ctl --list-devices
ls /dev/video*
# ทดสอบกล้องด้วย OpenCV
python3 -c "import cv2; cv2.VideoCapture(0).read()"
เช็ค USB ทั้งหมด
lsusb
# จะเห็น Atom serial (Silicon Labs CP2104 ฯลฯ)
เช็คพลังงาน Jetson
sudo tegrastats
# ดูการใช้ CPU/GPU/RAM แบบ real-time (Ctrl+C เพื่อหยุด)
sudo nvpmodel -q
# โหมดพลังงานปัจจุบัน (0=MaxN, 1=5W)
tegrastats แสดงสถานะทุก 1 วินาที RAM (เช่น 2972/3964MB), CPU (4 core %), GPU (GR3D_FREQ), thermal (อุณหภูมิ) ใช้ตอนต้องการดูว่าโมเดล AI กิน resource เท่าไรROS Commands
เปิด Bridge Node
roslaunch mycobot_280jn_moveit \
mycobot_moveit_control.launch
เปิด rviz (Visualization)
roslaunch mycobot_280jn \
display.launch
Topic ที่สำคัญ
# list topics
rostopic list
# joint states
rostopic echo /joint_states
# ส่งคำสั่งเคลื่อน
rostopic pub /joint_states ...
สั่งจาก Python (rospy)
import rospy
from sensor_msgs.msg import JointState
rospy.init_node('my_controller')
pub = rospy.Publisher(
'/joint_states',
JointState,
queue_size=10
)
3D Vision (AIKit)
เปิดกล้องและจับภาพ
import cv2
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
while True:
ret, frame = cap.read()
if not ret: break
cv2.imshow('Camera', frame)
if cv2.waitKey(1) == ord('q'): break
cap.release()
cv2.destroyAllWindows()
จับ ArUco Marker
import cv2
import cv2.aruco as aruco
# Dictionary ที่ AIKit ใช้
aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)
params = aruco.DetectorParameters_create()
# Detect
corners, ids, _ = aruco.detectMarkers(
frame, aruco_dict, parameters=params
)
if ids is not None:
aruco.drawDetectedMarkers(frame, corners, ids)
HSV Color Detection
import cv2
import numpy as np
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# แดง (วน hue ใกล้ 0/180)
lower1, upper1 = np.array([0,120,70]), np.array([10,255,255])
lower2, upper2 = np.array([170,120,70]), np.array([180,255,255])
mask = cv2.inRange(hsv, lower1, upper1) | cv2.inRange(hsv, lower2, upper2)
# เขียว
# lower, upper = (40,40,40), (80,255,255)
# น้ำเงิน
# lower, upper = (100,150,0), (140,255,255)
แก้ปัญหาเร็ว
Permission denied: '/dev/ttyTHS1' |
sudo chmod 666 /dev/ttyTHS1 หรือ add user เข้า dialout group |
|---|---|
could not open port |
เช็คว่า cable USB-C เสียบครบทั้งสองด้าน + ลองพอร์ตอื่น |
| แขนค้างไม่ขยับ | กด emergency stop หรือ mc.release_all_servos() |
get_angles() [] (ว่าง) |
Serial ไม่พร้อม ใส่ time.sleep(2) หลัง MyCobot280() |
| LED แดงค้าง | เกินขีดจำกัด ส่ง send_angles([0]*6, 30) แล้ว power_off/power_on ใหม่ |
| เคลื่อนแล้วกระตุก | ลด speed จาก 80 30 และเพิ่ม time.sleep() ระหว่างคำสั่ง |
Camera VideoCapture(0) ว่าง |
ลอง index 1, 2 หรือ v4l2-ctl --list-devices |
| Vacuum ทำงานเองตอน boot | ปกติ เพราะ GPIO default = LOW = ON; เขียน GPIO.output(pin, 1) ก่อน |