石榴姐

Level 1 deceleration racing car arduino control

 
Overview

After actual testing, the car ran very fast and easily lost control. This motherboard is suitable for controlling large motors. Now I am considering using RZ7899 to control the output in parallel or using a Loli remote control. The next finished product is expected to take a long time because I have to concentrate on learning and I encountered a bottleneck (I don’t know how to write the program controlled by 2.4hhz pwm. I would be very grateful if someone can help me). This time the car is very powerful. With the addition of a reducer, I am not afraid of the wheels falling off. It is recommended to add a 104 capacitor to the motor to eliminate high-frequency interference.

Manufacturing process display: https://www.bilibili.com/read/cv6217381 Video results display https://www.bilibili.com/video/bv1cz411B7Se https://www.bilibili.com/video/bv1A5411s7Vs IMG_20200522_171527.jpgIMG_20200522_171521.jpgIMG_20200522_101023.jpg The program is here:

//////////////////////////////////////////////////////////////////////////////////////////////
//// 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   0
#define NUM_TX_SHORT  2
#define NUM_TX_INT    0
#define NUM_TX_FLOAT  0
//*******************************************************

//****define what we want to get from cell phone********
#define NUM_RX_BOOL   3
#define NUM_RX_ByTE   5
#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 righA_PIN 9
#define righB_PIN 10
#include <Servo.h>

void motor_pinint();
void LEFTmotorcontrolGO();
void RIGHTmotorcontrolBACK();
void RIGHTmotorcontrolGO();
void LEFTmotorcontrolBACK();
void motorcontrolSTOP();
void LEFTmotorcontrolSTOP();
void RIGHTmotorcontrolSTOP();
void STOPP();
void sdcl();

/*电机引脚初始化*/
void motor_pinint()
{
pinMode (righA_PIN, OUTPUT); //设置引脚为输出引脚
pinMode (righB_PIN, OUTPUT); //设置引脚为输出引脚
pinMode (6, OUTPUT); //设置引脚为输出引脚
pinMode (5, OUTPUT); //设置引脚为输出引脚
pinMode (12, OUTPUT); //设置引脚为输出引脚
pinMode (2,OUTPUT);
pinMode (A0, INPUT);
}

Servo myservo;  // 定义Servo对象来控制
int pos = 0;    // 角度存储变量
int sudu=0;
int SPEED=0;
int led=0;
int closetime=0;
int opentime=0;
int dangwei=0;
int zhuanxiang=0;
int k=9900;
int i=0;
int sc=0;
int duoji=100;
int sd=0;
int zxcha=0;
unsigned long duration;
unsigned long A=0.0;//定义duration变量为无符号长整数型变量

void setup()
{
myservo.attach(11);
motor_pinint();
Serial.begin(19200); //串口波特率9600(PC端使用)
initPack(Serial,19200);
}

void loop()
{
if(recvPack())
{
sudu=rxPack.bytes[0];
duoji=rxPack.bytes[3];
zxcha=rxPack.bytes[4];
led=rxPack.bools[0]2;
*    sc=rxPack.bools[1];*
*    sd=rxPack.bools[2];*
*      if (sc==1) myservo.write(duoji);*
*      else myservo.write(100);*
*    dangwei=rxPack.bytes[1];*
*    zhuanxiang=rxPack.bytes[2];*
*    digitalWrite(12,led);*
*    SPEED=dangweisudu;
Serial.println(SPEED);
if(SPEED>9900){
digitalWrite(2,LOW);
LEFTmotorcontrolGO();
RIGHTmotorcontrolGO();}
else if(SPEED<-9900){
digitalWrite(2,LOW);
RIGHTmotorcontrolBACK();
LEFTmotorcontrolBACK();}
else if(SPEED>=1000)
{
digitalWrite(2,LOW);
opentime = map(SPEED, 1000, 9900, 200, 0);
closetime = map(SPEED, 1000, 9900, 5, 100);
RIGHTmotorcontrolGO();
LEFTmotorcontrolGO();
delay(closetime);           //延时1000ms
if(zhuanxiang>=30)
{
k=(zhuanxiangSPEED)/100;
zhuanxiang=map(k,300,9900,zxcha,0);
LEFTmotorcontrolSTOP();
delay(zhuanxiang);
}
motorcontrolSTOP();
delay(opentime);           //延时1s
}

else if(SPEED<=-1000)
{
digitalWrite(2,LOW);
SPEED=-SPEED;
opentime = map(SPEED, 1000, 9900, 200, 0);
closetime = map(SPEED, 1000, 9900, 5, 100);
RIGHTmotorcontrolBACK();
LEFTmotorcontrolBACK();
delay(closetime);           //延时1000ms
if(zhuanxiang<=-30)
{
zhuanxiang=-zhuanxiang;
k=(zhuanxiang*SPEED)/100;
zhuanxiang=map(k,300,9900,zxcha,0);
RIGHTmotorcontrolSTOP();
delay(zhuanxiang);
}
motorcontrolSTOP();
delay(opentime);           //延时1s
}
else{
motorcontrolSTOP();
STOPP();
}
}
if (sd==1) {sdcl();
sendPack();}

}

void RIGHTmotorcontrolGO()
{
digitalWrite(righA_PIN, HIGH);
digitalWrite(righB_PIN, LOW);
}

void LEFTmotorcontrolGO()
{
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
}
void RIGHTmotorcontrolBACK()
{
digitalWrite(righA_PIN, LOW);
digitalWrite(righB_PIN, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, LOW);
}

void LEFTmotorcontrolBACK()
{
digitalWrite(6, HIGH);
digitalWrite(5, LOW);
}

void RIGHTmotorcontrolSTOP()
{
digitalWrite(2,LOW);
digitalWrite(righA_PIN, LOW);
digitalWrite(righB_PIN, LOW);
}
void LEFTmotorcontrolSTOP()
{
digitalWrite(2,LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);

}
void motorcontrolSTOP()
{
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(righA_PIN, LOW);
digitalWrite(righB_PIN, LOW);

}

void STOPP()
{
delay(5);
digitalWrite(2,HIGH);
Serial.println("停止");

}

void sdcl()
{
duration = pulseIn(A0,HIGH);
A = 17278759.595/duration;
Serial.println(A);
txPack.shorts[0] =(A);
txPack.shorts[1] =(A/100*3.6);
//Serial.println(duration);
}
 
 
Search Datasheet?

Supported by EEWorld Datasheet

Forum More
Update:2025-06-04 17:48:22

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
community

Robot
development
community

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号