Raspberry Pi和Arduino Robot的问题

时间:2018-04-08 20:00:13

标签: python arduino raspberry-pi

您好我无法使用有线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的屏幕截图。

The Python shell running on my PC is on the left and the Python shell running on my Pi is on the right.

0 个答案:

没有答案