控制流图如下图所示:
arduino代码见下:
#include <Wire.h>
#define I2C_ADDR 0x2D
#define numOfValRec 2//值的数量
#define digitsPerValRec 3//值的位数,例如255,007
int valsRec[numOfValRec];//接受数组
int stringLength = numOfValRec*digitsPerValRec + 1;//数组长度,+1式$的验证
int counter = 0;
bool counterStart = false;
String recString;
bool test_flag = false;
void setup()
{
//pinMode(13,OUTPUT);
Wire.begin();
pinMode(2,OUTPUT);
Serial.begin(9600);
}
void recData()//串口通信接受
{
while(Serial.available())
{
char c = Serial.read();
if (c == '$')//起始验证位
{
counterStart = true;
}
if(counterStart)
{if(counter<stringLength)
{
recString = String(recString + c);
counter++;
}
if(counter >=stringLength )
{
for(int i =0;i<numOfValRec;i++)
{
int num = (i*digitsPerValRec) +1 ;
valsRec[i] = recString.substring(num,num+digitsPerValRec).toInt();
}
recString = "";
counter = 0;
counterStart=false;
}
}
}
}
bool I2CWrite(unsigned char reg_addr,unsigned char date)//IIC舵机控制
{
Wire.beginTransmission(I2C_ADDR); //发送Device地址
Wire.write(reg_addr); //发送要操作的舵机
Wire.write(date); //发送要设置的角度
if(Wire.endTransmission()!=0) //发送结束信号
{
delay(10);
return false;
}
delay(10);
return true;
}
void loop() {
recData();
if((valsRec[0]==666) && (valsRec[0]==666))//$666666 自检查
{
I2CWrite(1,90);
I2CWrite(2,0*2/3);
delay(500);
// I2CWrite(1,90);
//I2CWrite(2,120*2/3);
//delay(500);
//I2CWrite(1,120);
//I2CWrite(2,120*2/3);
//delay(500);
//I2CWrite(1,90);
//I2CWrite(2,0*2/3);
//delay(500);
//delay(5000);
test_flag = true;
}
else if(test_flag)
{
I2CWrite(1,valsRec[0]);//设置舵机S1角度valsRec[0]
I2CWrite(2,valsRec[1]*2/3);//设置舵机S1角度valsRec[1]*2/3,因为S2是270舵机
delay(500);
}
//digitalWrite(13,HIGH);
}
注意1:
I2C_ADDR,I2C的地址为0x2D;
numOfValRec为我们要接受jetson发送的值的数量,比如 [122,233,548] ,值的数量为3;
digitsPerValRec为我们要接受jetson发送的值的位数,例如[122,003,548],位数为3;
jetson和arduino的串口通信波特率统一为9600;
每一次重启我们必须发送复位值666之后才能控制舵机;
jetson的python代码如下:
import serial
import time
"""jetson发送数据"""
def initConnection(portNo,baudRate):
try:
ser = serial.Serial(portNo,baudRate)#portNo:端口地址;baudRate:波特率
print("Device Connectde")
return ser
except:
print("Not Connectde")
def sendData(se,data,digits):
myString = '$'
for d in data:
myString += str(d).zfill(digits)#25填充为025;
try:
se.write(myString.encode())
print(myString)
except:
print("Data Transmission Failed!")
if __name__ =="__main__":
ser = initConnection("COM4",9600)#linux系统类似/dev/ttyUSB0,window为COM4之类的;/dev/ttyUSB0
while True:
sendData(ser, [666, 255], 3)
注意2:
arduino也会占用一个端口;
sendData(ser, [666, 255], 3) 第一个参数为实例化的串口对象,第二个参数是我们要发送角度数组,最后一个参数是我们发送数据的位数。
舵机控制板需要外接电源,舵机控制板为亚博的16路舵机控制板。
arduino 为R3版本;
jetson nano版本;
结果展示: