加入交流群  

扫一扫,添加管理员微信
备注:参考设计,即可被拉入群
和也在搞设计小伙伴们碰一碰

收藏 

评论 

黄土马家 发布

邯郸学院-智能小车驱动板寻光循迹超声波避障测速蓝牙遥控成板。

 
设计简介

画了11个小时,可以去B站看制做过程 搜索“立创EDA开源” 电路实现的功能可以搭配程序完成: PID五路自动循迹、寻光、寻火功能。 通过蓝牙模块可以实现蓝牙遥控功能(变速控制加上转向控制),板子的驱动使用的是RZ7899贴片驱动,4路寻光是需要和淘宝上的4路循迹模块搭配使用,其实也可以把小板打出来自己弄,因为有成品我就没自己做循迹头了。(改进建议就是自己做一个头,然后用排线连接,这样车显得更漂亮了!!) 连续肝了11小时的EDA制板过程(压缩成了三分钟 超急爽):https://www.bilibili.com/video/BV1E741177mW/ 小车最终实测视频片段(越野趣味遥控性能极佳):https://www.bilibili.com/video/BV15E411g78h/ 没有用EDA之前的智能小车视频,可以看到好多好多线密密麻麻的,还是打电路板好!!!https://www.bilibili.com/video/BV1E7411f7Cf/

https://www.jianshu.com/p/1a8262492619 蓝牙调试器使用说明


最近做了一个高速蓝牙遥控车,速度预计在40km/h以上,欢迎来立创开源社区关注我veryshunshine 里边有好多好玩的工程哦 在哔哩哔哩里有很多关于电子制作的视频,大多是通过立创完成的,欢迎关注我的ID:“漫步在宇宙的边缘” 要是小车点赞或者需要的人多的话我有时间出一期视频,把程序讲一遍,咱们一起学习进步! 小生大二邯郸学院(全校最长专业名!)机电学院机械设计制造及其自动化智能制造专业 在校生,爱好电子制作,为啥选了机械呢(因为机械动手肯定多,电子还得算,哈哈哈,结构机械也要计算好多好多东西。。。)欢迎一起交流鸭!@立创 冲鸭!!!

设计思路:

最先采用arduino进制控制,其功能丰富,代码简单移动,操控简单可行,配置双路电压输出模块,电带年纪驱动采用RZ7899进行控制,搭载车前灯以及超声波模块,拥有寻光寻火烟等拓展模块。

电路组成:

电源模块电机驱动模块、传感器模块、主控板模块、循迹分析模块等组成

实现功能:

最基本的功能有差速转向、变速控制、寻光、寻火焰、避障、跟随、等等并具有非常重要的循迹功能。


//////////////////////////////////////////////////////////////////////////////////////////////
//// Communication protocol start
//// ----the only thing you need to do is modifying the numbers of variables according to your demand
//
//****define what to send to cell phone*******************
#define NUM_TX_BOOL   0
#define NUM_TX_BYTE   2
#define NUM_TX_SHORT  0
#define NUM_TX_INT    0
#define NUM_TX_FLOAT  0
//*******************************************************

//****define what we want to get from cell phone********
#define NUM_RX_BOOL   1
#define NUM_RX_BYTE   2
#define NUM_RX_SHORT  0
#define NUM_RX_INT    0
#define NUM_RX_FLOAT  0
//*******************************************************

// size of Loop Buffer is editable depending on the data packet transmission rate and memory space
#define LOOP_BUFFER_SIZE 512
#define SIZE_RECV_PERTIME 64  // fixed

/////////////////////////////////////////////////////
//Do not change the code below+++++++++++++++++++++++
/////////////////////////////////////////////////////
// data structure to send to phone
struct {
bool bools        [NUM_TX_BOOL];
int8_t bytes      [NUM_TX_BYTE];
int16_t shorts    [NUM_TX_SHORT];
int32_t  integers [NUM_TX_INT];
float   floats    [NUM_TX_FLOAT];
}txPack;

// data structure to recv from phone
struct {
bool bools        [NUM_RX_BOOL];
int8_t bytes      [NUM_RX_BYTE];
int16_t shorts    [NUM_RX_SHORT];
int32_t  integers [NUM_RX_INT];
float   floats    [NUM_RX_FLOAT];
} rxPack;

byte loopBuffer[LOOP_BUFFER_SIZE];
byte rxPacketBuffer[((NUM_RX_BOOL+7)>>3)+NUM_RX_BYTE+(NUM_RX_SHORT<<1)+(NUM_RX_INT<<2)+(NUM_RX_FLOAT<<2)+3];
byte txPacketBuffer[((NUM_TX_BOOL+7)>>3)+NUM_TX_BYTE+(NUM_TX_SHORT<<1)+(NUM_TX_INT<<2)+(NUM_TX_FLOAT<<2)+3];

int16_t RXPACK_SIZE = sizeof(rxPacketBuffer);
int16_t TXPACK_SIZE = sizeof(txPacketBuffer);
int32_t INDEX_RANGE = LOOP_BUFFER_SIZE*2;

HardwareSerial *pSerial;

void initPack(HardwareSerial &serial, int32_t baudRate)
{
serial.begin(baudRate);
serial.setTimeout(0);
pSerial = &serial;
}
void getVariables(void)
{
unsigned char byte_pos=0,bit_pos=0;
#if (NUM_RX_BOOL>0)
for(int i=0;i<NUM_RX_BOOL;i++)
{
rxPack.bools[i] = (0x01<<bit_pos)&rxPacketBuffer[byte_pos];
bit_pos++;
if(bit_pos>=8)
{
byte_pos++;
bit_pos=0;
}
}
if(bit_pos!=0)
byte_pos++;
#endif

#if (NUM_RX_BYTE>0)
for(int i=0;i<NUM_RX_BYTE;i++)
{
rxPack.bytes[i] = rxPacketBuffer[byte_pos];
byte_pos++;
}
#endif

#if (NUM_RX_SHORT>0)
for(int i=0;i<NUM_RX_SHORT;i++)
{
rxPack.shorts[i] = (rxPacketBuffer[byte_pos+1]<<8)|rxPacketBuffer[byte_pos];
byte_pos+=2;
}
#endif

#if (NUM_RX_INT>0)
for(int i=0;i<NUM_RX_INT;i++)
{
rxPack.integers[i] = (rxPacketBuffer[byte_pos+3]<<24)| (rxPacketBuffer[byte_pos+2]<<16)| (rxPacketBuffer[byte_pos+1]<<8)|rxPacketBuffer[byte_pos];
byte_pos+=4;
}
#endif

#if (NUM_RX_FLOAT>0)
float f;
byte *p = (byte *) &f;
int pp=0;
for(int i=0;i<NUM_RX_FLOAT;i++)
{
p[0+pp] =  rxPacketBuffer[byte_pos];
p[1+pp] =  rxPacketBuffer[byte_pos+1];
p[2+pp] =  rxPacketBuffer[byte_pos+2];
p[3+pp] =  rxPacketBuffer[byte_pos+3];
pp+=4;
byte_pos+=4;
rxPack.floats[i] = f;
}
#endif

}
int32_t  rxIndex=0;
int32_t rdIndex=0;
int32_t err=0;
int32_t sum;
bool recvPack(void)
{

int start_index;
int tail_index;
int cut_size;
int rx_length;
bool isOK = 0;
int rx_pack_index;

// read bytes to loop buffer
start_index = rxIndex%LOOP_BUFFER_SIZE;
if(start_index+SIZE_RECV_PERTIME<=LOOP_BUFFER_SIZE)
{
rx_length+=pSerial->readBytes(loopBuffer+start_index,SIZE_RECV_PERTIME);
rxIndex+=rx_length;
}else
{
cut_size = LOOP_BUFFER_SIZE-start_index;
rx_length=pSerial->readBytes(loopBuffer+start_index,cut_size);
rxIndex+=rx_length;
if(rx_length==cut_size)
{
cut_size = SIZE_RECV_PERTIME-cut_size;
rx_length=pSerial->readBytes(loopBuffer,cut_size);
rxIndex+=rx_length;
}
}

// extract a complete packet
while(rdIndex<(rxIndex-2*RXPACK_SIZE))
rdIndex+=RXPACK_SIZE;

while(rdIndex<=rxIndex-RXPACK_SIZE)
{
start_index = rdIndex%LOOP_BUFFER_SIZE;
isOK = 0;
if(loopBuffer[start_index]==0xA5)
{
tail_index = (start_index+RXPACK_SIZE-1)%LOOP_BUFFER_SIZE;
if(loopBuffer[tail_index]==0x5A)  // Head and Tail match
{
rx_pack_index = 0;
// Check Summing
sum = 0;
// if data packet is divided into two segments
if(tail_index<start_index)
{
for(int i = start_index+1;i<LOOP_BUFFER_SIZE;i++)
{
rxPacketBuffer[rx_pack_index] = loopBuffer[i];
rx_pack_index++;
sum+=loopBuffer[i];
}
for(int i = 0;i<tail_index-1;i++)
{
rxPacketBuffer[rx_pack_index] = loopBuffer[i];
rx_pack_index++;
sum+=loopBuffer[i];
}
tail_index--;
if(tail_index<0)
tail_index+=LOOP_BUFFER_SIZE;

if(loopBuffer[tail_index]==(sum&0xff))
isOK = 1;
}else // data packet is contiguous
{
for(int i = start_index+1;i<tail_index-1;i++)
{
rxPacketBuffer[rx_pack_index] = loopBuffer[i];
rx_pack_index++;
sum+=loopBuffer[i];
}
if(loopBuffer[tail_index-1]==(sum&0xff))
isOK = 1;
}
if(isOK) // parse the data to rxPack
{
getVariables();
rdIndex+=RXPACK_SIZE;
}
}
}
if(!isOK)
{
rdIndex++;
err++;
}
}
// limit the range of read index and recv index
if(rxIndex>INDEX_RANGE&&rdIndex>INDEX_RANGE)
{
rxIndex-=INDEX_RANGE;
rdIndex-=INDEX_RANGE;
}
return isOK;
}

void sendPack(void)
{
short byte_pos=0,bit_pos=0;
int32_t sum=0;
txPacketBuffer[byte_pos++] = 0xA5;

#if (NUM_TX_BOOL>0)
for(int i=0;i<NUM_TX_BOOL;i++)
{
if(txPack.bools[i])
txPacketBuffer[byte_pos] |= 0x01<<bit_pos;
else
txPacketBuffer[byte_pos] &= ~(0x01<<bit_pos);
bit_pos++;
if(bit_pos>=8)
{
byte_pos++;
bit_pos=0;
}
}
if(bit_pos!=0)
byte_pos++;
#endif

#if (NUM_TX_BYTE>0)

for(int i=0;i<NUM_TX_BYTE;i++)
txPacketBuffer[byte_pos++] = txPack.bytes[i];

#endif

#if (NUM_TX_SHORT>0)
for(int i=0;i<NUM_TX_SHORT;i++)
{
txPacketBuffer[byte_pos++] = txPack.shorts[i]&0xff;
txPacketBuffer[byte_pos++] = (txPack.shorts[i]>>8)&0xff;
}
#endif

#if (NUM_TX_INT>0)
for(int i=0;i<NUM_TX_INT;i++)
{
txPacketBuffer[byte_pos++] = txPack.integers[i]&0xff;
txPacketBuffer[byte_pos++] = (txPack.integers[i]>>8)&0xff;
txPacketBuffer[byte_pos++] = (txPack.integers[i]>>16)&0xff;
txPacketBuffer[byte_pos++] = (txPack.integers[i]>>24)&0xff;
}
#endif

#if (NUM_TX_FLOAT>0)
float f;
byte *add;
for(int i=0;i<NUM_TX_FLOAT;i++)
{
f = txPack.floats[i];
add = (byte *)&f;

txPacketBuffer[byte_pos++] = add[0];
txPacketBuffer[byte_pos++] = add[1];
txPacketBuffer[byte_pos++] = add[2];
txPacketBuffer[byte_pos++] = add[3];
}
#endif

for(int i=1;i<TXPACK_SIZE-2;i++)
sum+=txPacketBuffer[i];
txPacketBuffer[byte_pos++] = sum&0xff;
txPacketBuffer[byte_pos] = 0x5a;

pSerial->write(txPacketBuffer,TXPACK_SIZE);
}

/////////////////////////////////////////////////////
//Do not change the code above-----------------------
/////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//
//// Communication protocol end//////////////////////
/////////////////////////////////////////////////////

#define leftA_PIN 6
#define leftB_PIN 5
#define righA_PIN 9
#define righB_PIN 10

void motor_pinint();
void motorcontrol();
void sdcl();
unsigned long SDA2;//定义duration变量为无符号长整数型变量
unsigned long SDA3;//定义duration变量为无符号长整数型变量
unsigned long A=0.0;//定义duration变量为无符号长整数型变量
unsigned long B=0.0;//定义duration变量为无符号长整数型变量
int i=0;
int Y=0;
int X=0;
int CD=0;

/*电机引脚初始化*/
void motor_pinint()
{
pinMode (leftA_PIN, OUTPUT); //设置引脚为输出引脚
pinMode (leftB_PIN, OUTPUT); //设置引脚为输出引脚
pinMode (righA_PIN, OUTPUT); //设置引脚为输出引脚
pinMode (righB_PIN, OUTPUT); //设置引脚为输出引脚
}

void motorcontrol()
{
if (Y>0)
{
if(X>0||X==0)
{
analogWrite(righA_PIN, Y-X);
analogWrite(righB_PIN, 0);
analogWrite(leftA_PIN, Y);
analogWrite(leftB_PIN, 0);
}
else
{
analogWrite(righA_PIN, Y);
analogWrite(righB_PIN, 0);
analogWrite(leftA_PIN, Y+X);
analogWrite(leftB_PIN, 0);
}
}

else if(Y<0)
{
if(X>0)
{
analogWrite(righA_PIN, 0);
analogWrite(righB_PIN, -Y-X);
analogWrite(leftA_PIN, 0);
analogWrite(leftB_PIN, -Y);
}
else
{
analogWrite(righA_PIN, 0);
analogWrite(righB_PIN, -Y);
analogWrite(leftA_PIN, 0);
analogWrite(leftB_PIN, -Y+X);
}
}
else
{
analogWrite(righA_PIN, 0);
analogWrite(righB_PIN, 0);
analogWrite(leftA_PIN, 0);
analogWrite(leftB_PIN, 0);
}
}
void setup()
{
motor_pinint();
Serial.begin(9600); //串口波特率9600(PC端使用)
initPack(Serial,9600);
}

void loop()
{
if(recvPack()) // if recved
{
Y=rxPack.bytes[0]2;
*    X=rxPack.bytes[1]2;*
**    CD=rxPack.bools[0];*
*    digitalWrite(A4,CD);*
*    }*
*    motorcontrol();*
*    sdcl();*
*    sendPack();*
*  /*

// delay(1000);
// Serial.print("Y:");
// Serial.print(rxPack.bytes[0]*2);
//Serial.print(" ");
// Serial.print("X:");
// Serial.println(rxPack.bytes[1]*2);

if (X > 0) {
analogWrite(leftA_PIN, X);
analogWrite(leftB_PIN, 0);
} else {
analogWrite(leftA_PIN, 0);
analogWrite(leftB_PIN, -X);
}/
//速度设定范围(-100,100)
/void motorsWritePct(int speedLpct, int Xpct) {**
**  //speedLpct, speedRpct ranges from -100 to 100*
*  motorsWrite(speedLpct * 2.55, speedRpct * 2.55);*
}/
}
void sdcl()
{
A=0.0;
B=0.0;
for(i=0;i<4;i++)//三次平均值
{
SDA3 = pulseIn(A3,0,100000); //读取引脚上的高电平脉冲
SDA2 = pulseIn(A2,0,100000); //读取引脚上的高电平脉冲
A=A+(357500.0/SDA3);
B=B+(357500.0/SDA2);
}

txPack.bytes[1] =(B/4);
txPack.bytes[0] =(A/4);
// Serial.print(B/3);
// Serial.println(A/3);
// delay(1);
}

!注意:请使用浏览器自带下载,迅雷等下载软件可能无法下载到有效资源。

 
相关器件
器件 类型 描述 数据手册
CS2012X7R104K500NRB 贴片电容(MLCC) 点击下载
AECR0805F10K0K9 贴片电阻 功率:1/8W 精度:±1% 阻值(欧姆):10K 0.125W 车规电阻 点击下载
08052A201JAT2A 贴片电容(MLCC) 点击下载
rz7899 电机驱动 25V 4A 控制直流电机正反转 点击下载
TC3838RGB-3CSA-TX1812HC 发光二极管 发光颜色:RGB三色 主波长:465nm~470nm;520nm~525nm;620nm~625nm 测试电流:20mA 正向电压(VF):5V 发光强度:1800mcd;700mcd;500mcd 工作温度:-40℃~+85℃ 3838RGB集成光源内置IC幻彩灯珠单点单控5v12ma 点击下载
B-2200S06P-B120 排母 点击下载
CGA4J2X7R1H104KT0Y0S 贴片电容 精度:±10% 容值:100nF 额定电压:50V 温漂系数(介质材料):X7R 材质:X7R 点击下载
A2541WR-3P 排针排母 针脚数:3 连接器类型:排针 排数:1 触头类型:公形引脚 间距:0.100"(2.54mm) - 点击下载
HX6306P332MR 低压差线性稳压(LDO) 输出类型:固定 最大输入电压:10V 输出电流:300mA 输出电压(最小值/固定值):3.3V 点击下载
D-B080508B1-KS2 发光二极管 照明颜色:蓝色 主波长/色坐标:456~457nm 0805蓝灯,高亮:33-36mcd@5mA,波长:456-457nm,耐ESD:1000V 点击下载
2.54-2*15P双排针 排针排母 针脚数:30 连接器类型:排针 排数:2 触头类型:公形引脚 间距:0.100"(2.54mm) 点击下载
ORH-G36G 发光二极管 照明颜色:绿色 主波长/色坐标:520~535nm 色温 - CCT(K):- 点击下载
3-644456-2 排针排母 针脚数:2 连接器类型:排针 排数:1 触头类型:公形引脚 间距:0.100"(2.54mm) 点击下载
SS-12D10L5 拨动开关 额定电压 DC:50V 触点额定电流:300mA @ 50VDC 开关功能:On-On 电路结构:SPDT 额定电压 AC:- 点击下载
RS-05K103JT 贴片电阻 阻值(欧姆):10K 精度:±5% 功率:1/8W 温度系数:±100ppm/°C 点击下载
A2541WV-4P 排针排母 针脚数:4 连接器类型:排针 排数:1 触头类型:公形引脚 间距:0.100"(2.54mm) - 点击下载
A2541WV-4P 排针排母 针脚数:4 连接器类型:排针 排数:1 触头类型:公形引脚 间距:0.100"(2.54mm) - 点击下载
MSS22D18G2 拨动开关 点击下载
B-2200S15P-A120 排母 点击下载
E6C0805URAC1UDA 发光二极管 照明颜色:红色 主波长/色坐标:616~626nm 点击下载
L7805CV 线性稳压芯片 输出类型:固定 最大输入电压:35V 输出电流:1.5A 输出电压(最小值/固定值):5V 5.0V 散热片厚度0.6mm 点击下载
LM339DT 电压比较器 输出类型:CMOS, DTL, ECL, MOS, Open-Collector, TTL 各通道功耗:2.5mA 传播延迟:- 比较器组数:4 电源电压:2V ~ 32V, ±1V ~ 16V 点击下载
MSS22D18G4 拨动开关 点击下载
3296W-1-103 精密可调电阻 阻值(欧姆):10K 精度:±10% 温度系数:±250ppm/℃ . 点击下载
XH-2A 线对板/线对线连接器 针脚数:2 连接器类型:针座 触头类型:公形引脚 间距:0.098"(2.50mm) 系列:XH 点击下载
WJ2EDGVC-5.08-2P 插拔式接线端子 类型:插针/板端,带罩(4面) 间距:0.200"(5.08mm) 每级针脚数:2 级别数:1 极数:2 点击下载
1206W4F1001T5 贴片电阻 阻值(欧姆):1K 精度:±1% 功率:1/4W 温度系数:±100ppm/°C 点击下载
NANOSMDC075F-2 /RF1348-000 自恢复保险丝 点击下载
50ME330AX+T 引线型铝电解电容 容值:330uF 精度:±20% 额定电压:50V 工作寿命:5000Hrs @ 105℃ 外观尺寸(¢DxL,mm):10x22 点击下载
群聊设计,与管理员及时沟通

欢迎加入EEWorld参考设计群,也许能碰到搞同一个设计的小伙伴,群聊设计经验和难点。 入群方式:微信搜索“helloeeworld”或者扫描二维码,备注:参考设计,即可被拉入群。 另外,如您在下载此设计遇到问题,也可以微信添加“helloeeworld”及时沟通。

 
下载中心 更多
查找数据手册?

EEWorld Datasheet 技术支持

论坛推荐 更多
更新时间2024-11-21 11:54:11

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版 版权声明

EEWORLD参考设计中心

站点相关: TI培训 德州仪器(TI)官方视频课程培训

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved