大家好,互联网上的人们,我的团队和我遇到了一个问题,python代码将37个字符的字节数组发送到arduino。arduino控制4个直流电机和4个180度伺服系统,因此我们通过pyserial向其发送控制数据。我们正在使用两个通过usb连接到计算机的logitech extreme 3d pro操纵杆(下面的参考链接)。使用pygame,将输入转换为PWM数据,然后发送到arduino(几句之前已经解释了如何完成)。我们的问题是,该代码在MacOS机器上运行得很好,当我们试图在windows或linux机器上运行它时(我们将使用的笔记本电脑将安装linux,我们只是测试了windows,看看它是否能工作),它会工作几秒钟,然后冻结。当我在没有4个直流电机和4个伺服装置的情况下测试这段代码时(我无法将它们带回家),它在所有操作系统上都能完美工作,我的同事一直告诉我这是一个编程问题,但我似乎找不到它。我已经附上了下面所有的代码,如果你有任何问题,请让我知道
Python代码
import pygame
import numpy as np
import serial
# function to map servo/motor data dependent on joystick input
def map(joy, min, max, omin, omax):
return float((((joy - min) * (omax - omin)) / (max - min)) + omin)
# same as above but used for the corner values of the joystick
def mapc(joy1, joy2, min1, max1, min2, max2, omin, omax):
return float((((((joy1 - min1) * (omax - omin)) / (max1 - min1)) + omin) + ((((joy2 - min2) * (omax - omin)) / (max2 - min2)) + omin)) / 2)
# dum1 = input("1: ")
class JoyStickClass:
# set up the joysticks and arduino
def __init__(self):
pygame.init()
pygame.joystick.init()
self.Joy1 = pygame.joystick.Joystick(0)
self.Joy2 = pygame.joystick.Joystick(1)
self.Joy1.init()
self.Joy2.init()
self.M1_Data = 1500
self.M2_Data = 1500
self.M3_Data = 1500
self.S1_Data = 1500
self.S2_Data = 1500
self.S3_Data = 1500
self.S4_Data = 1500
self.lights = 0
# port = str(input("Enter com port (Windows: COM, MacOS: usual crap:) : "))
self.ard1 = serial.Serial('/dev/cu.usbmodem1434201', 115200, timeout = 0.01)
self.startMarker = '<'
self.endMarker = '\n'
self.dividingmarker = ','
self.Timer = 0
# read the data from the joysticks and store them in their variables
def JoyRead(self):
for event in pygame.event.get():
self.Joy1X = self.Joy1.get_axis(0)
self.Joy1Y = self.Joy1.get_axis(1)
self.Joy1B1 = self.Joy1.get_button(0)
self.Joy1B6 = self.Joy1.get_button(5)
self.Joy1B7 = self.Joy1.get_button(6)
self.Joy1B8 = self.Joy1.get_button(7)
self.Joy1B3 = self.Joy1.get_button(2)
self.Joy2X = self.Joy2.get_axis(0)
self.Joy2Y = self.Joy2.get_axis(1)
self.Joy2B1 = self.Joy2.get_button(0)
self.Joy2B3 = self.Joy2.get_button(2)
self.Joy2B5 = self.Joy2.get_button(4)
self.Joy1H = self.Joy1.get_hat(0)
garbo = 1500
# Convert the data read from the joysticks to useful motor and servo data
def JoyConv(self):
self.Timer = self.Timer + 1
# Motor crap
x= self.Joy1X * 1
y=self.Joy1Y * 1
# Deadzones
if x > -.1 and x < .1:
x = 0
if y > -.1 and y < .1:
y = 0
tamp = map(abs(y),0,1,500,0)
# //preturn
pT = map(x,-1,1,-tamp,tamp)
lM = map(y, -1, 1, 1000, 2000)
rM = map(y, -1, 1, 1000, 2000)
# //Take the amplitude of the motors
lMAmp = round(1500-lM)
lMAmp -= pT
lM = 1500 - lMAmp
rMAmp = round(1500-rM)
rMAmp += pT
rM = 1500 - rMAmp
self.M1_Data = round(lM)
self.M2_Data = round(rM)
#Up Down
if self.Joy1B7 == 1 and self.Joy1B8 == 0:
self.M3_Data = 1000
elif self.Joy1B8 == 1 and self.Joy1B7 == 0:
self.M3_Data = 2000
else:
self.M3_Data = 1500
self.S2_Data = round(map(self.Joy2X, 1, -1, 800, 2200))
# ArmTIlt
if round(map(self.Joy2Y, -1, 1, 1000, 2000)) > 1600 and self.S1_Data < 2200 and self.Timer % 50 == 0:
self.S1_Data = self.S1_Data + 7
elif round(map(self.Joy2Y, -1, 1, 1000, 2000)) < 1400 and self.S1_Data > 1000 and self.Timer % 50 == 0:
self.S1_Data = self.S1_Data - 7
else:
self.S1_Data = self.S1_Data
if self.Joy2B1 == 1:
self.S3_Data = 2000
else:
self.S3_Data = 1000
# Camera
if self.Joy1H == (0, -1) and self.S4_Data <= 2200 and self.Timer % 100 == 0:
self.S4_Data = self.S4_Data + 15
elif self.Joy1H == (0, 1) and self.S4_Data >= 1000 and self.Timer % 100 == 0:
self.S4_Data = self.S4_Data - 15
else:
self.S4_Data = self.S4_Data
# lights
if self.Joy1H == (1, 0):
self.lights = 1
elif self.Joy1H == (-1, 0):
self.lights = 0
else:
self.lights = self.lights
# Send the data to the arduino
def send_to_arduino(self):
Sending_Data1 = str(self.M1_Data)
Sending_Data1 += self.dividingmarker
Sending_Data1 += str(self.M2_Data)
Sending_Data1 += self.dividingmarker
Sending_Data1 += str(self.M3_Data)
Sending_Data1 += self.dividingmarker
Sending_Data1 += str(self.S1_Data)
Sending_Data1 += self.dividingmarker
Sending_Data1 += str(self.S2_Data)
Sending_Data1 += self.dividingmarker
Sending_Data1 += str(self.S3_Data)
Sending_Data1 += self.dividingmarker
Sending_Data1 += str(self.S4_Data)
Sending_Data1 += self.dividingmarker
Sending_Data1 += str(self.lights)
Sending_Data1 += self.endMarker
Sending_Data_ByteArray1 = bytearray(Sending_Data1, 'ascii')
# print()
if self.ard1.inWaiting():
self.ard1.flush()
self.ard1.write(Sending_Data_ByteArray1)
data = self.ard1.readline()
print(data, len(Sending_Data_ByteArray1))
# self.ard1.flush()
class MainClass:
def __init__(self):
self.joy = JoyStickClass()
def run(self):
self.joy.JoyRead()
self.joy.JoyConv()
self.joy.send_to_arduino()
main = MainClass()
while 1==1:
main.run()
Arduino代码:
#include <Servo.h>
Servo M1;
Servo M2;
Servo M3;
Servo M4;
Servo S1;
Servo S2;
Servo S3;
Servo S4;
int VA = 0; //1000-2000
int VB = 0; //1000-2000
int VC = 0; //1000-2000
int VD = 0; //1000-2000
int VE = 0; //1000-2000
int VF = 0; //1000-2000
int VG = 0; //1000-2000
int VH = 0; //1000-2000
int VI = 0; //1 or 0
int Lights = 13;
void setup()
{
Serial.begin(115200);
Serial.println();
pinMode(Lights, OUTPUT);
M1.attach(22);
M2.attach(23);
M3.attach(24);
M4.attach(25);
S1.attach(30);
S2.attach(34);
S3.attach(38);
S4.attach(42);
}
void SerialEvent()
{
char characterBuf[39]; //stores incoming
int incomingLength = 0; //stores incoming length
char *token; //token for converting byte array to string array
int counterNum = 1;
//1503,1503,1500,1503,1523,1000,1500,0
if (Serial.available()) {
// Serial.println("1");
incomingLength = Serial.readBytesUntil('\n', characterBuf, 50); //calculate length of byte array
token = strtok(characterBuf, ","); //convert to string
VA = atoi(token);
// Serial.println(token);
while (token != NULL) { //if token doesnt find another comma it goes back to beginning
token = strtok(NULL, ","); //changes token to a string def of NULL
// Serial.println(token);
switch (counterNum) {
case 1:
VB = atoi(token);
break;
case 2:
VC = atoi(token);
break;
case 3:
VD = atoi(token);
break;
case 4:
VE = atoi(token);
break;
case 5:
VF = atoi(token);
break;
case 6:
VG = atoi(token);
break;
case 7:
VH = atoi(token);
break;
case 8:
VI = atoi(token);
break;
}
counterNum++;
}
}
}
void loop()
{
if (Serial.available()) {
SerialEvent();
M1.writeMicroseconds(VA);
M2.writeMicroseconds(VB);
M3.writeMicroseconds(VC);
M4.writeMicroseconds(VD);
S1.writeMicroseconds(VE);
S2.writeMicroseconds(VF);
S3.writeMicroseconds(VG);
S4.writeMicroseconds(VH);
if (VI == 1) {
digitalWrite(Lights, HIGH);
}
else {
digitalWrite(Lights, LOW);
}
}
Serial.print("M1: ");
Serial.print(VA);
Serial.print(" ");
Serial.print("M2: ");
Serial.print(VB);
Serial.print(" ");
Serial.print("M3: ");
Serial.print(VC);
Serial.print(" ");
Serial.print("M4: ");
Serial.print(VC);
Serial.print(" ");
Serial.print("S1: ");
Serial.print(VD);
Serial.print(" ");
Serial.print("S2: ");
Serial.print(VE);
Serial.print(" ");
Serial.print("S3: ");
Serial.print(VF);
Serial.print(" ");
Serial.print("S4: ");
Serial.print(VG);
Serial.print(" ");
Serial.print("Lights: ");
Serial.print(VH);
Serial.println();
}
请原谅任何格式错误,在过去的48小时里我一直在处理这个问题,我没有时间检查这些问题
另请参考操纵手柄的链接:
https://www.amazon.com/Extreme-3D-Pro-Joystick-Windows/dp/B00009OY9U/ref=sr_1_1?crid=1MQ474EU5M3KK&dchild=1&keywords=logitech+extreme+3d+pro+joystick&qid=1615092807&sprefix=logitech+extreme+%2Caps%2C164&sr=8-1
伺服和电机的参考链接:
伺服系统:
https://www.savoxusa.com/products/savsw1210sg-waterproof-coreless-digital
电机:
http://aquaphoton.net/aquaphoton/?product=seabotix-thruster-btd150
还有其他问题请告诉我
通过将serial.flush切换到arduino端,解决了问题
相关问题 更多 >
编程相关推荐