0

I am working with raspberryPi 3 and I have a python script on it to receive connection requests as a tcp server..I need it to keep listening to the pins in case I receive any signal from them..I have done the code but it did not work as I want..maybe you can help me with an idea..here is my code

import socket
import time
from time import sleep
import RPi.GPIO as GPIO

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_address = ('10.1.39.117', 5040)
print('starting up on %s port %s' % server_address)
sock.bind(server_address)

Msg = "IamHere"
d = ""

sock.listen(1)

GPIO.setmode(GPIO.BOARD)
GatePin       = 11 #pin11 to open gate
closeGatePin  = 23 #pin23 to close gate
LoopsensorPin = 16 #pin16 for loop sensor
TngPin        = 22 #pin22 for tng signal
RFIDPin       = 32 #pin32 for RFID signal
Count         = 1

Status = "closed"

GPIO.setwarnings(False)

def OpenGate():
    print ("Opening Gate.. led on....")
    GPIO.output(GatePin, GPIO.HIGH)  # led on
    time.sleep(0.5)


def CloseGate():
    print ("Closing Gate..led off...")
    GPIO.output(GatePin, GPIO.LOW)  # led off
    time.sleep(0.5)

def setup():
    GPIO.setup(GatePin, GPIO.OUT)  # Set GatePin's mode is output
    GPIO.output(GatePin, GPIO.LOW)  # Set GatePin high to off led
    GPIO.setup(closeGatePin, GPIO.OUT)
    GPIO.output(closeGatePin, GPIO.LOW)

GPIO.setup(LoopsensorPin,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(TngPin,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(RFIDPin,GPIO.IN,pull_up_down=GPIO.PUD_UP)


setup()

print("Start..")

while(True):

    if GPIO.input(LoopsensorPin)==0:
        print("Signal received from main loop sensor ")
        CloseGate()
        Count = 0
        Status = "closed"
        print("Gate status is: "+Status)


    #Listen for incoming connections

    #Wait for a connection
    print('waiting for a connection')
    connection, client_address = sock.accept()

    try:
        print('connection from', client_address)

        #while True:
        data = connection.recv(16)
        d = data.decode('utf-8')
        print('received from agent: %s' % d)
        if d == 'Open':
            print('sending response back to the agent')
            #connection.sendall(data)
            connection.send(str(Msg).encode())
            #open gate
            OpenGate()
            Status = "opened"
            print("Gate status is: "+Status)
            print("Waiting for loop sensor signal..")
            GPIO.input(LoopsensorPin)
            while(1):
                if GPIO.input(LoopsensorPin)==0:
                    print("Signal received from loop sensor..")
                    print("loop sensor pressed")
                    sleep(.5)
                    CloseGate()
                    break

    finally:
        # Clean up the connection
        connection.close()


GPIO.cleanup()

I think I need to change something in the While loop to make it work but I am not sure how..

After I put all the tcp code in a thread, here is my new While loop:

print("Application Start..")

if __name__ == "__main__":    
    myTCPThread = TCPThread(shared_variable)
    myTCPThread.start()

while(True):

    if GPIO.input(LoopsensorPin)==0:
        print("Signal received from main loop sensor ")
        CloseGate()
        Count = 0
        Status = "closed"
        print("Gate status is: "+Status)


    if shared_variable == 'Open':
        print('sending response back to the agent')
        connection.send(str(Msg).encode())
        #open gate
        OpenGate()
        Status = "opened"
        print("Gate status is: "+Status)
        print("Waiting for loop sensor signal..")
        GPIO.input(LoopsensorPin)
        while(1):
            if GPIO.input(LoopsensorPin)==0:
                print("Signal received from loop sensor..")
                print("loop sensor pressed")
                sleep(.5)
                CloseGate()
                break           

myTCPThread.close()
myTCPThread.join()      
GPIO.cleanup()  
Osama Shaki
  • 139
  • 15
  • may you describe the logic that you want in detail? In addition, which part of the logic failed? It helps us to help you better. Cheers! – hyloop Aug 07 '18 at 02:30
  • ok sure..I have a c# application which is sending a tcp request connection to the Pi if for example x =1 then I open a boom gate..the pi is receiving and responding as desired when it is a tcp listner..at the same time while the pi is waiting for a tcp connection from the c# application I want it to be able to receive signal from (loop sensor gpio pin16) so I can close the boom gate in any time I receive a signal from this pin. I hope it is clear now. Thanks – Osama Shaki Aug 07 '18 at 02:40

1 Answers1

1

May not work as I cannot test it. But the problem is socket.accept() is a blocking call and thus blocks your while loop. Solution is to put all TCP code in a separate thread like this

from threading import Thread


class TCPThread(Thread):
    def __init__(self, shared_variable):  # run TCP code in a seperate thread
        super().__init__()
        self.shared_variable = shared_variable  # share a variable from main thread to this thread

        server_address = ('10.1.39.117', 5040)  # from your code
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # ...
        self.sock.bind(server_address)  # ...
        sock.listen(1)  # ...

    def run(self):
        while True:  # this loop constantly updates the shared_variable, your while loop (commented below) can just check if it is "Open" or not
            connection, client_address = self.sock.accept()
            data = connection.recv(16)
            self.shared_variable[0] = data.decode('utf-8') 

shared_variable = [None]

if __name__ == "__main__":    
    myTCPThread = TCPThread(shared_variable)
    myTCPThread.start()

    # your while loop
    # ...
    # if shared_variable[0] == "Open":
    # ...
hyloop
  • 349
  • 1
  • 5
  • I modify the while loop as you suggested.. Am I correct? thanks – Osama Shaki Aug 07 '18 at 04:09
  • @osamashaki looks good to me. But move this line "connection.send(str(Msg).encode())" into the run method of the TCPThread like this "self.connection.send(...)". Also, indent all the code so that they are in the "if" statement. Test your code if it works for you since I can't do that. – hyloop Aug 07 '18 at 04:20
  • thanks I modified my code but still have an error here.. myTCPThread.start() the error is Runtime error thread.__init__() not called.. and can I know please what is this if condition for? if __name__ == "__main__" – Osama Shaki Aug 07 '18 at 04:45
  • I put this line: Thread.__init__(self) in __init__ method and the error is gone..but the shared_variable value is always None :( – Osama Shaki Aug 07 '18 at 05:18
  • @osamashaki ops, I made a mistake. For the shared variable, currently it is a string. It needs to be a list with a string inside. I will edit my code for clarify. As for '''if __name__ == "__main__":''', please refer to this question here: [What does if __name__ == “__main__”: do?](https://stackoverflow.com/questions/419163/what-does-if-name-main-do). – hyloop Aug 07 '18 at 05:23
  • @osamashaki Changes are at line 17, 19, 27. – hyloop Aug 07 '18 at 05:31
  • Thank you for your help it is working now :) ..I have a question about myTCPThread.close() I am getting an error saying TCPThread object has no attribute 'close' can I know why please? thanks – Osama Shaki Aug 07 '18 at 06:52
  • @osamashaki my bad, delete the __last two lines__ as you cannot and do not need to close a thread. When the main thread ends (because you break out of your while loop), the thread that you created will be closed automatically. Consider reading this tutorial Python - Multithreaded Programming. If you need multithreading in any future problem, they have a lot of good examples to get you started. – hyloop Aug 07 '18 at 07:23
  • Thank you for your help, every thing is working ok now – Osama Shaki Aug 07 '18 at 09:58