<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[TFmini与舵机结合的机器人小车避障应用方案]]></title><description><![CDATA[<p dir="auto">1.试验设备及接线<br />
1.1实验设备<br />
•	MiniQ 桌面机器人底盘<br />
<img src="/assets/uploads/files/1563267749407-1.png" alt="1.png" class=" img-responsive img-markdown" width="225" height="211" /></p>
<ul>
<li>底盘直径：122mm</li>
<li>轮子直径：42mm</li>
<li>底盘高度：15mm</li>
<li>兼容 Arduino 标准板及 Romeo 控制器固定孔</li>
<li>电机参数：<br />
•	   N20 电机电压：3-9V<br />
•	  无负载转速：13000rpm<br />
•	  50：1 减速箱<br />
•	  260rpm@6V<br />
•	  40mA@6V<br />
•	  360mA 堵转@6V<br />
•	  10 盎司英寸扭矩@6V</li>
</ul>
<p dir="auto">•	Romeo 三合一 Arduino 兼容控制器<br />
<img src="/assets/uploads/files/1563267761552-2.png" alt="2.png" class=" img-responsive img-markdown" width="326" height="280" /></p>
<ul>
<li>采用 Atmel Atmega328 单片机</li>
<li>Arduino UNO bootloader</li>
<li>完全兼容 Aruduino UNO 的端口布局</li>
<li>集成 APC220 无线数传和 DF-BluetoothV3(SKU:TEL0026)蓝牙模块接口</li>
<li>支持 5 组 I2C 总线接口</li>
<li>支持两路电机驱动，峰值电流 2A，4 个控制口使用跳线切换</li>
<li>外部输入电压范围：6V~20V</li>
<li>更详细的参数介绍详见附录的网页地址。</li>
</ul>
<p dir="auto">•	MiniQ 小车上层安装板<br />
<img src="/assets/uploads/files/1563267785582-3.png" alt="3.png" class=" img-responsive img-markdown" width="261" height="263" /><br />
•	Benewake TFmini 标版<br />
<img src="/assets/uploads/files/1563267791782-4.png" alt="4.png" class=" img-responsive img-markdown" width="393" height="258" /><br />
TFmini 详细参数见 TFmini 使用说明。</p>
<p dir="auto">•	9g 舵机<br />
<img src="/assets/uploads/files/1563267796619-5.png" alt="5.png" class=" img-responsive img-markdown" width="307" height="228" /><br />
1.2接线<br />
<img src="/assets/uploads/files/1563267802976-6.png" alt="6.png" class=" img-responsive img-markdown" width="718" height="537" /><br />
2.小车避障原理<br />
小车启动后，小车开始向前运动。当雷达探测到前方阈值内有障碍物时，小车停止运动，开始左右扫描寻路。舵机搭载 TFmini 从 90°开始向 180°扫描，然后从 180°向 0°扫描。<br />
<img src="/assets/uploads/files/1563267807615-7.png" alt="7.png" class=" img-responsive img-markdown" width="346" height="182" /><br />
当扫描方向无障碍物时，小车向此方向转向，舵机回正到 90°。若从左至右扫描一圈都没有可以行进的路线，则小车后退，舵机回正。<br />
逻辑流程图如下所示：<br />
<img src="/assets/uploads/files/1563267811117-8.png" alt="8.png" class=" img-responsive img-markdown" width="584" height="736" /><br />
3.注意事项<br />
•	当前避障原理模型只用来抛砖引玉，探索用 TFmini 避障的可行性，并不能大范围的适用于大规模的商业场景，如有需要，应以专业软件开发人员的代码为准。<br />
•	搭载的外部电源过重时，会影响小车车轮的摩擦力，可能两个车轮的转速不一致，导致小车并不能按照轨迹行驶。<br />
•	小车车轮在光滑地面有可能造成空转的现象，导致小车不能走直线。<br />
•	如果单独对 TFmini 外部供电，则需将外部电源和控制板共地处理。<br />
•	如果搭载更高复杂度的程序，要考虑芯片的能力，当前开发板在跑程序时已经发现会有卡顿的现象。<br />
4.附录<br />
4.1代码<br />
#include &lt;Servo.h&gt;<br />
Servo myservo;<br />
int pos=90; //定义舵机角度<br />
bool flag=true;//定义舵机转向<br />
float dist_f;//定义 foward 方向距离<br />
float dist_s;//定义 sideway 方向距离<br />
int E1=5; //定义 M1 使能<br />
int E2=6; //定义 M2 使能<br />
int M1=4; //定义 M1 控制<br />
int M2=7; //定义 M2 控制<br />
int temp_distance =0;<br />
/**</p>
<ul>
<li>双轮停止<br />
<em>/<br />
void brake(void){<br />
digitalWrite(E1,LOW); //给 E1 低电平<br />
digitalWrite(E2,LOW); //给 E2 低电平<br />
}<br />
/</em>*</li>
<li>双轮前进<br />
<em>/<br />
void advance(char a, char b){<br />
analogWrite(E1,a);<br />
digitalWrite(M1,LOW);<br />
analogWrite(E2,b);<br />
digitalWrite(M2,LOW);<br />
}<br />
/</em>*</li>
<li>双轮后退<br />
<em>/<br />
void back(char a, char b){<br />
analogWrite(E1,a);<br />
digitalWrite(M1,HIGH);<br />
analogWrite(E2,b);<br />
digitalWrite(M2,HIGH);<br />
}<br />
/</em>*</li>
<li>左转<br />
<em>/<br />
void turn_L(char a, char b){<br />
analogWrite(E1,a);<br />
digitalWrite(M1,LOW);<br />
analogWrite(E2,b);<br />
digitalWrite(M2,HIGH);<br />
}<br />
/</em>*</li>
<li>右转<br />
<em>/<br />
void turn_R(char a, char b){<br />
analogWrite(E1,a);<br />
digitalWrite(M1,HIGH);<br />
analogWrite(E2,b);<br />
digitalWrite(M2,LOW);<br />
}<br />
/</em>*</li>
<li>读取 TFmini 测量结果<br />
<em>/<br />
void getTFminiData(int</em> distance, int* strength) {<br />
static char i = 0;<br />
char j = 0;<br />
int checksum = 0;<br />
static int rx[9];<br />
if(Serial.available()) {<br />
rx = Serial.read();<br />
if(rx[0] != 0x59) {<br />
i = 0;<br />
} else if(i == 1 &amp;&amp; rx[1] != 0x59) {<br />
i = 0;<br />
} else if(i == <img src="http://community.bwbot.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f60e.png?v=9q7h1n1nrom" class="not-responsive emoji emoji-android emoji--sunglasses" title="8)" alt="😎" /> {<br />
for(j = 0; j &lt; 8; j++) {<br />
checksum += rx[j];<br />
}<br />
/*<br />
if(rx[8] == (checksum % 256)) {<br />
*distance = rx[2] + rx[3] * 256;<br />
<em>strength = rx[4] + rx[5] * 256;<br />
}</em>/<br />
*distance = rx[2] + rx[3] * 256;<br />
<em>strength = rx[4] + rx[5] * 256;<br />
i = 0;<br />
} else {<br />
i++;<br />
}<br />
}<br />
}<br />
void setup() {<br />
// put your setup code here, to run once:<br />
Serial.begin(115200);<br />
//舵机的插口在 4<br />
myservo.attach(4);<br />
brake();<br />
/</em></li>
<li>将雷达指向前方<br />
<em>/<br />
myservo.write(pos);<br />
/</em></li>
<li>设置轮胎电机输出口<br />
<em>/<br />
pinMode(4,OUTPUT);<br />
pinMode(5,OUTPUT);<br />
pinMode(6,OUTPUT);<br />
pinMode(7,OUTPUT);<br />
delay(10);<br />
}<br />
void loop() {<br />
/</em></li>
<li>读数一次<br />
<em>/<br />
int distance = 0;<br />
int strength = 0;<br />
getTFminiData(&amp;distance, &amp;strength);<br />
while(!distance) {<br />
getTFminiData(&amp;distance, &amp;strength);<br />
Serial.print("Distance: ");<br />
Serial.print(distance);<br />
Serial.print("cm ");<br />
Serial.print("strength: ");<br />
Serial.println(strength);<br />
}<br />
/</em></li>
<li>设置 30CM 阈值<br />
<em>/<br />
if(distance &lt;= 30 &amp;&amp; distance &gt; 0){<br />
temp_distance = distance;<br />
}<br />
delay(10);<br />
/</em></li>
<li>判断读数距离</li>
<li>如果度数距离小于阈值，则停车，开始向左向右扫描，直到扫描出有空隙可以走，然后车轮转弯，然后扫描器回正</li>
<li>如果读数距离大于阈值，则开车<br />
<em>/<br />
if(temp_distance &lt;= 30 &amp;&amp; temp_distance &gt;= 0){<br />
brake();<br />
/</em></li>
<li>判断当前舵机应该向左还是向右转<br />
<em>/<br />
if(flag){<br />
if(pos&lt;170){<br />
pos=pos+45;<br />
}else{<br />
flag = false;<br />
}<br />
/</em></li>
<li>如果探测距离大于阈值，则舵机回正，小车转向<br />
<em>/<br />
if(distance &gt; 32){<br />
pos = 90;<br />
myservo.write(pos);<br />
delay(1200);<br />
//判断小车回正方向<br />
if(pos &gt;= 90){<br />
turn_L(35,35);<br />
}else{<br />
turn_R(35,35);<br />
}<br />
delay(250);<br />
temp_distance = distance;<br />
}<br />
/</em></li>
<li>如果探测距离小于阈值，则继续扫描<br />
<em>/<br />
else{<br />
myservo.write(pos);<br />
delay(1200);<br />
}<br />
}else{<br />
if(pos&gt;10){<br />
pos=pos-45;<br />
}else{<br />
flag=true;<br />
}<br />
/</em></li>
<li>如果探测距离大于阈值，则舵机回正，小车转向<br />
<em>/<br />
if(distance &gt; 32){<br />
pos = 90;<br />
myservo.write(pos);<br />
delay(1200);<br />
//判断小车回正方向<br />
if(pos &gt;= 90){<br />
turn_L(35,35);<br />
}else{<br />
turn_R(35,35);<br />
}<br />
delay(250);<br />
temp_distance = distance;<br />
}<br />
/</em></li>
<li>如果探测距离小于阈值，则继续扫描<br />
<em>/<br />
else{<br />
myservo.write(pos);<br />
delay(1200);<br />
}<br />
}<br />
}<br />
/</em></li>
<li>如果前方没有障碍物，直行<br />
<em>/<br />
else if(distance &gt; 32 &amp;&amp; distance &lt; 1200){<br />
advance(35,35);<br />
}<br />
/</em></li>
<li>如果雷达挂了，小车停止<br />
*/<br />
else if(distance == -3){<br />
brake();<br />
}<br />
}</li>
</ul>
]]></description><link>http://community.bwbot.org/topic/772/tfmini与舵机结合的机器人小车避障应用方案</link><generator>RSS for Node</generator><lastBuildDate>Sat, 06 Jun 2026 12:59:08 GMT</lastBuildDate><atom:link href="http://community.bwbot.org/topic/772.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 16 Jul 2019 09:04:01 GMT</pubDate><ttl>60</ttl></channel></rss>