Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 1361

Python • Pico W + socket server + clients

$
0
0
hello everyone,
i have maid a main code on pico W which purpose is :
1. count number of click on A , B and C buttons.
2. save the number of click internally and initiate the counter from them in case of cnx problem or power problem.
3. communicate with a python server to send the number of click on demand
4. receive order from PC to reset any counter
below is the code

Code:

import networkimport socketimport timefrom time import sleepfrom machine import Pinimport threading# WiFi configurationWIFI_SSID = "TN9262"WIFI_PASSWORD = "mywifipassword"SERVER_IP = "192.168.137.2"SERVER_PORT = 5555client_socket = None# Connect to WiFidef connect_to_wifi():    wifi = network.WLAN(network.STA_IF)    wifi.active(True)    wifi.connect(WIFI_SSID, WIFI_PASSWORD)    while not wifi.isconnected():        print('Waiting for connection...')        sleep(1)    print('Connected to WiFi')    print(wifi.ifconfig())# Configure socket connectiondef connect_to_server():    global client_socket    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    try:        client_socket.connect((SERVER_IP, SERVER_PORT))        return True    except OSError as e:        print(f"Socket connection error: {e}")        return False# Initialize buttonsbutton1 = Pin(2, Pin.IN, Pin.PULL_UP)button2 = Pin(5, Pin.IN, Pin.PULL_UP)button3 = Pin(9, Pin.IN, Pin.PULL_UP)button1_state = 1button2_state = 1button3_state = 1# Folder to store text filesFOLDER = "counters"# Function to create files if they don't existdef create_files_if_not_exists():    for button in ["button1", "button2", "button3"]:        try:            with open(f"{FOLDER}/{button}.txt", "x") as f:                f.write("0")        except OSError as e:            if e.args[0] != 17:  # File already exists                print(f"Error creating {button}.txt: {e}")# Create the files if they don't existcreate_files_if_not_exists()# Function to read counter value from a text filedef read_counter_from_txt(button):    try:        with open(f"{FOLDER}/{button}.txt", "r") as file:            return int(file.readline().strip())  # Read the first value in the text file    except (OSError, ValueError) as e:        print(f"Error reading {button}.txt: {e}")        return 0  # Return 0 on error# Initialize counters with values read from text filescounters = {    "button1": read_counter_from_txt("button1"),    "button2": read_counter_from_txt("button2"),    "button3": read_counter_from_txt("button3")}# Function to write counter value to a text filedef write_counter_to_txt(button, value):    try:        with open(f"{FOLDER}/{button}.txt", "w") as file:            file.write(str(value))  # Write the number of clicks to the text file    except OSError as e:        print(f"Error writing to {button}.txt: {e}")def send_click_counts():    global client_socket    dataS = f"A{counters['button1']:05d} B{counters['button2']:05d} C{counters['button3']:05d}"    client_socket.send(dataS.encode('utf-8'))    time.sleep(0.5)def reconnect_to_server():    global client_socket    while True:        print("Attempting to reconnect...")        if connect_to_server():            print("Reconnected to server.")            break        time.sleep(5)def handle_buttons():    global button1_state, button2_state, button3_state    while True:        if button1.value() == 1 and button1_state == 0:            counters["button1"] += 1            write_counter_to_txt("button1", counters["button1"])            time.sleep(0.2)        button1_state = button1.value()        if button2.value() == 1 and button2_state == 0:            counters["button2"] += 1            write_counter_to_txt("button2", counters["button2"])            time.sleep(0.2)        button2_state = button2.value()        if button3.value() == 1 and button3_state == 0:            counters["button3"] += 1            write_counter_to_txt("button3", counters["button3"])            time.sleep(0.2)        button3_state = button3.value()                time.sleep(0.1)# Main looptry:    connect_to_wifi()    if connect_to_server():        print("Socket connection initialized.")except (OSError, ValueError) as e:    print(f"Connection error: {e}")# Start button handling threadbutton_thread = threading.Thread(target=handle_buttons)button_thread.daemon = Truebutton_thread.start()while True:    try:        if client_socket:            data = client_socket.recv(1024).decode('utf-8').strip()            if data == 'SEND_DATA':                send_click_counts()            elif data == 'A':                counters["button1"] = 0                write_counter_to_txt("button1", counters["button1"])                time.sleep(0.5)            elif data == 'B':                counters["button2"] = 0                write_counter_to_txt("button2", counters["button2"])                time.sleep(0.5)            elif data == 'C':                counters["button3"] = 0                write_counter_to_txt("button3", counters["button3"])                time.sleep(0.5)    except (OSError, ValueError) as e:        print(f"Data reception error: {e}")        reconnect_to_server()    time.sleep(0.1)
below is the server code:

Code:

import socketimport threading# Server configurationSERVER_IP = '0.0.0.0'SERVER_PORT = 5555# Shared resourcesclients = []lock = threading.Lock()def handle_client(client_socket, addr):    global clients    print(f"[INFO] New connection from {addr}")    while True:        try:            request = client_socket.recv(1024).decode('utf-8')            if not request:                break            print(f"[INFO] Received {request} from {addr}")            if request == "A":                with lock:                    for c in clients:                        if c != client_socket:                            c.send("A".encode('utf-8'))                client_socket.send("RESET".encode('utf-8'))            elif request == "data":                                pico_data = None                with lock:                    for c in clients:                        if c != client_socket:                            try:                                c.send("SEND_DATA".encode('utf-8'))                                pico_data = c.recv(1024).decode('utf-8')                                print(f"[INFO] Received {pico_data} from {c.getpeername()}")                                pico_data = None                                break                            except Exception as e:                                print(f"[ERROR] Error receiving data from Pico W: {e}")#                            finally:#                                c.settimeout(None)  # Reset the timeout to None#                if pico_data:#                    xa = pico_data[1:6].strip()#                    xb = pico_data[8:13].strip()#                    xc = pico_data[15:20].strip()#                    with open("/home/tunita/Desktop/counters/A.csv", "w") as destination_file:#                        destination_file.write(xa)#                    with open("/home/tunita/Desktop/counters/B.csv", "w") as destination_file:#                        destination_file.write(xb)#                    with open("/home/tunita/Desktop/counters/C.csv", "w") as destination_file:#                        destination_file.write(xc)#                else:#                    print("[ERROR] No data received from Pico W")#                    client_socket.send("ERROR: No data received from Pico W".encode('utf-8'))#            else:#                client_socket.send(request.encode('utf-8'))        except Exception as e:            print(f"[ERROR] {e}")            break    client_socket.close()    with lock:        clients.remove(client_socket)    print(f"[INFO] Connection closed from {addr}")def start_server():    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    server.bind((SERVER_IP, SERVER_PORT))    server.listen(5)    print(f"[INFO] Server listening on {SERVER_IP}:{SERVER_PORT}")    while True:        client_socket, addr = server.accept()        with lock:            clients.append(client_socket)        client_handler = threading.Thread(target=handle_client, args=(client_socket, addr), daemon=True)        client_handler.start()if __name__ == "__main__":    start_server()
and here is 1 client code who will ask every 3 sec the data from the pico W:

Code:

import socketimport time# Client configurationSERVER_IP = '192.168.137.2'SERVER_PORT = 5555def client1():    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    client.connect((SERVER_IP, SERVER_PORT))    while True:        try:            time.sleep(3)            client.send("data".encode('utf-8'))                  except Exception as e:            print(f"[ERROR] {e}")            break    client.close()if __name__ == "__main__":    client1()


the problem is that my server work arbitrary , it can work for 1 sec then freeze, or work for minutes then freeze!
no error msg, no stopping , it just freeze and in the mean time the picoW as a counter continue to work perfectly.
any one can please have a look and help with that ?
sorry for my bad english in advance

exemple of return when freezed from first try :

Code:

[INFO] Server listening on 0.0.0.0:5555[INFO] New connection from ('192.168.137.169', 58308)[INFO] New connection from ('192.168.137.2', 54596)[INFO] Received data from ('192.168.137.2', 54596)[INFO] Received A00191 B00083 C00000 from ('192.168.137.169', 58308)

Statistics: Posted by oussmess — Wed Jun 19, 2024 3:04 pm



Viewing all articles
Browse latest Browse all 1361

Latest Images

Trending Articles



Latest Images