Im trying to communicate two RPi with TCP. One RPi is server and other is client. Server part includes motor and sensor, client part includes joystick. I want to send control values from client to the server, and sensor values from server to the client. My code can do these separately, i can control BLDC from server to the client and send sensor values from client to the server. But i am trying to do these at the same time. How can i do that?
Server code:
import socket
import os
import time
os.system("sudo pigpiod")
time.sleep(1)
import pigpio
import RPi.GPIO as GPIO
pi = pigpio.pi()
ESC = 4
min_value = 1200
max_value = 2400
HOST = ''
PORT = 65458
a = 0
c = 0
def control():
data = conn.recv(1024)
stringdata = data.decode('ascii')
altan = int(stringdata)
alta = altan + 1000
print(alta)
pi.set_servo_pulsewidth(ESC, alta)
def update():
global a
global c
a = a + 5
c = c + 3
def sendsensorvalues():
b = 'd1' + str(a)
conn.send(b.encode('ascii'))
d = 'd2' + str(c)
conn.send(d.encode('ascii'))
update()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('CONNECTED BY', addr)
while True:
control()
sendsensorvalues()
Client code :
import socket
import serial
from time import sleep
HOST = '169.254.78.190'
PORT = 65458
def sendmotor():
read = ser.readline()
a = int(read)
b = str(a)
s.sendall(b.encode('ascii'))
def displayfirst():
a = strdata[2:]
print('First senso value is : ' + a)
def displaysecond():
b = strdata[2:]
print('Second sensor value is : ' + b)
def getsensorvalues():
data = s.recv(1024)
strdata = data.decode('ascii')
if strdata[1] == '1':
displayfirst()
else:
displaysecond()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
ser = serial.Serial("/dev/ttyUSB0", 57600)
ser.baudrate = 57600
while True:
sendmotor()
getsensorvalues()
When i run this codes, i get errors:
The server receives up to 1024 bytes at once with data = conn.recv(1024)
. From the screen image it is obvious that the data items sent were 516
and that two consecutive items 516516
were received at once, causing the error when interpreted as one large number. One way to fix this is to not send data of variable length, but rather of fixed length and receive only that number of bytes, e. g. with import struct
and in the client changing
b = str(a)
s.sendall(b.encode('ascii'))
to
b = struct.pack('i', a) # length 4
s.sendall(b)
as well as in the server changing
data = conn.recv(1024)
stringdata = data.decode('ascii')
altan = int(stringdata)
to
data = conn.recv(4)
altan = struct.unpack('i', data)[0]
Client part error
The shown client error is likely a consequence of strdata
being empty due to the termination of the server. Besides that, the client has the same problem as the server with potentially receiving concatenated sensor values, which you can address in a similar way, e. g. by changing
b = 'd1' + str(a)
conn.send(b.encode('ascii'))
to
conn.send(struct.pack('=2si', b'd1', a)) # length 6
…