帖子摘要: 前言本文为手把手教学STM32的机械臂项目——Robot Arm本次项目采用的是STM32作为MCU。该机械臂的基础模型为国外开源项目诸多前辈经过长时间的验证与改进其机械臂精度可以满足日常需求。本项目......
9 Q( F" p4 {- b. g / X$ K/ ]& R, }2 T+ M
大家好,欢迎来到Java吧(www.java8.com),交流、学习Java技术、获取Java资源无任何套路,今天说一说:“基于STM32与TB6600的机械臂项目(代码开源)” % H3 w6 I. \1 T1 s( ^9 i4 g# C
6 A5 l K+ ]% c( p , c) N2 H) L9 W" w8 h/ ~ l
! n! A$ C5 n( y- r
0 [9 U0 M- F$ v* m; Z2 k6 }
前言 本文为手把手教学STM32的机械臂项目 ——Robot Arm 本次项目采用的是STM32 作为MCU 。该机械臂的基础模型为国外开源项目 诸多前辈经过长时间的验证与改进其机械臂精度可以满足日常需求。本项目机械臂为三自由 度机械臂42步进电机 搭配TB6600驱动器 作为动力支撑。整体项目框架具有极高的可拓展性 方便后期实现视觉抓取 等高级嵌入式开发应用。 机械臂的控制选用JDY-31 蓝牙控制结合手机上位机APP进行联动。文末有代码与3D打印件开源 6 U+ P, V: c9 j1 [7 W
, D L$ c- e7 }& c/ j) S$ L
实验硬件 STM32F103ZET6TB6600驱动器42步进电机JDY-31蓝牙模块5V步进电机ULN2003驱动板机械臂3D打印件$ r) Q1 z, Q8 B2 m" {6 t- a2 h
, L! w! N; \/ M% @% H) e0 X" R6 C& D 硬件实物图
% T' Z; q% N$ r* e3 c& c+ [ 8 B$ B- P+ a9 S" B) W- s( f- [% U% ^
: F. ]9 M, ~, V6 z* p; U7 j
1 T& r5 H) j! U8 d% ~& @8 Z5 Y$ n
, c k( d: u: J& |
8 ]2 n4 I" T; G
效果图
, l5 _4 Z+ _3 X
! Z9 \, R( A/ Q5 A7 D
# C6 H* V6 L8 \8 l1 R8 M% T2 n
: i8 ]0 \1 {9 K4 G; [ 一、机械臂简介 6 a4 w$ Z% H! k" E7 q( ^7 o2 r# G
机械臂是机械人技术领域中得到最广泛实际应用的自动化机械装置在工业制造、医学治疗、娱乐服务、军事、半导体制造以及太空探索等领域都能见到它的身影。尽管它们的形态各有不同但它们都有一个共同的特点就是能够接受指令精确地定位到三维或二维空间上的某一点进行作业。机械臂是指高精度多输入多输出、高度非线性、强耦合的复杂系统。因其独特的操作灵活性已在工业装配、安全防爆等领域得到广泛应用。
3 s+ {. }/ ^" v2 ^$ m
- w7 }( Z. X S7 A8 s6 Q 本项目的机械臂目前为被动控制方案需要使用手机蓝牙APP作为上位机人为控制抓取目标物。考虑到目前设计的机械臂已拥有较高的机械精度后续可以附加树莓派等开发板进行视觉抓取开发。
6 ^# D0 v" C6 h4 i( b1 S
/ A8 k! [" _! j- U' D ( n6 e) W! v: F( ^+ W3 f
; N2 @# p% `8 B" Y 二、42步进电机与TB6600驱动器
1 J2 \! Y% P" Z2 O; { 2.1 42步进电机 * u' e6 Q+ f5 ?/ H
42步进电机 是指安装机座尺寸是42mm×42mm 的步进电机又叫NEMA 17 步进电机这里的NEMA是National Electrical Manufacturers Association的缩写美国电气制造商协会是美国最大的电气设备制造商协会如下图所示相同机座尺寸的步进电机又有不同长度和不同绕组参数的型号一般相同机座尺寸的情况下步进电机越长定子上能够绕下的绕组就越多电机的输出力矩就越大。: y3 ^8 y; b- `
5 I6 l) s* v( c1 E c3 X
4 x) `! d6 D0 j& g# z. s 42 57 86步进电机的主要区别是什么即42 57 86的意义是什么
" Q* t1 `! M& l$ W 6 m+ `, g6 B( b+ v2 Z/ P z
答42 57 86 步进电机的区别主要是步进电机的机座不同尺寸分别是42×42mm、57×57mm、86×86mm 一般来说步进电机的机座尺寸越大电机的静力矩就越大电机运行时的转矩就越大电机能够承受的负载就越大。( b6 E& i. s1 r4 m- m9 c
# A* \" y5 ?9 Y
( v8 R7 ~ Y. z1 A 6 Y9 K2 B' y+ Y, d) \
, X C' B) ^6 k( O# f. k 本项目中所使用的为四线二相 的42步进电机 步距角是1.8度在无细分的情况下转一圈走200步360/1.8=200。切记 42这个数字的含义仅与电机的尺寸有关。而电机步距角细分程度只与电机驱动器的配置有关。
$ I. ]( N7 r1 t! g0 H7 V- X
% o6 e) \, [6 N- r4 K / H8 j6 Y( {0 u B5 e' c
9 y7 D3 Z' g( T# {! a% y0 ` ]4 o ( h4 X: D9 B8 {! p! m" h8 z+ M0 n
机械臂由3台42步进电机驱动实现三自由度控制。限位器则可以用来初始化机械臂位置合理校准机械臂对应的笛卡尔空间坐标下的状态。" T4 u7 l$ P" }
$ q4 Y- f# C- Y" J
9 {' t; w2 u' \2 A; |/ \4 Z9 h/ V
2.2 TB6600驱动器
0 d: j) y9 T, m6 } 驱动步进电机往往需要驱动器帮助常见的步进电机驱动器有TB6600 、A4988、DM542、DMA860H 和ULN2003 等。其中大部分步进电机驱动器用法和接线思路大致相同驱动电机的原理也基本一样。
0 ~$ X5 v: Z7 F ( W. R( ?, _ ]6 E* R( ]8 C
项目中使用的步进电机驱动器为TB6600 TB6600 是一款专业的两相步进电机驱动器 兼容STM32 、Arduino 和其他多种主控器 可实现电机正反转控制旋转角度控制等功能。步进电机驱动是一种电子设备通常作为桥梁来连接控制器、电源和步进电机。虽然控制器的处理性能很强大但是它本身的输出能力电流却很弱小。它需要一个中间桥梁去连接电机和主控并同时为电机提供足够的电源。4 A7 ?+ T7 W0 f
, M) f0 j S7 o5 _' x- U TB6600步进电机驱动器采用H桥双极恒相流驱动可直接用9~42VDC供电可选择7档细分控制 1、2/A、2/B、4、8、16、32 8档电流控制 0.5A、1A、1.5A、2A、2.5A、2.8A、3.0A、3.5A 。最高支持4A电流输出。信号端都有配有高速光电隔离防止信号干扰并且支持共阴 、共阳两种信号 输入方式。出于安全考虑驱动器支持脱机保持功能能够让用户在通电状态下调试。内置温度保护和过流保护可适应更严苛的工作环境。 驱动器适合驱动57、42型两相、四相混合式步进电机 能达到低振动、低噪声、高速度的驱动效果。可以适用于机械人控制3D打印等高精度应用领域中。$ O2 v. e' ^ Q$ V
) P* o9 _( G( B * R5 N& l/ W' ]
( q K8 j! s, E+ V5 t 9 e; U/ H* O6 y1 U% {
9 I, A7 y: U; y$ I& b: y' `& a6 I 通过拨动TB6600侧边的拨码开关 设置步进电机的细分 与电流 当拨码开关向下拨动则为ON 上图为作者设置的步进电机为16细分 电流设置为1.0A 。分析 正常情况下步进电机的步距角为1.8° 转动一圈需要200 脉冲当设置为16细分 则需要16×200=3200 脉冲一个脉冲步距角为0.1125° 。而电流拨码开关的设置只要保证输出电流别超过步进电机电流的运载上限就行。
" e6 W3 a: e$ Y2 h5 H; Q. j + N8 c' u3 s3 D, @! ?# [
! Q4 P( N4 [9 [ TB6600信号线的共阴和共阴接法 " `2 x# h& \1 [
# N+ ?; U8 a7 k+ y$ ]1 p (1)共阴接法 分别将PUL-DIR-EN-连接到控制系统的地端脉冲输入信号通过PUL+接入方向信号通过DIR+接入使能信号通过EN+接入。若需限流电阻限流电阻R的接法取值与共阳极接法相同。5 T- j" a( z% D" n
. S9 q1 x. b0 R9 L
(2)共阳接法 分别将PUL+DIR+EN+连接到控制系统的电源上如果此电源是+5V则可直接接入如果此电源大于+5V则须外部另加串联限流电阻R保证给驱动器内部光藕提供8到15mA的驱动电流。脉冲输入信号通过PUL-接入方向信号通过DIR-接入使能信号通过EN-接入。( e3 H0 o* J' x6 \$ Z
* l7 j0 ^% b& m 特别注意 作者建议大家采用共阴接法 方便且不容易犯错。- j0 U! S2 r4 w6 r, K
% m6 ^& Z/ k/ ]+ z* r- M% v
: _$ m7 A0 g; w! k3 J- Y6 B
# L8 ^2 \1 t0 B. p) P 特别注意
* {& B! `# j2 Z9 Q B . \; G+ R# y/ I3 q) y
初学者接触步进电机与步进电机驱动器时很容易接错相位线 导致出现缺陷漏项发现 。所以当发现信号线电源线都满足驱动要求但无法驱动步进电机亦或是步进电机驱动异常时出现丢步转动噪音等 。问题往往可能出现在相位线接错了 读者朋友们可以去找步进电机厂商去拿一下步进电机的相位线说明。3 S# c; G+ Z7 ?" [4 M. L3 {
" P) C! t( Y3 p* J: k
$ }# ~7 f/ d4 \% a. ` 三、5V步进电机与ULN2003驱动器
) _: {& |) ]% X) e g. e 5V五线四相步进电机 是一种常见的小扭矩 电机本项目中采用此电机通过机械结构驱动机械臂爪子进行物体抓取。该型号电机往往使用ULN2003驱动器 配合使用UNL2003 器件是高电压大电流达林顿晶体管阵列。
" Y/ t' p0 I( m( ~% j. D0 R ( J9 M' |+ e4 [4 T. J2 V
/ b. K2 V! Z5 B/ \! f6 p5 v) k
# K) m5 k% H8 Y. i % {9 N2 D/ j; ^; j8 T
该直流减速电机直径28mm 电压5V 步距角度5.625×1/64 减速比1/64步距角5.625 / 64 = 0.087度 也就是说理论上你给一个脉冲电机外部轴转动0.087度也就是说一个脉冲内部转子转5.625度但是由于减速64倍所以外部轴只转了0.087度那么外部轴要转一圈的话需要360/0.087=4096个脉冲。采用4相8拍驱动的话8个脉冲是一个周期那么就需要4096/8=512个周期外部轴刚好转一圈。% _; {9 g" I6 ^9 N( ~; q: |2 t
w& g2 ^7 z& {8 G9 ?
5 g2 P# q2 G! I
2 ~$ [9 b D7 p0 X4 H' `8 ?
电机的驱动一般分为3种方法 8 D. B7 u- T7 |9 s) T+ {2 k% f2 `9 {
7 q& v8 q/ W: ]* j4 a; [) R) k; T Y 一. 1相励磁法 每一瞬间只有一个线圈相通其它休息。& z% I& w0 w$ O! O
, B5 g" g+ @( E) ?& p0 J6 {3 @ 优点简单耗电低精确性良好。缺点力矩小振动大每次励磁信号走的角度都是标称角度。1相励磁法A->B->C->D & e1 u [6 v, X0 D4 f
& a3 k. Y5 P1 j 二、 2相励磁法 每一瞬间有两个线圈导通。
. k6 A* X# e3 `4 b0 A ' R, ^) i5 r' B4 O2 ?" k
优点力矩大震动小。缺点每励磁信号走的角度都是标称角度。2相励磁法 AB->BC->CD->DA
9 R6 B' ?% U% K4 h5 F
, W* D: p- C% H( r+ h 三、 1-2相励磁法 1相和2相交替导通。
4 e! h( g. W7 l. s 0 W" S& h9 v, D* K* A" A& R2 I
优点精度较高运转平滑每送一个励磁信号转动1/2标称角度称为半步驱动。前两种称为4相4拍这一种称为4相8拍1-2相励磁法 A-->AB-->B->BC->C-->CD->D-->DA
- e- x& x0 Q2 ^4 c& N
8 ]( T$ I$ f0 k3 m8 R
& C9 W5 O% c) c/ h ULN2003驱动板上的IN1、IN2、IN3、IN4 四个引脚和单片机的IO口直接使用杜邦线连接为了方便初次学习ULN2003驱动板的朋友理解这里仅具体给大家讲解1相励磁法 如下图所示
2 b, e. u+ U: C5 M" q
0 k# q: }5 R7 O: {3 L( _ % d, E f: F; A$ K3 O2 H
' ^; V, Q" C, }( r 上图4个定子线圈分别为A、B、C、D 我们依次给A、B、C、D通电则可实现电机的转动这个就是上面提到的1相励磁法 。使用ULN2003驱动板时我们只需要将IN1、IN2、IN3、IN4 四个引脚分别去逐个给予高电平 即可使用定时器 。
% J& O5 C( V& {# C
+ B2 I# H1 n& B1 a * f" z# r8 c* k
, z* o% X+ |, ]9 D. Y
四、机械臂控制
. U% P4 n9 Y! [ 4.1 JDY-31蓝牙控制 ) ?2 }7 I. [1 p
JDY-31蓝牙模块 基于蓝牙3.0 SPP 设计这样可以支持 Windows、Linux、android数据透传工作频段 2.4GHZ 调制方式GFSK最大发射功率8db最大发射距离30米支持用户通过AT命令 修改设备名、波特率等指令方便快捷使用灵活。" D! Z# {7 N4 G0 K! C& j
/ h o' d' C o8 e
其通常使用时接入串口引脚UART 即可成功与蓝牙模块建立通信后会发送CONNECTED 。简单的说JDY-31蓝牙模块本质上就是一个蓝牙转串口的设备 使用的时候直接当串口通讯进行使用即可。# x% B4 M. h5 t3 o
" x! ]3 R+ p5 i4 o# e% H! h* j
9 Q& f7 \1 Y; H8 Y, ^9 u9 ~( M
) G) E9 u9 N/ g: J 而上位机作者则选用现成开源的蓝牙调试器APP 直接创建一个针对本项目机器人的控制上位机工程。利用该APP极大的缩短 了上位机开发的时间与工作量 也可以快速检验出机器人的运动控制是否满足要求需要蓝牙调试APP的可以私信作者提供 。6 M0 u G( C7 f" d, v- s
+ D$ U6 D$ _9 {/ Q) ^$ z JDY-31蓝牙模块的AT指令集
7 O- ?* b! C% u+ H9 r. T1 K + p5 ?5 s# B1 k* ~8 _
序号$ l3 h$ S# N' N+ w
目的
) W# W$ o& y5 w2 [/ F& T 指令
! l* i- |" D" e 参数3 `( @8 Y% w8 H7 S3 k
响应
" l: X6 T. [2 N; _' W& @# Z6 k$ A 备注$ w8 Z. G8 |& @& y
1
# [4 ^ X% \0 b8 e& r 查询版本号$ R( |% x+ T" ^& X
AT+VERSION
# Y5 _+ U0 O0 F+ g0 x2 u NONE
2 Q/ ]: g0 V5 U2 g0 e +VERSION=…
& e% o0 F" ?2 p3 a. n. c6 p 2( k2 L2 @+ g( Q+ V3 q w$ j* x+ c
复位( Z$ Y1 {+ m. s: z6 d; j) }
AT+RESET
! ~; N8 B+ a* ~ NONE
' n$ W: M7 r, c( S+ ] +OK
( R4 M9 K, p) b& ^) ]. d 34 l& j4 {8 X. N7 @ i
断开连接: g# q7 _$ y g G) H& E1 a
AT+DISC% E( E& i- x `0 x4 E: H% c
NONE& z% H K1 a; z# H# `! n& }% V
+OK0 K9 d* B3 f$ {7 n% I' Z& M6 B$ W
蓝牙连接后有效
8 @8 k h1 e; `" I+ d5 ?$ m) F f 4; l9 n% `/ _% H q
BLE蓝牙MAC地址; ?! e$ k* f! {( W. x2 L
AT+LADDR
0 ^8 p: G% k0 c* ^& b% \ NONE; q! ^( H3 p" v" \" ~: m
+LADDR=…
I A9 x5 X- v' B! r9 q 5( `6 `+ l. c: K7 ~% k
波特率设置/查询, G' U. R8 S& ?& _9 a, T, F! z* s
AT+BAUD[参数]
! K$ j$ y% d- j3 s1 W t, b) q 4-9600;5-19200;6-38400;7-57600;8-115200;9-128000& z! X2 Y8 h! N8 x ~# ]
+OK5 f* l9 q# Z! [5 b
128000也不丢包
- X5 L; I7 g/ J0 N( } 6, {' b6 k1 ]5 Y7 p7 M
SPP蓝牙密码配对/查询* l" i3 r( H. O5 c* O* [& t: s3 ^( f
AT+PIN[参数], _. _, k1 H7 F0 f, C- }
4位密码
) e& _1 F7 _( U7 l +OK8 ?" z* ? r* e- i/ ]* o
默认12342 {# t6 T& g& F; L
7
# b9 s. Q2 T, t0 w* s- Q+ l8 v 广播名设置/查询
8 I+ L Y" ~& K: W" ]$ P7 P ^( l( i( Y AT+NAME[参数]2 G# D% T" Y: t9 D- t) d
18字节以下
2 P) t3 u; N; O0 O5 O OK
% G2 c0 ~. ]- l( X O 8
5 J1 a9 i2 M( d% O" P 恢复出厂设置
+ |8 s) W) ?" i( `+ K5 } AT+DEFAULT
z2 Z& [, g, k) l) ?/ Q C NONE
9 d, _! H0 w4 T6 f3 b {; N: y OK
8 C) z! o1 q, B5 x r9 H" y 默认JDY-31-SPP
# j, ^5 p% h$ q3 e# ?9 T8 M 9
$ X4 {4 m% X0 B2 k5 k 串口输出状态使能查询* \4 \) r* W2 K6 a" \- r
AT+ENLOG
0 V3 U+ V9 p% i5 O 1:打开 0关闭: ?8 F9 \' f6 b& y1 E; v4 P
OK
6 q% X7 y/ j& J* a. R 默认为13 x5 S. ^4 v: G& I1 k
- Y L/ m7 R7 m5 F, f. h* s
0 i5 {1 {/ x# T& O 特别注意 购买的JDY-31蓝牙模块可能初试化的波特率不一样读者朋友一定要去询问到厂家的初试波特率或自己使用AT指令去设置一下否则对后续的蓝牙控制会造成很大影响。: @5 U \! N. l- B1 @
% Z) K- |0 c) ~$ a/ |, I0 }, J7 d. w % x4 }; D8 z7 b6 i# a( ~
4.2 机械臂运动学建模
. ~' R1 t z# m: ? u 合格的机械臂产品往往都需要根据其设计的机械结构去解算其运动模型即仅输入需要的笛卡尔空间坐标系下的位置点
$ J6 D- F2 b7 y
' U* m. N. ~ P% ~' a. n1 T) V0 D 即可解算出各台电机需要运转的情况。考虑到博客篇幅有限这里仅给大家提供该机械臂的几何模型算法 后续基于树莓派与STM32的视觉抓取机械臂 给大家详细介绍一下。/ P* }7 X h3 J v, L- Z1 a4 f- S
4 B3 \' Y! L, s( d6 J! \
. G& f7 X+ X" E( G* u: z# r # _( g8 J) K$ }3 W8 P
五、 CubeMX配置
9 i$ v4 F6 Y \$ J$ x 1、RCC配置外部高速晶振精度更高——HSE % b/ \. q' h3 U4 L6 P! a" g
0 V* {, c7 K) W1 K5 ^# p0 O3 ^
! w5 u7 w$ M6 v
: c; s4 b0 ^+ u& ]3 m- y& f: T 2、SYS配置Debug设置成Serial Wire 否则可能导致芯片自锁 & I# F7 M: P+ x: d7 ]
5 s( Z5 K. k( n% E& v2 D3 Y
. \+ f) c3 u, D; d
5 `/ H4 B6 N( V4 X& p 3、TIM2配置利用TM2定时器配置us级脉冲
4 v4 E) Q. q1 ~% k! s
0 ?# U9 _' }7 W
' l N0 J0 L }/ o6 ?# G: ?, Y 4 b, v! O; m( D( l$ h5 ^. Z& b
4、UART3配置 JDY-31模块与STM32的蓝牙串口通讯开启串口中断
3 M! L( @4 i3 h8 {5 d: U 3 V" `$ |3 u- E% ]( C7 G
. q1 J7 i* r+ w+ S' |; T+ {
8 @6 M( C0 @: ~1 j
) ^. R ]( n4 g! E* P 8 M/ G' K2 e; H( } G6 m+ M4 \
5、GPIO配置PA5、PA6、PA7为机械臂方向控制引脚PD9、PD10、PD11、PD12为5V步进电机的四相输入PF13、PF14、PF15为机械臂电机驱动脉冲输入引脚 ; i! [: ]1 `4 d7 D# f4 x
5 L: d& r* i2 d. f6 Q/ s
7 I/ I+ g! p, e$ v/ x/ S$ D
) |: O4 A, U% j; X2 x8 V* z" N 6、时钟树配置 1 N9 K" g2 i0 T7 Y% | ]0 y3 h4 w
& t z8 Q' k: E
' r' O2 N1 w; s9 W3 W
+ R2 V0 h4 e5 l9 f" n/ Y2 ? 7、工程配置
+ B X9 D. @2 q1 @+ e0 i" t6 z8 f " @7 L( v) m0 T: s* [
9 A" p O+ |$ i+ D8 A: Q8 ?. I
: B8 ^- C) t# R q) _2 K: \
六、代码与解析 9 T9 b* ~) n% n o% `1 J+ ^
6.1 机械臂电机控制代码 4 G9 J* ^' A7 J* d4 `. G
机械臂的驱动器件为3台42步进电机通过TB6600驱动器进行驱动。单片机MCU主要控制的是TB6600 上的DIR 与PUL 端口其控制过程也很简单——GPIO控制即可作者选择共阴接法DIR-与PUL-都需接地只需要控制DIR+与PUL+即可 。 ^! Q1 J1 g+ c) H' B
+ O2 O+ I' u! o/ S# i 其中DIR+端口 的控制为GPIO的高低电平控制该DIR+端口的高低电平 输入决定了步进电机的转动方向 。PUL+端口 则需要输入脉冲信号进行控制脉冲频率 的高低决定了步进电机的转速 。当然这里的PUL+端口 的脉冲输入有2种主流方式 1us级延迟函数GPIO电平翻转2设置定时器翻转GPIO这里作者使用us级延迟函数翻转实现脉冲。
; J1 x% x. V0 G" [6 H: h
* `; q3 G$ o% S- t7 \, a5 @ Motordrive.h代码 S8 `" h# ?- j$ ?, X; q
/ r* O2 g# `1 g2 V6 n- h' k4 q/ i
#ifndef __MOTORDRIVER_H
#define __MOTORDRIVER_H
6 }7 `1 n$ o- E4 z# R #include "main.h"
//电机方向控制引脚
: W4 }( _& y& o6 i% }5 a //正转
3 i0 B4 p1 B- j0 R2 j- t #define MOTOR1Forward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
* U* z" f5 t0 M! r #define MOTOR2Forward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET);
#define MOTOR3Forward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
/ h$ j- O. ^1 L //反转
#define MOTOR1Backward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET)
#define MOTOR2Backward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET)
. y. g& ]7 I/ K1 y* U) U #define MOTOR3Backward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET)
3 n3 W7 p l2 I4 m# e! }! U: Z //步进电机控制
$ s9 h6 l) t+ p- h! v% Q void Motor1(short dir,int speed);//步进电机1号机
void Motor2(short dir,int speed);//步进电机2号机
void Motor3(short dir,int speed);//步进电机3号机
#endif 复制代码
' e# t' S9 o0 L+ ` Motordrive.c代码
) K5 e. k0 u' X
! y \3 R4 v7 ]8 E- A #include "Motordrive.h"
#include "tim.h"
* ~6 t4 O4 k2 Z8 }- ~1 u9 Y //1号步进电机,1正转其他反转
, a$ M( ^/ F6 @8 v1 F void Motor1(short dir,int speed)
& K) {8 J) \! n* X {
1 J' F5 e7 h1 Y2 E, Y2 n4 W if(dir == 1)
; ]* Z+ u: @+ n" }0 Y5 ~. G {
MOTOR1Forward;
}
( A+ t: w& x3 T& z; O( q else
& T4 q# }+ _8 |; R V, o {
+ t& H2 j1 p$ ]; a" b MOTOR1Backward;
}
+ n, r8 C9 c% C2 V+ i //电机脉冲控制
+ F3 L/ `$ L( r2 V$ C HAL_GPIO_WritePin(GPIOF,GPIO_PIN_13,GPIO_PIN_SET);
9 x9 O$ g) ]+ ]* l Tims_delay_us(speed);
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_13,GPIO_PIN_RESET);
1 N7 Y5 w/ ]9 w5 m7 d- z Tims_delay_us(speed);
, h1 R( i5 I5 a& e5 _ }
//2号步进电机,1正转其他反转
& r5 b+ o$ k8 `% |, A void Motor2(short dir,int speed)
) z: L; [, A8 _+ s. Z5 ~ {
7 o; f1 I8 H: ] if(dir == 1)
{
MOTOR2Forward;
}
4 V3 b% }( a9 z) g8 K! H" `2 [ else
{
7 ~' Y7 C a& M; e2 @ MOTOR2Backward;
2 U6 @( |0 m2 `3 t3 n) x: ` }
//电机脉冲控制
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_14,GPIO_PIN_SET);
Tims_delay_us(speed);
B; K2 P* W3 T1 \ HAL_GPIO_WritePin(GPIOF,GPIO_PIN_14,GPIO_PIN_RESET);
# G" J/ m$ R/ d& C' j) G Tims_delay_us(speed);
}
//3号步进电机,1正转其他反转
void Motor3(short dir,int speed)
{
! O/ U' E# F5 V, s: Y( O if(dir == 1)
{
; U, K5 C/ Y# M& r MOTOR3Forward;
# _2 ^4 O% R( c }
else
6 L; T) N9 j+ }( s' ]+ C/ B/ i {
MOTOR3Backward;
- q0 U+ v% X9 R8 l( i7 V4 I2 _ }
//电机脉冲控制
8 ~- X* ]1 e) ]( e8 z, v& f HAL_GPIO_WritePin(GPIOF,GPIO_PIN_15,GPIO_PIN_SET);
Tims_delay_us(speed);
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_15,GPIO_PIN_RESET);
1 o5 l4 i$ q* F7 f1 z n Tims_delay_us(speed);
} 复制代码
5 h7 w% r, e$ [- M us级延迟函数 4 r B5 B8 i; o% _( n( d
Z6 v: \, u. X. Q2 Z
void Tims_delay_us(uint16_t nus)
5 o% d% `, J4 Y# ]8 D {
7 X3 b8 ~* D- J* ^ __HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);
8 D- a/ K. V, \) ?" Q- F __HAL_TIM_ENABLE(DLY_TIM_Handle);
while (__HAL_TIM_GET_COUNTER(DLY_TIM_Handle)
; A$ X$ e7 y8 ]* |# D [size=5]6.2 机械爪控制代码[/size]
& y, h) a, M% x C 机械爪部分使用5V步进电机与ULN2003驱动板驱动将ULN2003驱动器上的[b]IN1、IN2、IN3、IN4[/b]四个引脚循环拉高电平即可实现对5V步进电机的控制[b]IN引脚循环周期的快慢决定电机转动的快慢循环引脚顺序决定了电机转动方向[/b]。
3 ^9 C0 r! v8 N [b]
! W' m, J A Y0 x9 j( z [b]注意[/b]ULN2003驱动器驱动5V步进电机的时候电机速度是有一定限制的。技巧可以通过ULN2003上面4个LED灯的闪烁速度来判别驱动电机转速的快慢。
I" E# \, I6 y* }* c* }
[/b]
[b]crawl.h代码[/b]
0 ?6 X5 b" x; |7 k, g
[code]#ifndef __CRAWL_H
" U' ~8 O% G) `) I) M3 n5 |4 p( K7 h #define __CRAWL_H
#include "main.h"
//引脚定义
, V6 f/ Y2 f0 o. I* d' K #define IN1_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_9,GPIO_PIN_SET)
#define IN2_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_10,GPIO_PIN_SET)
( T; ]7 b$ c( j$ G1 N #define IN3_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11,GPIO_PIN_SET)
#define IN4_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_SET)
#define IN1_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_9,GPIO_PIN_RESET)
7 s) j: A( {( K3 C! [ #define IN2_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_10,GPIO_PIN_RESET)
#define IN3_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11,GPIO_PIN_RESET)
( [/ F, d, n# f! r #define IN4_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_RESET)
+ v; b6 D) N8 n, B m4 H( _ //5v步进电机控制
void stepper(short dir,int speed);
#endif 复制代码
* D; O& [- L$ e' X. U
crawl.c代码
; L/ e3 N' e u3 s' O% T % \: r# d" J& t" l' [
#include "crawl.h"
//1是正转其余是反转
! B5 b8 Q8 U( g void stepper(short dir,int speed)
{
' F ^$ y2 X- T% }+ e9 m/ ? if(dir == 1)
$ Z% f& Z {& `1 ^ {
IN1_HIGH;
9 N; R/ A) c( Y, G7 |) R HAL_Delay(speed);
IN1_LOW;
IN2_HIGH;
" v8 h6 C% H( a* O HAL_Delay(speed);
IN2_LOW;
IN3_HIGH;
HAL_Delay(speed);
8 n5 g1 z& D- V+ Z+ r IN3_LOW;
! K4 _" B# Q% b4 U2 P IN4_HIGH;
HAL_Delay(speed);
9 d- c" F& r% {- i4 C/ ` IN4_LOW;
}
! A' b- j; r0 P# v8 _ else
" L* h* c3 O% b+ I% @1 v1 j2 Q% ]9 L {
IN1_HIGH;
HAL_Delay(speed);
- i2 D& }2 \4 }/ P0 o IN1_LOW;
IN4_HIGH;
HAL_Delay(speed);
IN4_LOW;
7 w! a/ f, |* V( T) V6 Z/ H IN3_HIGH;
3 L3 d- v {" c" O HAL_Delay(speed);
IN3_LOW;
IN2_HIGH;
HAL_Delay(speed);
IN2_LOW;
5 Q# ]/ m- t# [ }
6 u2 j/ ?8 Y0 k+ H* g1 P* y* j1 ?, p! W } 复制代码
2 f. g2 L- q0 x* Q2 ^4 ?6 b* H
6.3 JDY-31蓝牙控制机械臂代码 + R1 V* C; B2 z( Z% }! u
项目机械臂采用手机蓝牙APP 进行控制且控制所用的蓝牙APP为开源的蓝牙调试助手 具体界面如图所示。设置6个控制组件为byte类型 按下时分别对应数字1-9 松开时为数字0 。
4 }& Y. R6 P$ o I9 b , Z0 l% o7 ]3 a- x0 s
- `5 c" s j% t& L* L
$ q, c' I: Z, f; R a0 Z7 I bluetooth.h代码 6 k" \( {4 _% r" q+ ^/ U# a. K* w
/ z- X) y! P2 I, V# b #ifndef __BULETOOTH_H
: q2 f+ X/ _4 ~2 x" y+ g+ [ #define __BULETOOTH_H
( R" u7 o; M. G: m9 Q #include "stm32f1xx_hal.h"
extern UART_HandleTypeDef huart3;
* l5 s; o/ K# w6 p: Z' ^8 _ #define USART3_REC_LEN 500
extern uint8_t USART3_RX_BUF[USART3_REC_LEN];
extern uint16_t USART3_RX_STA;
extern uint8_t USART3_NewData;
% e$ ]( J5 i, L% k- W void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
; K2 D( X6 Z( n" v1 k #endif 复制代码
" E- {1 }" f( {- S/ w bluetooth.c代码
$ a3 L# {; ~7 F9 u
{3 b/ [8 T D5 ]: ^: o3 S/ X. _ #include "bluetooth.h"
uint8_t USART3_RX_BUF[USART3_REC_LEN];
" u" R4 D0 A8 o6 B! ]/ Y& i uint16_t USART3_RX_STA=0;
2 G. d& g) H7 Q$ ?$ h uint8_t USART3_NewData;
! Z2 K q5 P( j5 A$ F! G) p/ ~8 Y extern int flag; //全局变量
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
0 r! |! n) E9 {7 R, c( x5 K' d {
" J% P7 P9 Y4 U( Q) B3 M/ e! w+ [2 G if(huart ==&huart3)
! o& D0 W: L! {5 q+ V# s2 l {
7 y& i% X! U* y( F
5 Q7 m8 u* D) i. b/ _ USART3_RX_BUF[USART3_RX_STA&0X7FFF]=USART3_NewData;
; G# U9 S( \4 ~: { USART3_RX_STA++;
7 n/ e) F J2 X& G
if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;
if(USART3_RX_BUF[USART3_RX_STA-15] == 0x01)
{
9 D r: w1 T4 X0 _; E! s$ @' u4 _ flag = 1;
4 z: r) d2 B, j( i }
if(USART3_RX_BUF[USART3_RX_STA-15] == 0x02)
$ }$ Q6 h) `' P {
0 D2 C8 a6 X9 ~3 p% j flag = 2;
7 q( C f# N+ V' V }
if(USART3_RX_BUF[USART3_RX_STA-15] == 0x03)
{
flag = 3;
$ h9 c, c8 `: ~: Z t' c0 V3 e }
if(USART3_RX_BUF[USART3_RX_STA-15] == 0x04)
{
flag = 4;
}
5 j- j0 M$ I& u6 ^1 `/ ` if(USART3_RX_BUF[USART3_RX_STA-15] == 0x05)
{
- V& j; y( N; y0 H3 A flag = 5;
}
5 {* l& _5 D1 @; _: M6 i if(USART3_RX_BUF[USART3_RX_STA-15] == 0x06)
{
& ]( O! G0 [7 B" v2 n flag = 6;
a- {) ~+ G+ X4 j% z# d }
if(USART3_RX_BUF[USART3_RX_STA-15] == 0x07)
{
flag = 7;
7 \* k! w5 P7 T2 Q0 C }
if(USART3_RX_BUF[USART3_RX_STA-15] == 0x08)
{
flag = 8;
}
( o. v# w$ q& [ if(USART3_RX_BUF[USART3_RX_STA-15] == 0x09)
{
flag = 9;
}
6 ~. J& t, ^ R HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_NewData,1);
5 K; v* R. |8 z }
2 W# Q$ _$ K8 g } 复制代码
J. X8 ~# Y) \/ w A# y0 d 6.4 main函数代码
& C. h, m4 w) h" R# H$ y 主函数利用switch()函数与蓝牙控制代码中定义的全局变量flag进行组合使用在while()循环函数中实现串口3中断后全局变量flag控制机械臂运动姿态。& u" j4 w C0 Z. V- T4 J4 W- ^
; Q: d. s' `1 w% N H main.c $ `' ]1 N+ o, c; Z! G
: `7 x9 h% W5 q; R) f
#include "main.h"
#include "i2c.h"
#include "tim.h"
g( W- r ]$ P9 c* g #include "usart.h"
6 l1 j- I: m; ^8 C# [6 R( n #include "gpio.h"
#include "crawl.h"
1 u4 _/ W& ^" s- j #include "Motordrive.h"
#include "oled.h"
6 r- Y r% ?' w: a #include "control.h"
; \% Q( z' T' ]" u, q3 a3 I3 { #include "bluetooth.h"
w9 H2 |$ [! B$ Y int flag;
int main(void)
2 y6 A; `5 B* H5 A6 ~2 n {
( E0 y% y/ j2 p9 j# E5 }$ Y //CubeMX配置的初始化代码
HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_RX_BUF,1);
while (1)
{
/* USER CODE END WHILE */
& \! N& f& B9 D$ q( F$ B! b- G1 {! {8 ] /* USER CODE BEGIN 3 */
3 @) v) S3 g) [2 d! Y switch(flag)
{
3 o7 z& Q7 [) E case(1):Motor1(0,2000);;break;
: A0 M: z1 ]8 H( ]# T1 e" q7 W case(2):Motor1(1,2000);;break;
case(3):Motor2(0,2000);;break;
6 d, b+ F7 B- L, D( P case(4):Motor2(1,2000);;break;
case(5):Motor3(0,2000);;break;
( }$ u6 \- C: K/ s case(6):Motor3(1,2000);;break;
case(7):stepper(0,20);;break; //收缩
% o- V# p5 p4 P( S2 O0 T' w& P case(8):stepper(1,20);;break; //外扩
case(9):stop();break;
* K: n6 ^, u' y. T( u, ] default:break;
# U, K1 s% L" S: k+ J- ^5 K }
3 a& h" e; Z) t" g! H2 L6 G }
/* USER CODE END 3 */
} 复制代码
) x# S4 ~3 z6 _: v
七、项目效果
7 c, y+ S+ W8 s: S) ^% Q
! X6 i+ S) h6 N. r2 A; l3 O 基于STM32与TB6600机械臂项目8 ]% w% Q1 _& P( M% h0 G2 \2 ~7 R
: I6 D( s2 W3 H& k( Q5 q! d! q/ U5 x
八、代码开源 : z6 L; X& P% I$ E' g1 [# g' s
3D打印件与代码地址 基于STM32与TB6600蓝牙控制机械臂项目-嵌入式文档类资源-CSDN文库5 |! o+ J* e' s& \+ Q" m
4 q( l/ _( @* x7 R! v6 x 如果积分不够的朋友点波关注评论区留下邮箱作者无偿提供源码和后续问题解答。求求啦关注一波吧
6 F N) M# c2 w4 a; A4 T$ c) h 6 h) \5 ~) G6 r; U/ _
本文来源csdn,由Java吧转载发布,观点不代表Java吧的立场,转载请标明来源出处:https://www.java8.com