Hi,
i have Portenta H7 and a Portenta Vision Shield (HM01B0) on it and want to use the ethernet port to communicate with a computer (Windows machine). The H7 runs latest Firmware 4.3.1. To get stated, I used the “image_transfer_jpg_as_the_remote_device_for_your_computer.py” over USB VCP with minimal changes of pixformat and framesize:
# Image Transfer - As The Remote Device
#
# This script is meant to talk to the "image_transfer_jpg_as_the_controller_device.py" on your computer.
#
# This script shows off how to transfer the frame buffer to your computer as a jpeg image.
import image, network, omv, rpc, sensor, struct
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
# Turn off the frame buffer connection to the IDE from the OpenMV Cam side.
#
# This needs to be done when manually compressing jpeg images at higher quality
# so that the OpenMV Cam does not try to stream them to the IDE using a fall back
# mechanism if the JPEG image is too large to fit in the IDE JPEG frame buffer on the OpenMV Cam.
omv.disable_fb(True)
# The RPC library above is installed on your OpenMV Cam and provides mutliple classes for
# allowing your OpenMV Cam to be controlled over USB or LAN/WLAN.
################################################################
# Choose the interface you wish to control your OpenMV Cam over.
################################################################
# Uncomment the below line to setup your OpenMV Cam for control over a USB VCP.
#
interface = rpc.rpc_usb_vcp_slave()
# Uncomment the below line to setup your OpenMV Cam for control over the lan.
#
#network_if = network.LAN()
#network_if.active(True)
#network_if.ifconfig(('192.168.1.41', '255.255.255.0', '192.168.1.1', '8.8.8.8'))
#interface = rpc.rpc_network_slave(network_if)
# Uncomment the below line to setup your OpenMV Cam for control over the wlan.
#
# network_if = network.WLAN(network.STA_IF)
# network_if.active(True)
# network_if.connect('your-ssid', 'your-password')
#
# interface = rpc.rpc_network_slave(network_if)
################################################################
# Call Backs
################################################################
# When called sets the pixformat and framesize, takes a snapshot
# and then returns the frame buffer jpg size to store the image in.
#
# data is a pixformat string and framesize string.
def jpeg_image_snapshot(data):
pixformat, framesize = bytes(data).decode().split(",")
sensor.set_pixformat(eval(pixformat))
sensor.set_framesize(eval(framesize))
img = sensor.snapshot().compress(quality=90)
return struct.pack("<I", img.size())
def jpeg_image_read_cb():
interface.put_bytes(sensor.get_fb().bytearray(), 5000) # timeout
# Read data from the frame buffer given a offset and size.
# If data is empty then a transfer is scheduled after the RPC call finishes.
#
# data is a 4 byte size and 4 byte offset.
def jpeg_image_read(data):
if not len(data):
interface.schedule_callback(jpeg_image_read_cb)
return bytes()
else:
offset, size = struct.unpack("<II", data)
return memoryview(sensor.get_fb().bytearray())[offset:offset+size]
# Register call backs.
interface.register_callback(jpeg_image_snapshot)
interface.register_callback(jpeg_image_read)
# Once all call backs have been registered we can start
# processing remote events. interface.loop() does not return.
interface.loop()
On PC side I used “rpc_image_tansfer_jpg_as_the_controller_device.py” with latest python 3.10.5 also with changed pixformat and framesize:
# Image Transfer - As The Controller Device
#
# This script is meant to talk to the "image_transfer_jpg_as_the_remote_device_for_your_computer.py" on the OpenMV Cam.
#
# This script shows off how to transfer the frame buffer to your computer as a jpeg image.
import io, pygame, rpc, serial, serial.tools.list_ports, socket, struct, sys
# Fix Python 2.x.
try: input = raw_input
except NameError: pass
# The RPC library above is installed on your OpenMV Cam and provides mutliple classes for
# allowing your OpenMV Cam to control over USB or WIFI.
##############################################################
# Choose the interface you wish to control an OpenMV Cam over.
##############################################################
# Uncomment the below lines to setup your OpenMV Cam for controlling over a USB VCP.
#
# * port - Serial Port Name.
#
print("\nAvailable Ports:\n")
for port, desc, hwid in serial.tools.list_ports.comports():
print("{} : {} [{}]".format(port, desc, hwid))
sys.stdout.write("\nPlease enter a port name: ")
sys.stdout.flush()
interface = rpc.rpc_usb_vcp_master(port=input())
print("")
sys.stdout.flush()
# Uncomment the below line to setup your OpenMV Cam for controlling over WiFi.
#
# * slave_ip - IP address to connect to.
# * my_ip - IP address to bind to ("" to bind to all interfaces...)
# * port - Port to route traffic to.
#
#interface = rpc.rpc_network_master(slave_ip="192.168.1.41", my_ip="192.168.1.100", port=0x1DBA)
##############################################################
# Call Back Handlers
##############################################################
def get_frame_buffer_call_back(pixformat_str, framesize_str, cutthrough, silent):
if not silent: print("Getting Remote Frame...")
result = interface.call("jpeg_image_snapshot", "%s,%s" % (pixformat_str, framesize_str))
if result is not None:
size = struct.unpack("<I", result)[0]
img = bytearray(size)
if cutthrough:
# Fast cutthrough data transfer with no error checking.
# Before starting the cut through data transfer we need to sync both the master and the
# slave device. On return both devices are in sync.
result = interface.call("jpeg_image_read")
if result is not None:
# GET BYTES NEEDS TO EXECUTE NEXT IMMEDIATELY WITH LITTLE DELAY NEXT.
# Read all the image data in one very large transfer.
interface.get_bytes(img, 5000) # timeout
else:
# Slower data transfer with error checking.
# Transfer 32 KB chunks.
chunk_size = (1 << 15)
if not silent: print("Reading %d bytes..." % size)
for i in range(0, size, chunk_size):
ok = False
for j in range(3): # Try up to 3 times.
result = interface.call("jpeg_image_read", struct.pack("<II", i, chunk_size))
if result is not None:
img[i:i+chunk_size] = result # Write the image data.
if not silent: print("%.2f%%" % ((i * 100) / size))
ok = True
break
if not silent: print("Retrying... %d/2" % (j + 1))
if not ok:
if not silent: print("Error!")
return None
return img
else:
if not silent: print("Failed to get Remote Frame!")
return None
pygame.init()
screen_w = 640
screen_h = 480
try:
screen = pygame.display.set_mode((screen_w, screen_h), flags=pygame.RESIZABLE)
except TypeError:
screen = pygame.display.set_mode((screen_w, screen_h))
pygame.display.set_caption("Frame Buffer")
clock = pygame.time.Clock()
while(True):
sys.stdout.flush()
# You may change the pixformat and the framesize of the image transfered from the remote device
# by modifying the below arguments.
#
# When cutthrough is False the image will be transferred through the RPC library with CRC and
# retry protection on all data moved. For faster data transfer set cutthrough to True so that
# get_bytes() and put_bytes() are called after an RPC call completes to transfer data
# more quicly from one image buffer to another. Note: This works because once an RPC call
# completes successfully both the master and slave devices are synchronized completely.
#
img = get_frame_buffer_call_back("sensor.GRAYSCALE", "sensor.QVGA", cutthrough=True, silent=True)
if img is not None:
try:
screen.blit(pygame.transform.scale(pygame.image.load(io.BytesIO(img), "jpg"), (screen_w, screen_h)), (0, 0))
pygame.display.update()
clock.tick()
except pygame.error: pass
print(clock.get_fps())
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
It worked fine. Now I want to switch to ethernet port. So I commented USB VCP stuff and uncommented network configs. But it doesn’t work. There is no image in the pygame window.
The computer ethernet adapter is set to “192.168.1.100”, “255.255.255.0”
CAM code:
# Image Transfer - As The Remote Device
#
# This script is meant to talk to the "image_transfer_jpg_as_the_controller_device.py" on your computer.
#
# This script shows off how to transfer the frame buffer to your computer as a jpeg image.
import image, network, omv, rpc, sensor, struct
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
# Turn off the frame buffer connection to the IDE from the OpenMV Cam side.
#
# This needs to be done when manually compressing jpeg images at higher quality
# so that the OpenMV Cam does not try to stream them to the IDE using a fall back
# mechanism if the JPEG image is too large to fit in the IDE JPEG frame buffer on the OpenMV Cam.
omv.disable_fb(True)
# The RPC library above is installed on your OpenMV Cam and provides mutliple classes for
# allowing your OpenMV Cam to be controlled over USB or LAN/WLAN.
################################################################
# Choose the interface you wish to control your OpenMV Cam over.
################################################################
# Uncomment the below line to setup your OpenMV Cam for control over a USB VCP.
#
#interface = rpc.rpc_usb_vcp_slave()
# Uncomment the below line to setup your OpenMV Cam for control over the lan.
#
network_if = network.LAN()
network_if.active(True)
network_if.ifconfig(('192.168.1.41', '255.255.255.0', '192.168.1.1', '8.8.8.8'))
interface = rpc.rpc_network_slave(network_if)
# Uncomment the below line to setup your OpenMV Cam for control over the wlan.
#
# network_if = network.WLAN(network.STA_IF)
# network_if.active(True)
# network_if.connect('your-ssid', 'your-password')
#
# interface = rpc.rpc_network_slave(network_if)
################################################################
# Call Backs
################################################################
# When called sets the pixformat and framesize, takes a snapshot
# and then returns the frame buffer jpg size to store the image in.
#
# data is a pixformat string and framesize string.
def jpeg_image_snapshot(data):
pixformat, framesize = bytes(data).decode().split(",")
sensor.set_pixformat(eval(pixformat))
sensor.set_framesize(eval(framesize))
img = sensor.snapshot().compress(quality=90)
return struct.pack("<I", img.size())
def jpeg_image_read_cb():
interface.put_bytes(sensor.get_fb().bytearray(), 5000) # timeout
# Read data from the frame buffer given a offset and size.
# If data is empty then a transfer is scheduled after the RPC call finishes.
#
# data is a 4 byte size and 4 byte offset.
def jpeg_image_read(data):
if not len(data):
interface.schedule_callback(jpeg_image_read_cb)
return bytes()
else:
offset, size = struct.unpack("<II", data)
return memoryview(sensor.get_fb().bytearray())[offset:offset+size]
# Register call backs.
interface.register_callback(jpeg_image_snapshot)
interface.register_callback(jpeg_image_read)
# Once all call backs have been registered we can start
# processing remote events. interface.loop() does not return.
interface.loop()
PC code:
# Image Transfer - As The Controller Device
#
# This script is meant to talk to the "image_transfer_jpg_as_the_remote_device_for_your_computer.py" on the OpenMV Cam.
#
# This script shows off how to transfer the frame buffer to your computer as a jpeg image.
import io, pygame, rpc, serial, serial.tools.list_ports, socket, struct, sys
# Fix Python 2.x.
try: input = raw_input
except NameError: pass
# The RPC library above is installed on your OpenMV Cam and provides mutliple classes for
# allowing your OpenMV Cam to control over USB or WIFI.
##############################################################
# Choose the interface you wish to control an OpenMV Cam over.
##############################################################
# Uncomment the below lines to setup your OpenMV Cam for controlling over a USB VCP.
#
# * port - Serial Port Name.
#
# print("\nAvailable Ports:\n")
# for port, desc, hwid in serial.tools.list_ports.comports():
# print("{} : {} [{}]".format(port, desc, hwid))
# sys.stdout.write("\nPlease enter a port name: ")
# sys.stdout.flush()
# interface = rpc.rpc_usb_vcp_master(port=input())
# print("")
# sys.stdout.flush()
# Uncomment the below line to setup your OpenMV Cam for controlling over WiFi.
#
# * slave_ip - IP address to connect to.
# * my_ip - IP address to bind to ("" to bind to all interfaces...)
# * port - Port to route traffic to.
#
interface = rpc.rpc_network_master(slave_ip="192.168.1.41", my_ip="192.168.1.100", port=0x1DBA)
##############################################################
# Call Back Handlers
##############################################################
def get_frame_buffer_call_back(pixformat_str, framesize_str, cutthrough, silent):
if not silent: print("Getting Remote Frame...")
result = interface.call("jpeg_image_snapshot", "%s,%s" % (pixformat_str, framesize_str))
if result is not None:
size = struct.unpack("<I", result)[0]
img = bytearray(size)
if cutthrough:
# Fast cutthrough data transfer with no error checking.
# Before starting the cut through data transfer we need to sync both the master and the
# slave device. On return both devices are in sync.
result = interface.call("jpeg_image_read")
if result is not None:
# GET BYTES NEEDS TO EXECUTE NEXT IMMEDIATELY WITH LITTLE DELAY NEXT.
# Read all the image data in one very large transfer.
interface.get_bytes(img, 5000) # timeout
else:
# Slower data transfer with error checking.
# Transfer 32 KB chunks.
chunk_size = (1 << 15)
if not silent: print("Reading %d bytes..." % size)
for i in range(0, size, chunk_size):
ok = False
for j in range(3): # Try up to 3 times.
result = interface.call("jpeg_image_read", struct.pack("<II", i, chunk_size))
if result is not None:
img[i:i+chunk_size] = result # Write the image data.
if not silent: print("%.2f%%" % ((i * 100) / size))
ok = True
break
if not silent: print("Retrying... %d/2" % (j + 1))
if not ok:
if not silent: print("Error!")
return None
return img
else:
if not silent: print("Failed to get Remote Frame!")
return None
pygame.init()
screen_w = 640
screen_h = 480
try:
screen = pygame.display.set_mode((screen_w, screen_h), flags=pygame.RESIZABLE)
except TypeError:
screen = pygame.display.set_mode((screen_w, screen_h))
pygame.display.set_caption("Frame Buffer")
clock = pygame.time.Clock()
while(True):
sys.stdout.flush()
# You may change the pixformat and the framesize of the image transfered from the remote device
# by modifying the below arguments.
#
# When cutthrough is False the image will be transferred through the RPC library with CRC and
# retry protection on all data moved. For faster data transfer set cutthrough to True so that
# get_bytes() and put_bytes() are called after an RPC call completes to transfer data
# more quicly from one image buffer to another. Note: This works because once an RPC call
# completes successfully both the master and slave devices are synchronized completely.
#
img = get_frame_buffer_call_back("sensor.GRAYSCALE", "sensor.QVGA", cutthrough=True, silent=True)
if img is not None:
try:
screen.blit(pygame.transform.scale(pygame.image.load(io.BytesIO(img), "jpg"), (screen_w, screen_h)), (0, 0))
pygame.display.update()
clock.tick()
except pygame.error: pass
print(clock.get_fps())
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
OpenMV IDE Terminal output:
IP Address:Port 192.168.1.41:7610
Running…
PyCharm Terminal output:
IP Address:Port 192.168.1.100:7610
Running…
0.0
0.0
0.0
0.0
What I already tried:
- Different Ports
- Firewall disabled
- Different Firmware version (4.3.1 Dev, 4.3.0, 4.2.3)
- Python 3.9
- Disabled Proxy settings
Could you please help me figure out, whats wrong?
Thanks