|
基于STM32的DIY遥控小船制作 01 前言
' b. {& C4 M! m0 r6 N/ [
0 R4 R* L* e$ S% u( s2 |9 T4 {周末带小朋友去公园玩耍,别的小孩在池塘里玩饮料瓶做的漂流船,看着他欢乐的跟着跑跳,无比羡慕的眼神,却又不能上手的小失落,又回想起儿时用泡沫板和小电机以及电池做的小船,和那时对于电驱动产生的无比兴趣,我决定升级一下儿时的装备,基于STM32给小朋友DIY一个遥控小船,使他成为公园里焦点,同时也期待他对电气控制产生一点点好奇。/ E0 Y8 U1 \2 [
6 {5 ^4 k5 v/ e5 I- k" t, X
$ n' B/ K- B- S% ?基本构想如下:stm32驱动两个小电机,小电机上安装两个螺旋桨,可以实现双桨前进、后退,单桨转弯等。供电使用18650电池,通过升压放电板管理电池的充放电。遥控使用最廉价的红外遥控,来控制小船的各种动作。同时可以增加一组数码管作为输出设备。
) K4 w* E6 Q* }/ f: m
0 ^; k& z: I# p* l# Q6 ~; D - V* d" h: m" H% }- v
在万能的某宝上可以淘到所有需要的材料,并且价格都十分实惠。% u3 o7 G4 u0 W
% b& a, j5 N, B" i 02 硬件模块
0 _! I1 x/ }& N8 n" e, b" b2 X, @9 [
a7 W ~, R" z& [# H4 w/ _, h3 h. k6 k' \5 ^+ p
6 S0 y* S& ?: Q) y9 U红外遥控模块
1 R Z! b/ E: Q! w6 H6 g一般遥控玩具使用的是2.4G高频无线遥控模块,但是本着能省则省的原则,选用遥控器带接收头3.5元还包邮的HX1838红外遥控模块。这种遥控器类似电视遥控器,优点是便宜,开发简单,缺点是控制距离短,并且要像遥控电视一样指着玩具操作,这些缺陷留着下一代产品迭代时升级。* v& r9 g- x1 d0 d" f! ?
/ o# ~) `/ T) A3 f' {1 H
3 l J, p! o0 ?: Y8 y: w
电机驱动模块% r' y) P, Z d- l# W F
电机使用直流小电机,3-6V可驱动,使用一片L298N驱动板驱动。STM32输出PWM可调速,可正反转。& X/ B* t0 q* u9 ~# ~; \, [5 j* [
" }: C7 z1 E5 S: ?7 A' g% ~3 Y& @! d
数码管显示
1 _4 Z* E+ n5 W) C& n, u基于TM1637的四位数码管,用于显示一些简单的信息。TM1637是天微公司出品的LED驱动专用芯片,集成简单,开发方便。除了TM1637,天微公司还有一系列TM16XX的芯片,主要区别就是位输出和段输出个数多少。6 b! j4 E. ~/ o* R
5 j. W3 [& q% _
7 w1 c/ s- K- f
电池和充放电模块' G6 K: @1 J0 U$ y2 @" ^
18650电池具有容量大,寿命长,安全性高等优点,普遍使用在充电宝,笔记本电池、仪器仪表中,甚至特斯拉的电池组也是由7000多节这样的电池组合成的。充放电线路板,主要的作用是将电池3.7V的输出电压升压到5V,供给STM32及外围电路使用,同时还具备给电池充电的功能。实际上等同于一个充电宝,充电宝的原理就是若干个18650电池并联,再用一块充放电板管理而已。
- }9 q) j3 N/ v# V/ R5 E5 p3 `03 嵌入式软件
& d, X- R! c, N# }' V0 b/ ^
4 w' x2 Q- n) q% e
! c) u' A" u4 I% B( b) C
, ~- K5 c$ b# K. {红外遥控器驱动
, |/ k. @' e" @6 w, ?* p; B/ A/ h+ {HX1838采用的是 NEC 编码格式。载波频率为38khz。
8 I7 ~& b- p7 S7 W9 O! `: q5 r
# V* }* @0 J# M2 n* E + I7 \, C# T5 A6 k
逻辑1是2.25ms,脉冲时间560us;逻辑0为1.12ms,脉冲时间560us。根据脉冲时间长短来解码。- _1 U4 \' P; P. D4 C% Y
协议示意图:3 P, U8 [( X D8 T: g0 |; R' i
f) F5 v; P: i. V 一组数据组成:
) \! L3 z6 p, x' u- t K起始是9ms的高电平脉冲- F0 F- V% E0 R- q% O6 N
4.5ms的低电平# Z1 x2 |* {7 }6 N
8位地址码,低位在前
3 }: \" |/ S! I; Q2 N1 ]: }8位地址码的反码,用于校验
5 K5 h6 m: Z$ W4 J8位命令码,低位在前
( ~9 d8 x5 \6 I2 q M6 X- U8位命令码的反码。
9 @+ n3 ^9 a* E' U需要注意的是1838红外一体接收头为了提高接受灵敏度。输入高电平,其输出的是相反的低电平。实际测量接收到的按键波形如下图,可以看到电平是相反的。& `9 h3 `* V" p
7 |) a/ P1 f! K/ e( w# s
5 T: f6 U/ e- H2 S) E) C7 X* W代码实现:
5 t/ O7 r, e, ^8 j, z# o使用下降沿外部中断作为一次按键的检测触发,然后每个20us读取一次数据管脚,按照上述的协议逻辑,读出一个u32的数据。, d5 w* o+ ?, f. T
- " x7 u$ Y9 ?9 i$ Q+ X) G$ o# }
- U8 Infrared_Receiver_Process(void)
8 Y8 |+ T1 ^1 z6 ?& L9 m) Q9 t - {, S4 o$ C9 G9 ~
- U16 nTime_Num = 0;$ {( u1 l+ n2 `" k. P3 o5 K
- U8 nData = 0;) H2 D1 {! z6 v
- U8 nByte_Num = 0;
" T8 @0 }6 d8 v8 [5 _ - U8 nBit_Num = 0;
) ?; M! r4 g) ^8 K4 h/ r" v+ W -
' \5 W/ S7 z! Z- b - nTime_Num = Infrared_Receiver_GetLowLevelTime();0 M3 u, A2 A( E* |- b
- //t0=nTime_Num;& S* B# [( H* A+ J% [2 q: u
- if((nTime_Num >= 500) || (nTime_Num <= 400))//9ms 数据头高电平 hx1838输入的反的* R; V. W a( ?. a
- {
; e$ ^5 k% b% L& u. o4 N - return INFRARED_RECEIVER_ERROR;2 A6 I' A; |% l
- }
) h H. I/ W' I* v* ?; M - nTime_Num = Infrared_Receiver_GetHighLevelTime();//4.5ms 低电平 hx1838输入的反的
* C" U" y* ]& w1 U - if((nTime_Num >= 250) || (nTime_Num <= 200))& X6 h5 k+ I* N4 \, B$ m1 J* j+ {- h# j
- {
" e$ }& v2 [" Z1 m- P" \ - return INFRARED_RECEIVER_ERROR;9 D* W) h+ @0 T3 \1 P' [9 r/ I
- }3 R, v% z8 r4 R( t/ j
- ; H9 p* U, ^8 \8 {( Q
- for(nByte_Num = 0; nByte_Num < 4; nByte_Num++)//4个8位码
6 L# y Q& _/ C# S: e - {
% e3 l5 {$ L- E+ [( K# d - for(nBit_Num = 0; nBit_Num < 8; nBit_Num++)
. Z9 T& V) a6 K0 g - {
. E$ e3 w, [) Z - nTime_Num = Infrared_Receiver_GetLowLevelTime();//560us 高电平 hx1838输入的反的 nTime_Num=28; \- E& a* ^7 N d! }6 w
- if((nTime_Num >= 60) || (nTime_Num <= 20)); z; r$ u+ O& m. E H3 u
- {. D/ ~ t- K a" i
- return INFRARED_RECEIVER_ERROR;
; U I- o; u/ b5 Z# j8 V/ s - }
( a5 K5 }) D& R7 i$ W2 n, X
# u0 V7 q5 N# V" n9 C- nTime_Num = Infrared_Receiver_GetHighLevelTime();//1690us(nTime_Num=84.5) 是逻辑1 560us是逻辑0 nTime_Num=28
8 f# N0 O) \: F. E: d - if((nTime_Num >=60) && (nTime_Num < 100))
9 j! L. E( ^+ E" a$ L: f% ^/ [ - {, D1 S1 U/ z8 v% g v" g% J( [$ V' t
- nData = 1;7 T5 H: \4 H9 \( Z. m4 N) ~
- }0 c9 }5 z# S, u) }3 F1 [, A5 N) X
- else if((nTime_Num >=10) && (nTime_Num < 50))- h! n7 {' W# [8 k$ y
- {: y7 a) k1 O% Y) |) k- Z5 L9 n9 Q, d+ U; b
- nData = 0; @" l+ P: B1 v
- }
2 a1 i2 _6 D9 }+ z/ g - else
# h: h6 T; d& }2 f0 B% N - {
' D/ i; O) z8 m- s5 n: w - return INFRARED_RECEIVER_ERROR;
" K; q/ k2 o9 d8 i7 f% I1 k - }2 S) |+ `- [6 ~8 @+ Y3 @
- 2 w# l. V" Q7 X6 y4 L8 I
- gInfraredReceiver_Data <<= 1;. P$ `2 S7 p p9 h9 E- P! Y
- gInfraredReceiver_Data |= nData;
: a! w0 p+ [5 _( E+ i( W! D - }
2 F* ~* r) I/ A4 X; q - }
) P) T, Z% B8 }1 N6 u6 G3 l - ) i6 b. z# a( P: W+ D
- return INFRARED_RECEIVER_OK;
8 X* f) H$ _$ m6 F! y( z - }
复制代码
& @1 |& h9 a. S! O+ g
$ k( o9 A* U4 f; H* ?' f$ G经过调试,得到遥控器的按键键值如下:
4 V# C1 f( K4 G- s7 c M- ' _) m0 [- d& F% B: w2 V2 k
- <font size="3">KEY_OK = 0x38,
6 r& L5 j: W/ [ F; V1 d: G - KEY_UP = 0x18,
0 a( r& b, Y1 y& z8 T, a; Q. e - KEY_DOWN = 0x4a,# F! i b4 t/ H- b
- KEY_LEFT = 0x10,
7 m( b* J) _) r' N8 B4 V8 i - KEY_RIGHT = 0x5a,/ U) |3 j- |$ E! M5 C5 C
- KEY_1 = 0xa2,) e6 ?/ m \9 Y
- KEY_2 = 0x62,; s$ D3 ~$ \! l0 V$ g7 Q+ O
- KEY_3 = 0xe2,
, M, G, L h9 S0 t - KEY_4 = 0x22,
* ?3 z, S+ X" M! D% O) P! y - KEY_5 = 0x02,. A0 V- b3 R- a! a5 D) ^5 S
- KEY_6 = 0xc2,
1 |$ {4 \% E- b9 L- A. A! p - KEY_7 = 0xe0,. T1 B; J( ~. R
- KEY_8 = 0xa8,- G* f W4 t1 }9 E. [
- KEY_9 = 0x90,/ X$ N8 D6 Y4 @8 ?
- KEY_STAR = 0x68,4 w4 T) }1 g8 \. k1 Y5 O7 `
- KEY_0 = 0x98," b3 i. W7 ?+ q( t5 U* R
- KEY_SHARP = 0x80,</font>
复制代码 . H# {- g: }, t/ T1 L
' y2 n- r! I# L另外由于NEC编码格式的红外遥控广泛的用于电视遥控,我们也可以找一个电视遥控器,把键值读出来,写入到stm的程序中,这样就可以用电视遥控器来操作小船了。% V5 }( [) n: P
4 g6 Z0 x% a' L
- f( R3 `; ?( N5 r/ _, R>>数码管显示驱动
, O1 b; ?# h1 U, i: xTM1637与其他的一些TM芯片有一些区别,没有同步通信的STB脚,控制时序也有相应改变。
N% r7 T2 x% F* i& a) E% w+ ]在输入数据时当CLK是高电平时,DIO上的信号必须保持不变;只有CLK上的时钟信号为低电平时,DIO上的信号才能改变。数据输入的开始条件是CLK为高电平时,DIO由高变低;结束条件是CLK为高时,DIO由低电平变为高电平。TM1637的数据传输带有应答信号ACK,当传输数据正确时,会在第八个时钟的下降沿,芯片内部会产生一个应答信号ACK将DIO管脚拉低,在第九个时钟结束之后释放DIO口线。
% j T, u! E. g$ A! q: I1 d
+ E0 t6 S, Q/ \7 N: |$ Z w, Z. \
+ ~, A+ v! s6 ?. k; _6 ?: ~代码实现:" u; s# U: e$ Y' P
- $ g8 A: T$ W0 h
- <font size="3">void start(void){
B+ p6 Z+ ~# f" Q6 G$ u - dio_output();
- Y0 R( f! I7 e& A; T; i - GPIO_SetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);! p, @ Y1 y5 u/ ]& X# |
- GPIO_SetBits(DIO_GPIO_PORT,DIO_GPIO_PIN);! I$ Z* v" K# p) D2 D
- Delay();
" s8 ^5 C t9 `/ s) F5 E4 n# k - GPIO_ResetBits(DIO_GPIO_PORT,DIO_GPIO_PIN);
' L0 @2 R6 B7 ?& @; i& p, j) P8 V - Delay();3 m6 {+ M& C% p1 ?
- }
4 Q0 l. ^! p& e* l' Z* B' L - 6 ~' {( B. X: W( z: v [8 U( u3 i
- * r5 v% C/ k; [+ ~
- void stop(void){8 k7 M# z: v, {+ y3 I1 z& H
- dio_output();
7 \; S( h) `% f% s0 s - /*GPIO_ResetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);
. L9 Q& N2 w4 g- L* ~5 u3 K - Delay();*// d4 j: b$ Q# E5 [
- GPIO_ResetBits(DIO_GPIO_PORT,DIO_GPIO_PIN);
+ Y6 N ?( k# l0 z - Delay();% N4 q, W: o8 H& K
- GPIO_SetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);
# w4 S- L, _! n) c8 |7 d' @ - Delay();: ~) N& K3 L4 t- W% N# U9 ^6 Y% |8 c
- GPIO_SetBits(DIO_GPIO_PORT,DIO_GPIO_PIN);
7 y& B0 r8 P5 y0 s: S. e9 Z - Delay();
: Z) C! `" h6 T2 S/ s; @0 o - }
$ H, N2 T! }5 L5 d5 r - 8 e$ T( G& x0 E7 R
8 m% m# e% m$ D9 E- void ack(void)1 s. B, l) }% c/ \8 ?0 x
- {( c& p# F) D; M& z& R+ L* @. p0 U
- u8 i;8 L% s2 c: [" \1 t+ ~" \! S$ O
- dio_input();9 j; l; h, ?# S. ]/ n' S
- GPIO_ResetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);2 h* @$ [9 S, g/ C0 \. j1 F
- Delay();0 b9 C# [% I' ^; Q+ o& B
- while(readDio()==1&&(i<250))i++; u! z+ }# L; G, V$ F3 c
- GPIO_SetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);
: Z2 I# B; p8 F- }. L - Delay();
+ h3 J" `0 l& t6 c* Q - GPIO_ResetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);& ^, e5 v7 v s- Y$ T9 X4 P
- dio_output();
+ N( x; T& k s4 h& O' \ - }# o$ O& x; ?& }
- void write_data(u8 wr_data)
2 f3 Y2 r4 ]) G! e2 W - {; y" r) V h @1 X( U2 a, P
- u8 i;9 h1 ]% Y& E( T( Z. J: V
- for(i=0;i<8;i++)//开始传送8位数据,每循环一次传送一位数据1 u7 D( e4 d. B; U" N
- {
) y+ y% b- d- }# S+ v: o9 r - GPIO_ResetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);
8 \( F, x: u; c6 p( B' c0 K - if(wr_data & 0x01){' v) `4 Q4 f% Y7 \$ [0 I+ z: V+ Y) u
- GPIO_SetBits(DIO_GPIO_PORT,DIO_GPIO_PIN);3 N. `) c; Q0 _5 e1 c$ m
- }else{
' a/ d4 H( P' F, R/ n" c# |. x - GPIO_ResetBits(DIO_GPIO_PORT,DIO_GPIO_PIN);9 p) d: s0 O e: w3 J
- }
" _7 f5 P6 x* z, J/ `4 ^1 i - Delay();$ G1 G# ? Y( z8 N( I4 V
- wr_data >>= 1;1 T, k7 H1 ?! I
- GPIO_SetBits(CLK_GPIO_PORT,CLK_GPIO_PIN);
- ]& V8 K) L) x: b - Delay();; M: H- `# O$ B
- }0 f2 Y% Q# E6 r9 N8 F; H' l. l/ g
- ack();1 a' W* U6 p/ ^0 G$ g& j# i
- }
6 q' k! M# ~6 l8 k) _$ o. h4 ` - void tm1637_DispStr(u8 *str)( e! J2 B$ J( R' _
- {
3 V9 S, ^ P: e$ b0 T$ d - u8 i;
5 ?' Q9 c! l5 u3 D5 V! K - u8 ledCode[5];7 e y9 r; c% j/ i- {7 s$ a1 t
- ; S- d Y) _: F* r
- ! G/ Q1 [2 Z# T8 e
- for(i = 0;i < 4;i++)
! V5 V; A9 T$ B% d" E - {
" m& {' D* m7 j% Y; r5 W - ledCode[i] = GetLedCode(str[i]);
. I4 k [4 m: N; q - }
. i: M2 h: T. @: O- ?3 J+ L2 ~! j - start();
/ W+ q# h" F, k - write_data(0x44); //固定地址模式. ]* I+ u H5 O6 `7 y. N
- stop();( ^8 H- W; ?) S' m; a+ M
- start();
( u% ]( z, D- q - write_data(LED_GRID1); [: d; ]. T- D" H' @
- write_data(ledCode[0]);3 ^2 {+ ], S% U( X
- stop();# |, @ k) ?" R' W& i0 I& U M$ @: J8 L8 S
- start();* I* o. O2 ~5 J# G! h6 Y1 P1 o6 `+ ]
- write_data(LED_GRID2);1 e. N, B# y! x1 {$ J
- write_data(ledCode[1]);/ p+ f7 `/ p: l* Y- v. l
- stop();' R& o$ s) f: }7 K' t8 J9 \
- start();: I+ |" {$ f% w) k! f% x
- write_data(LED_GRID3);
& K+ r& y1 R! u- G - write_data(ledCode[2]);( c7 R; n8 Q `
- stop();
5 `$ o: {7 ^5 x1 }9 B P o9 k - start();8 F9 B: K" L5 q( [
- write_data(LED_GRID4);
: [$ J0 @5 U( r" W" K - write_data(ledCode[3]);+ r/ w/ }# i' p, f2 Z; D
- stop(); N2 v T5 c# x3 J# k! M5 j3 O" ~
- start();3 q9 w' t' x* u+ X- d U* [" H7 }
- write_data(0x89);
) K! w) L- k6 u - stop();! o; O& }" v, r. h
- }</font>
复制代码 * I0 n. q2 x) ^# s+ q. T6 H
( K1 L0 J9 h* C! e' K
( {# U/ T- @0 a) E
小船控制逻辑
0 w. W" \9 O, F目前的逻辑比较简单, 就是收到按键后控制电机的转停。
" _& Q2 {9 i. a4 ~- ' A9 f) ^1 ^) v: j! }, \2 W
- void dealIrKeyDown(){" T6 a; X' i5 z
- u8 len;3 D( m p# t# k( c
- len = irKeyfifo_count;; u5 e- X. q5 X. t" i: e% y D
- if(len > 0){ s( q/ S9 N7 Q$ j
- irKeyDataOut = irKeyfifo_DataOut();5 f, P5 i; i1 f' |- ^6 v
- //按键显示
8 {* a Z; Z4 f' Y) |2 d4 [' s/ v" x - U8ToHexstr(irKeyDataOut.index,dispStr);, O' z$ z# E( K% Q9 V5 y' k' P
- U8ToHexstr(irKeyDataOut.cmd,dispStr+2);
: O+ M8 A' h# Q2 b* K - tm1637_DispStr(dispStr);
& f' G X" T% a5 \0 C* _ - switch(irKeyDataOut.cmd){
2 T. v) a: @$ B4 i# g7 C8 M+ L - case KEY_OK:% w7 d6 u% {, ^0 x' a- N. X
- case KEY_OK_CHANGHONG:# L6 n! n: R3 v% Y4 t7 h
- motor1_Stop();4 x5 Z. J4 |% P) a4 C! I( P. @2 z
- motor2_Stop();
: J5 d( Q2 D: I+ y% `1 l - break;" e8 i9 Y& H5 K$ H
- case KEY_UP:9 ~9 ?* z+ y- b# Y0 p4 e4 I
- case KEY_UP_CHANGHONG:
- _ b4 f7 y- R8 u# J0 C3 K) ^ - motor1_ForwardRun();
+ g- P- u6 @5 M6 J9 P* S+ G. o - motor2_ForwardRun();
; H1 M8 t2 y! B - break;
9 ]# n4 e/ [2 L9 r: g* G - case KEY_DOWN:
# ?+ ]/ S- s; ?5 J9 W! T# C' Z - case KEY_DOWN_CHANGHONG:, o! A9 @1 M% G) ]& ~: I. n
- motor1_BackwardRun();
' b) |9 I" c% U5 v8 ]( O% D - motor2_BackwardRun();
; n9 b* u7 _( L - break;
& A3 s K$ t7 f- C4 a8 Q. U( y4 Y - case KEY_LEFT:% n V$ T/ k* y
- case KEY_LEFT_CHANGHONG:
4 O* M9 c' I6 Z6 n+ z+ b7 N7 T - motor1_ForwardRun();
4 L6 [3 H8 c3 N& O9 v- n - motor2_Stop();8 X& L5 X# b5 a
- state = SHIP_LEFT;& N% q: X/ F) b/ P& l& F
- break;
6 S6 N5 J: c- ? - case KEY_RIGHT:
$ N! q6 q3 T" X. j$ c5 Z: e - case KEY_RIGHT_CHANGHONG:' F8 h% g! d2 D3 u2 @2 T
- motor2_ForwardRun();
+ v# e! l. H/ d) R4 l9 \ - motor1_Stop();: r8 z& l/ V% ?
- state = SHIP_RIGHT;9 S! `2 G) |! S# o8 _' g# @
- break;5 j7 K6 W4 Z1 u" K9 m9 t( k
- default:
$ d' e2 {/ D9 u- y# | - motor1_Stop();
$ ?, B' e5 a8 C% `; l% k - motor2_Stop();+ z F3 A- K# C7 O0 F0 Q
- state = SHIP_STOP;
& `' [4 Q1 K: s - break;
% l+ \( R: d3 D0 ?7 \- U* G1 T - }7 u1 T& r* g: z5 Z( M
- }6 O2 ^% `% ^$ J/ u
- }
复制代码 : i) `, k6 ^) C( H) P: D+ s
, N) }( b6 d( z/ A1 ~
9 { I, R4 l/ X+ V3 ]* l6 k }
04 DIY成品展示和演示视频
7 }) T& M% j$ y" ? 6 [' R( W: P, V: [6 i
05 总结存在的问题
! @# `, O! ~ ~ \' U, ^0 m+ f; v% ?) z6 m/ T5 `- t- R
遥控不灵敏: K, g4 z" H8 f& u
毕竟红外遥控的使用场合并不是移动的物体上,再加上距离近,经常会出现遥控要按多次的情况。后期考虑改进stm的协议处理方法,增加容错性,如果还是不行就考虑升级为2.4G专用的玩具遥控。1 i2 o3 T/ R) Q0 F
9 D" x+ L$ L) `7 E$ R' z z( I: G& u9 i/ e' o$ K- O. z
防水性问题
. N, D& M# N4 g1 h4 s6 M正常使用不会有水进入,但是在没有大人的情况下交给小孩操作,就没那么保险了。
2 G+ m i2 q+ U+ x. o |后期考虑升级防水性能。8 B+ x- C/ _5 t$ j$ l" v+ K
- I5 D0 n$ @; |+ ?" ?4 z" [
* U; N/ i# A6 H: V- k5 T没有声光电,不够酷炫。
4 h% ^6 V$ P/ S/ j* Z6 ?$ `考虑升级,增加led灯条。$ V$ \0 u; X* x8 O. ]
2 D I/ ^ E/ }) d2 t9 y- e% j/ L
2 o9 T! s) T$ H1 n! P, M, }! W8 ?4 K( W8 Y9 n0 j
3 G$ f: i% ?5 }& x) K2 B E, ^
1 p- u* f9 w( m0 R: ^5 V |
01
前言
- q) }2 X& _/ i' j
前面的文章《基于STM32的DIY遥控小船制作》中使用的HX1838红外遥控模块确实是足够便宜,但是实际用下来遥控距离太短,大概只有2米左右。外加必须指着才能遥控,在公共场合操作起来有些奇怪。3 V( E& J# H9 A1 ~. k
023 W- j& w1 e y
升级改造
$ a, e1 }- X' p8 R6 ~! a
在某宝上寻到了便宜的27Mhz四通道玩具遥控器。
接收小板供电电压4.5-6v,直接接到电池组输出的5V上。小板输出是4个控制信号,按下遥控按键后,由0V变为5V。注意信号接到stm32的ft耐5v管脚上。程序中定时扫描4个gpio的电平,当电平变化时就收到了遥控按键,控制电机做出相应的响应即可。3 w( {+ Z) i8 n4 _" T# O
: K7 K9 `: X2 f$ S0 j
实际使用下来,比红外遥控器强多了,稳定性大大加强,遥控距离4-5m,可玩性提升很多。但是遥控距离还是不够远,后面再升级2.4GHz遥控器。. S: L3 y" g5 y8 ~4 {4 v1 e' f+ U) @
另外还提升防水性能,把小船原来的收纳盒盖子盖上,只露出开关和天线,即使小朋友用水枪喷小船,也算能过关。