After painting for 11 hours, you can go to Station B to see the production process and search for "EDA Open Source". The functions implemented by the circuit can be completed with the program: PID five-way automatic tracking, light search, and fire search functions. The Bluetooth remote control function (variable speed control plus steering control) can be realized through the Bluetooth module. The driver of the board uses the RZ7899 chip driver. The 4-way light tracking needs to be used in conjunction with the 4-way tracking module on Taobao. In fact, it can also be used I printed out the small board and made it myself. Since I had the finished product, I didn’t make the tracking head myself. (Improvement suggestion is to make a head yourself, and then connect it with a cable, so that the car looks more beautiful!!) The EDA board making process that lasted for 11 hours (compressed into three minutes, super fast): https://www .bilibili.com/video/BV1E741177mW/ The final actual test video clip of the car (off-road fun remote control performance is excellent): https://www.bilibili.com/video/BV15E411g78h/ There are many smart car videos before using EDA, you can see a lot There are a lot of densely packed wires, so it’s better to build a circuit board! ! ! https://www.bilibili.com/video/BV1E7411f7Cf/
https://www.jianshu.com/p/1a8262492619Bluetooth Debugger Instructions
I recently built a high-speed Bluetooth remote control car, and the speed is expected to be above 40km/h. Welcome to the Lichuang Open Source Community to follow me on veryshunshine. There are many interesting projects in it. There are many videos about electronic production on Bilibili, most of which are through Completed by Lichuang, please follow my ID: "Walking on the edge of the universe" If the car likes it or if there are many people who want it, I will have time to publish a video and explain the program again. Let's learn and make progress together! A junior and sophomore student from Handan College (the longest major name in the school!), College of Mechanical and Electrical Engineering, majoring in Mechanical Design, Manufacturing and Automated Intelligent Manufacturing. I like electronic production. Why did I choose machinery (because there is definitely a lot of hands-on work with machinery, and electronics also has to be considered, haha) Haha, structural machinery also needs to calculate a lot of things...) Welcome to communicate with us! @立Chuangchongya! ! !
Design ideas:
It was the first to use arduino binary control. It has rich functions, simple code movement, simple and feasible control. It is equipped with dual voltage output modules. The electric belt age driver is controlled by RZ7899. It is equipped with headlights and ultrasonic modules, and has light and fire smoke search. and other expansion modules.
Circuit composition:
Composed of power module, motor drive module, sensor module, main control board module, tracking analysis module, etc.
Implementation function:
The most basic functions include differential steering, variable speed control, light seeking, flame seeking, obstacle avoidance, following, etc. It also has a very important tracking function.
//////////////////////////////////////////////////////////////////////////////////////////////
//// 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);
}
All reference designs on this site are sourced from major semiconductor manufacturers or collected online for learning and research. The copyright belongs to the semiconductor manufacturer or the original author. If you believe that the reference design of this site infringes upon your relevant rights and interests, please send us a rights notice. As a neutral platform service provider, we will take measures to delete the relevant content in accordance with relevant laws after receiving the relevant notice from the rights holder. Please send relevant notifications to email: bbs_service@eeworld.com.cn.
It is your responsibility to test the circuit yourself and determine its suitability for you. EEWorld will not be liable for direct, indirect, special, incidental, consequential or punitive damages arising from any cause or anything connected to any reference design used.
Supported by EEWorld Datasheet