0

Ok so I have a UDP socket setup between two computers. One computer gets coordinates from a joystick and sends them as a array over the socket. At the other end the array is received and then the value is sent to a servo. The problem is, is that this works great for about 10 seconds and then the entire connections crashes on the receiving end (in this case a RPI), and I have to restart it. If anyone could find a solution that would be swell. Code below.

import socket
import time
import pygame
try:
   import cPickle as pickle
except:
   import pickle
from pygame.locals import *
pygame.init()

#Initiate Some Variables
IP = "x.x.x.x"
Port = "5000"
crashed = False
connectionID = "123456789"
clock = pygame.time.Clock()
ready = True

#Initalize Joystick
pygame.init()
pygame.joystick.init() # main joystick device system

try:
    j = pygame.joystick.Joystick(0) # create a joystick instance
    j.init() # init instance
    print ('Enabled joystick: ' + j.get_name())
except pygame.error:
    print ('no joystick found.')

m = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:  
    if ready:
        pycontrol = pygame.event.get()

        #Get Joystick Pos
        x = j.get_axis(0)
        y = j.get_axis(1)
        s = j.get_axis(2)
        z = j.get_axis(3)

        #Set Buttons To 0
        JoyButton_0 = 0
        JoyButton_1 = 0
        JoyButton_2 = 0
        JoyButton_3 = 0
        JoyButton_4 = 0
        JoyButton_5 = 0
        JoyButton_6 = 0

        #Lets do some math
        #Create cubic graph y=x^3
        #And a linear
        cubic_x = (x**3)*100 
        cubic_y = (y**3)*100
        linear_s = ((-0.5*s+1)-0.5)*100
        linear_z = (z**3)*100
        data_x = round(cubic_x, 0)
        data_y = round(cubic_y, 0)
        data_s = round(linear_s, 0)
        data_z = round(linear_z, 0)

        #Get Joystick Key Events
        for event in pycontrol:
            if event.type == pygame.QUIT:
                crashed = True

            ############################
            if event.type == pygame.JOYBUTTONDOWN:
               if 1 == j.get_button(0):
                    JoyButton_0 = 1
               if 1 == j.get_button(1):
                    JoyButton_1 = 1
               if 1 == j.get_button(2):
                    JoyButton_2 = 1
            ######################

        #Turn into array and steralize it
        array = (data_x, data_y, data_s, data_z, JoyButton_0, JoyButton_1, JoyButton_2)
        print (array)
        #Pickle Array and set Protocol to 2 to be read by RPI
        send_array = pickle.dumps(array, protocol=2)
        m.sendto(send_array, (IP,5000))
        time.sleep(0.05)

Now that was for the sending end, here is the receiving end

#!/usr/bin/python

from Adafruit_PWM_Servo_Driver import PWM
import time

import socket
try:
   import cPickle as pickle
except:
   import pickle

# Setup Variables & Socket
IP = '192.168.0.122'
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((IP, 5000))
print ("Ready")
servoMin = 150  # Min pulse length out of 4096
servoMax = 600  # Max pulse length out of 4096

# Initialise the PWM device using the default address
pwm = PWM(0x40)
# Note if you'd like more debug output you can instead run:
#pwm = PWM(0x40, debug=True)
pwm.setPWMFreq(60) # Set the Frequency to 60hz

while True:
   raw_message,data = s.recvfrom(1024)
   (data_x, data_y, data_s, data_z, JoyButton_0, JoyButton_1, JoyButton_2) = pickle.loads(raw_message)
   if JoyButton_0 == 1:
      print("heelo")
   if JoyButton_1 == 1:
      print("Potato")
   if JoyButton_2 == 1:
      print("Dog")

   Aileron_Servo = (2.25*data_x)+375
   Elevator_Servo = (2.25*data_y)+375
   Throttle_Servo = (4.5*data_s)+150
   Rudder_Servo = (2.25*data_z)+375


   if 150 <= Aileron_Servo <= 600:
      Servo0 = Alieron_Servo
      pwm.setPWM(0, 0, Servo0)
   time.sleep(1)
ferret249
  • 53
  • 1
  • 10
  • The receiver may be getting flooded with data from the sender. Try throttling back the data you are sending or drop some packets. We need more information about the errors you are getting. System logs may be helpful. – John Hall Jul 09 '16 at 15:22
  • Ok ill see if i can grab the system logs in a minute. But the connection seems to stay open right up until I try to make the servo move, so it could potentially be the servo driver being the problem. But i dont see how that would crash the connection. And as in crashing the connection I mean that the IP address and everything is gone and wont come back until a restart. Just to clear it up. – ferret249 Jul 10 '16 at 12:18

1 Answers1

0

I see you have sleeps but they don't match. The sender is sleeping 0.05 seconds and your receiver is sleeping 1 second. This is probably creating a buffer overflow.

John Hall
  • 556
  • 1
  • 4
  • 10
  • All TCP connection got 50ms delay without any declaration(if don't use ethernet on hardware level). This is right point (overflow), he need some send-recv garbage data(used socket one way style). – dsgdfg Jul 09 '16 at 16:46
  • The connection is a UDP connection so its probably alot faster than TCP. And what does sending the garbage data do? – ferret249 Jul 10 '16 at 12:13