您好我无法使用有线Xbox控制器从我的PC无线控制机器人。机器人由Raspberry Pi 3和Arduino控制。 Pi使用python 2.7的套接字库通过wifi与我的PC通信,然后将数据写入Arduino上的串口以控制电机。
我的问题是尝试将数据从我的PC发送到Pi。我的PC将使用套接字库发送数据,Pi将接收它,但是当我发送大量输入时,例如Xbox控制器上的模拟棒,Pi将所有数据连接在一起。例如,当我发送255,150和10时,Pi将收到25515010,这是不正确的。此外,当发送大量数据时,Pi会因某种原因冻结并退出接收数据。
为了解决连接问题,我在延迟添加到我的代码中修复了问题,但使控制器变慢且无响应,我不想在机器人中使用。
任何和所有的帮助表示赞赏我是使用python和Raspberry Pi的新手。谢谢!
以下是我的电脑上运行的代码。
# This is the server code.
# This is where my PC takes inputs from and Xbox controller and sends them to the Pi.
from __future__ import print_function
from inputs import get_gamepad
import socket
import time
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
server_address = ('192.168.1.17', 8086)
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)
def ArduinoMap(value1, in_min, in_max, out_min, out_max):
return(value1 - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
def main():
X = str(0)
Y = str(0)
A = str(0)
B = str(0)
LX = str(0)
LY = str(0)
RX = str(0)
while True:
# Wait for a connection
connection, client_address = sock.accept()
try:
print('Connection from:', client_address)
last_inputs = '0 0 0 0'
# Receive the data in small chunks and retransmit it
while True:
events = get_gamepad()
for event in events:
## time.sleep(.005) # This is the delay that makes the robot slow and unresponsive
if event.code == "ABS_X" or event.code == "ABS_RX" or event.code == "ABS_Y" or event.code == "ABS_RY": #start of deadzone
if event.state >= -2550 and event.state <= 2550:
event.state=0
if event.code == "BTN_WEST": # button X The X,Y,A,and B button are currently not being used.
X = str(event.state)
#print(X)
elif event.code == "BTN_NORTH": # button Y
Y = str(event.state)
#print(Y)
elif event.code == "BTN_SOUTH": # button A
A = str(event.state)
#print(A)
elif event.code == "BTN_EAST": # button B
B = str(event.state)
#print(B)
elif event.code == "ABS_Y": # left stick Y
LY = ArduinoMap(event.state, -32768, 32767, 0, 255)
if LY == 127:
LY = 0
LY = str(LY)
elif event.code == "ABS_X": # left stick X
LX = ArduinoMap(event.state, -32768, 32767, 0, 255)
if LX == 127:
LX = 0
LX = str(LX)
elif event.code == "ABS_RX": # right stick turn
RX = ArduinoMap(event.state, -32768, 32767, 0, 255)
if RX == 127:
RX = 0
RX = str(RX)
inputs = LY+' '+LX+' '+RX #+' '+X+' '+Y+' '+A+' '+B
if inputs != last_inputs:
connection.send(inputs)
## time.sleep(.001) # This delay also doesn't help
print(inputs)
last_inputs = inputs
finally: # Clean up the connection
print('Keyboard Interrupt')
connection.close()
break
if __name__ == "__main__":
main()
这是Pi上运行的代码
# This is the client code
import serial
import time
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serial = serial.Serial('/dev/ttyACM0',9600, timeout = 1) # opening serial port between pi and arduino
server_address = ('192.168.1.17',8086) # computron
#server_address = ('192.168.1.128',8089) # my laptop
sock.connect(server_address)
print'Connecting to:', server_address
last_input = [0, 0, 0, 0]
inputs = 0
try:
sock.sendall('Starting Connection')
while True:
inputs = sock.recv(4096) # receive data from socket
print(inputs)
inputs = inputs
data = inputs.split()# change string into list
serial.write(str(data)) # write data to Arduino serial port
print('data', data)
last_input = inputs
status = serial.read() # read what the arduino is sending
#print(status)
sock.send(str(status))
waiting = serial.inWaiting()
if waiting > 2000:
serial.reset_input_buffer() # clean up serial buffer
finally:
print('Closing Connection')
sock.close() # clean up connection
以下是Arduino上运行的代码:
// 4/3/2018
// Motor control
#include <Wire.h>
//#include <I2CEncoder.h>
const byte numChars = 32;
char data[numChars]; // an array to store received data
char tempData[numChars]; // temoporary array for use by strtok() function
char message[numChars] = {0}; // variables to hold parsed data
int integer;
boolean newData = false;
int motor1dir1 = 8; // Motor 1
int motor1dir2 = 10;
int motor1speed = 9;
int motor2dir1 = 2; // Motor 2
int motor2dir2 = 4;
int motor2speed = 3;
int motor3dir1 = 12; // Motor 3
int motor3dir2 = 13;
int motor3speed = 11;
int motor4dir1 = 6; // Motor 4
int motor4dir2 = 7;
int motor4speed = 5;
int joy1x = A0; // Joy stick for directional movement
int joy1y = A1;
int joy1xx;
int joy1yy;
int joy2x = A2; // Joy stick for rotation
int joy2y = A3;
int joy2xx;
int joy2yy;
int motor1val;
int motor2val;
int motor3val;
int motor4val;
int NSdir;
int EWdir;
int LRdir;
//I2CEncoder Encoder1;
//I2CEncoder Encoder2;
//I2CEncoder Encoder3;
//I2CEncoder Encoder4;
void setup() {
Serial.begin(250000); // start serial comms
//Wire.begin();
//Encoder1.init((2.75 / 12)*MOTOR_393_SPEED_ROTATIONS, MOTOR_393_TIME_DELTA);
//Encoder2.init((2.75 / 12)*MOTOR_393_SPEED_ROTATIONS, MOTOR_393_TIME_DELTA);
//Encoder3.init((2.75 / 12)*MOTOR_393_SPEED_ROTATIONS, MOTOR_393_TIME_DELTA);
//Encoder4.init((2.75 / 12)*MOTOR_393_SPEED_ROTATIONS, MOTOR_393_TIME_DELTA);
pinMode(motor1dir1, OUTPUT);
pinMode(motor1dir2, OUTPUT);
pinMode(motor1speed, OUTPUT);
pinMode(motor2dir1, OUTPUT);
pinMode(motor2dir2, OUTPUT);
pinMode(motor2speed, OUTPUT);
pinMode(motor3dir1, OUTPUT);
pinMode(motor3dir2, OUTPUT);
pinMode(motor3speed, OUTPUT);
pinMode(motor4dir1, OUTPUT);
pinMode(motor4dir2, OUTPUT);
pinMode(motor4speed, OUTPUT);
pinMode(joy1x, INPUT);
pinMode(joy1y, INPUT);
pinMode(joy2x, INPUT);
pinMode(joy2y, INPUT);
// if(Serial.available() == 0) // maybe i'll add in a handshake later
// {
// Serial.write('A');
// }
}
void loop() {
// joy1xx = analogRead(joy1x);
// joy1yy = analogRead(joy1y);
//
// joy2xx = analogRead(joy2x);
// joy2yy = analogRead(joy2y);
dataReceive();
if (newData == true) {
strcpy(tempData, data);
dataParse();
assignData();
newData = false;
}
if (joy1xx == 127){
joy1xx = 0;
}
joy1xx = integer; // think of better name later
//Serial.println("here");
// joy1yy
// joy2yy
NSdir = map(joy1xx, 0, 255, -255, 255);
EWdir = map(joy1yy, 0, 255, -255, 255);
LRdir = map(joy2yy, 0, 255, -255, 255);
motor1val = NSdir + EWdir + LRdir;
motor2val = NSdir - EWdir + LRdir;
motor3val = NSdir + EWdir - LRdir;
motor4val = NSdir - EWdir - LRdir;
motor1val = constrain(motor1val, -255, 255);
motor2val = constrain(motor2val, -255, 255);
motor3val = constrain(motor3val, -255, 255);
motor4val = constrain(motor4val, -255, 255);
if (motor1val < 0)
{
motor1val = abs(motor1val);
analogWrite(motor1speed, motor1val);
digitalWrite(motor1dir1, HIGH);
digitalWrite(motor1dir2, LOW);
}
else
{
analogWrite(motor1speed, motor1val);
digitalWrite(motor1dir1, LOW);
digitalWrite(motor1dir2, HIGH);
}
if (motor2val < 0)
{
motor2val = abs(motor2val);
analogWrite(motor2speed, motor2val);
digitalWrite(motor2dir1, LOW);
digitalWrite(motor2dir2, HIGH);
}
else
{
analogWrite(motor2speed, motor2val);
digitalWrite(motor2dir1, HIGH);
digitalWrite(motor2dir2, LOW);
}
if (motor3val < 0)
{
motor3val = abs(motor3val);
analogWrite(motor3speed, motor3val);
digitalWrite(motor3dir1, HIGH);
digitalWrite(motor3dir2, LOW);
}
else
{
analogWrite(motor3speed, motor3val);
digitalWrite(motor3dir1, LOW);
digitalWrite(motor3dir2, HIGH);
}
if (motor4val < 0)
{
motor4val = abs(motor4val);
analogWrite(motor4speed, motor4val);
digitalWrite(motor4dir1, LOW);
digitalWrite(motor4dir2, HIGH);
}
else
{
analogWrite(motor4speed, motor4val);
digitalWrite(motor4dir1, HIGH);
digitalWrite(motor4dir2, LOW);
}
}
void dataReceive()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '\n';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
data[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
data[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void dataParse() {
//Serial.print(data);
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempData, ","); // get the string
strcpy(message, strtokIndx); // store in pasrsedData
strtokIndx = strtok(NULL, ","); // continue where we left off
integer = atoi(strtokIndx); // convert to an integer
}
void assignData() {
if (newData == true) {
//Serial.println(message);
// val = map(integer, 0, 255, 0, 180);
// myservo.write(val);
// Serial.println(val);
// val = data;
// myservo.write(val);
// newData = false;
}
}
最后是我的PC(左)和我的Pi(右)上运行的python shell的屏幕截图。