Hi,
I would like to establish communication via the Websocket between the Sunfounder Zeus and a
python script, such that the python script sends commands to the Zeus like “forward”. How would I need to change the Code of the Sunfounder to do that?
Zeus Car’s ESP32 CAM opens a websocket service upon startup, you can use a python script to set up a client to communicate with it, the commands to control the movement of the car consist of text in json format, for example:
{“Q”:[0,0], “K”:[0,0], “N”:true, “O”:true, “P”:true, “M”:true, “J”:true, “E”:false, “F”:false, “G”:false, “I”: “forward”}
where the key corresponds to the control on the sunfounder controller APP Controlled by APP — SunFounder Zeus Robot Car Kit for Arduino 1.0 documentation
Dear Moderator, I have a similar request to GreyPanda (would like to command the car via my laptop keyboard instead of the app) and I try the following code on python IDE Thonny after reading your answer. My wifi board indicates I’m connected to Zeus_car but I have the following message “ Remote system refused network connection”. Any advice on how to change the code to make it work? Thanks!
The code used on python:
import asyncio
import websockets
import json
import keyboard
async def control_zeus_car(uri, command):
async with websockets.connect(uri) as websocket:
await websocket.send(json.dumps(command))
response = await websocket.recv()
print(f"Received response: {response}")
def get_movement_command():
# Check for key presses and return the corresponding movement command
if keyboard.is_pressed(‘2’):
return {“I”: “backward”}
elif keyboard.is_pressed(‘4’):
return {“I”: “left”}
elif keyboard.is_pressed(‘6’):
return {“I”: “right”}
elif keyboard.is_pressed(‘8’):
return {“I”: “forward”}
else:
return {}
if name == “main”:
# Set the URI of the WebSocket server on the Zeus car
zeus_car_uri = “ws://Zeus_Car:8765”
while True:
movement_command = get_movement_command()
if movement_command:
control_command = {
"Q": [0, 0],
"K": [0, 0],
"N": False,
"O": False,
"P": False,
"M": False,
"J": False,
"E": False,
"F": False,
"G": False,
**movement_command # Merge movement command into the main command
}
asyncio.get_event_loop().run_until_complete(control_zeus_car(zeus_car_uri, control_command))
Zeus car can’t be controlled by computer keyboard, you can only use APP, arduino programming, remote control to control it.
We suggest you use APP or remote control to control Zeus car.
Upload zeus-car-main\Zeus_Car\Zeus_Car.ino to arduino, then you can use APP or remote control to control it.
After successfully uploading the program, every time you start Zeus car, you can control it by APP or remote control.
Hi, can we revive this topic please.
I have the same requirement to read the Zeus car camera from a Python App so I can apply some machine learning algorithms myself.
It has been explained that the Camera opens a websocket on port 8765 but it is not clear how the image can be read from here. Obviously it can (since the android app is able to get the images over the WiFi) but my Python code is obviously missing something. From the debug we can also see that the camera is streaming a live feed on port 9000/mjpg but is very slow if you open a web browser onto it…
import asyncio
import websockets
import cv2
import numpy as np
WebSocket URL of the Zeus car’s camera server
WEBSOCKET_URL = "ws://192.168.4.1:8765"
async def receive_camera_feed():
async with websockets.connect(WEBSOCKET_URL) as websocket:
print("Connected to the camera feed.")
while True:
try:
# Receive binary data (JPEG or PNG image) from the WebSocket
image_data = await websocket.recv()
print(image_data)
# Convert binary data to a NumPy array
np_data = np.frombuffer(image_data, dtype=np.uint8)
# Decode the image from the NumPy array
frame = cv2.imdecode(np_data, cv2.IMREAD_COLOR)
# Check if frame is valid
if frame is not None:
# Display the frame
cv2.imshow("Zeus Car Camera Feed", frame)
# Break the loop if 'q' is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
print("Failed to decode image.")
except websockets.ConnectionClosed:
print("WebSocket connection closed.")
break
except Exception as e:
print(f"Error: {e}")
#break
# Release resources when done
cv2.destroyAllWindows()
Main event loop to run the async function
async def main():
await receive_camera_feed()
Run the main function
asyncio.run(main())
Sorry about the messy code.
When this runs we get:
Connected to the camera feed
Pong 143430
Error: a byte-likeobject is required, not str # This is obviously because we are trying to convert the string “Pong 143430” to an image.
So how do we get the image?
Please note that you can access the image stream at the following address: http://ip:9000/mjpg. The stream uses the HTTP protocol.
However, please be aware that it supports only one client at a time, meaning multiple clients cannot access the stream simultaneously. If you experience slowness, it may be due to network issues.