ich arbeite gerade an einem Projekt und benötige eure Hilfe.
Ein ESP32 liest eine Position eines Ventil's aus, diesen Wert gibt er an einen Server. Der Server speichert den Wert in eine Datenbank und errechnet ein PWM-Signal, das er an den ESP32 sendet und dieser setzt an einem Pin dieses Signal.
Die Kommunikation, vom senden bis zum erhalten des PWM-Wert's soll innerhalb einer Sekunde geschehen.
Ich habe zwei Fragen: Mir ist nichts besseres eingefallen, als das auf dem Server beide `Queue`' s auf Modulebene definiert sind und dass ich das Rechnen und Schreiben in die Datenbank in einem extra Thread mache. Habt ihr eine bessere Idee?
Dann habe ich ein komisches Verhalten, zumindest kommt es mir komisch vor. Mein Testcode sendet jede Zentel Sekunde Werte an den Server und dieser fragt aber nur jede Sekunde die Queue ab und es gehen keine Daten verloren. Ich hätte erwartet, dass da Daten verloren gehen. In die andere Richtung, sende ich jede Sekunde an meinen ESP32, dieser fragt jede Zentel-Sekunde die Daten ab und es gehen hier Daten verloren.
Ich denke, dass das eventuell mit `async` gelöst werden könnte. Zum einen würde ich dieses Verhalten gern verstehen und zum anderen würde ich gerne wissen, wie man so eine Kommunikation richtig aufbaut. Die `sleep`'s in der Schleife, haben bis jetzt noch gar nichts mit der zeitlichen Anforderung zu tun. Das kommt im nächsten Schritt. Ich will erst verstehen, wieso sich das nicht so verhält, wie ich es erwartet habe. Aktuell läuft beides lokal auf einem Rechner, weil das angenehmer ist um den Code anzupassen. Später ist der ESP32 mit Ethernet verbunden.
Server:
Code: Alles auswählen
#!.venv/bin/python
from queue import Empty, Queue
from threading import Thread
from time import sleep
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
position = Queue(maxsize=1)
pwm = Queue(maxsize=1)
class Position(BaseModel):
position: float
@app.post("/")
async def get_position(message: Position):
response = message.position
if position.full():
_ = position.get_nowait()
position.put_nowait(response)
@app.get("/get_pwm")
async def send_pwm():
if pwm.empty():
return {"pwm": 0}
return {"pwm": pwm.get_nowait()}
class PressureInjection(Thread):
def run(self):
pwm_value = 1
while True:
if pwm.full():
_ = pwm.get_nowait()
pwm.put_nowait(pwm_value)
try:
print(f"Aus der Schleife: {position.get_nowait()}")
except Empty:
print("leer")
sleep(1)
pwm_value += 1
if __name__ == "__main__":
pressure_injection = PressureInjection()
pressure_injection.daemon = True
pressure_injection.start()
uvicorn.run(app, host="0.0.0.0", port=8000)
Code: Alles auswählen
import json
from time import sleep
import requests
SERVER_IP = "localhost"
SERVER_PORT = 8000
SERVER_ADDRESS = f"http://{SERVER_IP}:{SERVER_PORT}/"
def send_to_server(address, data):
response = requests.post(address, data=data)
response.close()
def get_from_server(address, target):
return requests.get(f"{address}/{target}").json()
def main():
position = 1
while True:
send_to_server(SERVER_ADDRESS, json.dumps({"position": position}))
print(get_from_server(SERVER_ADDRESS, "/get_pwm"))
position += 0.1
sleep(0.1)
if __name__ == "__main__":
main()
Code: Alles auswählen
leer
INFO: Started server process [22084]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
leer
leer
leer
leer
INFO: 127.0.0.1:50810 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.0
leer
INFO: 127.0.0.1:50812 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
INFO: 127.0.0.1:50814 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.1
leer
INFO: 127.0.0.1:50816 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
INFO: 127.0.0.1:50818 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.2000000000000002
leer
INFO: 127.0.0.1:50821 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
INFO: 127.0.0.1:50823 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.3000000000000003
leer
INFO: 127.0.0.1:50825 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
INFO: 127.0.0.1:50827 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.4000000000000004
leer
INFO: 127.0.0.1:50829 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
INFO: 127.0.0.1:50831 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.5000000000000004
leer
INFO: 127.0.0.1:50833 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
leer
INFO: 127.0.0.1:50835 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.6000000000000005
leer
INFO: 127.0.0.1:50837 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
INFO: 127.0.0.1:50839 - "POST / HTTP/1.1" 200 OK
Aus der Schleife: 1.7000000000000006
leer
INFO: 127.0.0.1:50850 - "GET /get_pwm HTTP/1.1" 200 OK
leer
leer
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [22084]Code: Alles auswählen
{'pwm': 7}
{'pwm': 11}
{'pwm': 15}
{'pwm': 19}
{'pwm': 23}
{'pwm': 27}
{'pwm': 32}
{'pwm': 36}Vielen Dank vorab.
Grüße
Dennis
