經過實際測試車跑的非常快,容易失控,這個主板適用于控制大電機,現在考慮使用RZ7899并聯控制輸出或者是使用蘿莉遙控器控制,下一個成品預計會很長時間,因為要專心學習而且遇到了瓶頸(2.4hhz pwm控制的程序不會寫要是有大佬幫助我感激不盡) 這次車是厲害的很 加入了減速器就不怕車輪掉下來了。 建議電機上加104電容消除高頻干擾。
制造過程展示:
https://www.bilibili.com/read/cv6217381
視頻成果展示
https://www.bilibili.com/video/bv1cz411B7Se
https://www.bilibili.com/video/bv1A5411s7Vs
程序在這:
//////////////////////////////////////////////////////////////////////////////////////////////
//// 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);
}
!注意:請使用瀏覽器自帶下載,迅雷等下載軟件可能無法下載到有效資源。
歡迎加入EEWorld參考設計群,也許能碰到搞同一個設計的小伙伴,群聊設計經驗和難點。 入群方式:微信搜索“helloeeworld”或者掃描二維碼,備注:參考設計,即可被拉入群。 另外,如您在下載此設計遇到問題,也可以微信添加“helloeeworld”及時溝通。
EEWorld Datasheet 技術支持