pythonraspberry-piservo

Error in Python code in controlling servo motor using Raspberry Pi 3 B+


I am currently building an automated trash bin using Raspberry Pi 3 B+ with Android application support where I would use a servo motor as an actuator for the lid and the Android application as a form of wireless remote control. Everything went on smoothly until I've encountered a problem that whenever I attempt to press a button on my Android application, the Python shell program has errors during testing. I've used a reference video (https://www.youtube.com/watch?v=t8THp3mhbdA&t=1s) and followed everything thoroughly until I've hit this roadblock.

The results to me that keeps appearing are:

Waiting for connection 
...connected from : 

Where the supposed result, according to the reference video, is:

Waiting for connection 
...connected from : ('192.168.1.70', 11937)
Increase: 2.5

As you can see, the IP address, the port, and 'Increase' text doesn't appear, meaning there is something wrong with the code.

According to some comments that was made by the people who watched the video, this code is outdated, using Python 2, and the latest version we have now is Python 3, and that we need to use a ".encode()" line in a condition. However, as someone who is still new to Python, I'm afraid that I still don't have the knowledge to apply this on the code.

Here is the code that was used in the video:

import Servomotor
from socket import *
from time import ctime
import RPi.GPIO as GPIO

Servomotor.setup()

ctrCmd = ['Up','Down']

HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)

tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

while True:
        print 'Waiting for connection'
        tcpCliSock,addr = tcpSerSock.accept()
        print '...connected from :', addr
        try:
                while True:
                        data = ''
                        data = tcpCliSock.recv(BUFSIZE)
                        if not data:
                                break
                        if data == ctrCmd[0]:
                                Servomotor.ServoUp()
                                print 'Increase: ',Servomotor.cur_X
                        if data == ctrCmd[1]:
                                Servomotor.ServoDown()
                                print 'Decrease: ',Servomotor.cur_X
        except KeyboardInterrupt:
                Servomotor.close()
                GPIO.cleanup()
tcpSerSock.close();

I have already changed the text strings that used the ' ' format into the (" ") format since it also produced some errors in the code which I corrected immediately.

Any help will be greatly appreciated and thank you in advance!


Solution

  • Here's a Python3 version, edited a tiny bit for better clarity and good practice:

    import Servomotor
    import RPi.GPIO as GPIO
    import socket
    
    # Setup the motor
    Servomotor.setup()
    
    # Declare the host address constant - this will be used to connect to Raspberry Pi
    # First values is IP - here localhost, second value is the port
    HOST_ADDRESS = ('0.0.0.0', 21567)
    
    # Declare the buffer constant to control receiving the data
    BUFFER_SIZE = 4096
    
    # Declare possible commands
    commands = 'Up', 'Down'
    
    # Create a socket (pair of IP and port) object and bind it to the Raspberry Pi address
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(HOST_ADDRESS)
    
    # Set the socket to listen to an incoming connection (1 at a time)
    server_socket.listen(1)
    
    # Never stop the server once it's running
    while True:
    
        # Inform that the server is waiting for a connection
        print("Waiting for connection to the following address: {}...".format(HOST_ADDRESS))
    
        # Perform a blocking accept operation to wait for a client connection
        client_socket, client_address = server_socket.accept()
    
        # Inform that the client is connected
        print("Client with an address {} connected".format(client_address))
    
        # Keep exchanging data
        while True:
    
            try:
    
                # Receive the data (blocking receive)
                data = client_socket.recv(BUFFER_SIZE)
    
                # If 0-byte was received, close the connection
                if not data:
                    break
    
                # Attempt to decode the data received (decode bytes into utf-8 formatted string)
                try:
                    data = data.decode("utf-8").strip()
                except UnicodeDecodeError:
                    # Ignore data that is not unicode-encoded
                    data = None
    
                # At this stage data is correctly received and formatted, so check if a command was received
                if data == commands[0]:
                    Servomotor.ServoUp()
                    print("Increase: {}".format(Servomotor.cur_X))
                elif data == commands[1]:
                    Servomotor.ServoDown()
                    print("Decrease: {}".format(Servomotor.cur_X))
                elif data:
                    print("Received invalid data: {}".format(data))
    
            # Handle possible errors
            except ConnectionResetError:
                break
            except ConnectionAbortedError:
                break
            except KeyboardInterrupt:
                break
    
        # Cleanup
        Servomotor.close()
        GPIO.cleanup()
        client_socket.close()
    
        # Inform that the connection is closed
        print("Client with an address {} disconnected.".format(client_address))
    

    To show you the code in action, I have hosted a local server on my machine and connected to it using Putty. Here are the commands I have entered:

    Putty commands

    Here is the output of the server (I have swapped the Servo-related functions to print statements):

    Waiting for connection to the following address: ('0.0.0.0', 21567)...
    Client with an address ('127.0.0.1', 61563) connected.
    Received invalid data: Hello
    Received invalid data: Let's try a command next
    Running ServoUp
    Increase: 2.5
    Running ServoDown
    Decrease: 2.5
    Received invalid data: Nice!
    Client with an address ('127.0.0.1', 61563) disconnected.
    Waiting for connection to the following address: ('0.0.0.0', 21567)...