Project Description
1.- It will be a robotics application for pick and place then we will need take some pics to record the position and dimensions of the part with this we can calculate the center mass of this part , so when the camara detects the parts it will send a digital input to register the track position of the part then the dimensions in pixels to convert to mm in X,Y and orientation.
2.- my cam speed is max 30FPs
3.- It will be a fixed position for all the applications and needs to be calibrated on each setup, fixed position on a conveyor belt or rotary table.
the scaling factor must be calculated every time so in the script I need to know how to modify this value
It will be necessary take pics and process with Roboflow AI and get the file in forma .tflite
4 &5: It will be a Motion Controller with Codesys thru Modbus TCP node this camera has a PoE shield not setup already.
6.- The camera will be a master so I just need to receive an input when detect the part , the holding read registers for coordinate position and rotation in mm( no color in this step).
Error light and Input when it is not ready or presents an error but no details on it only an input for alarm.
7.- A trigger when detects a part xy coordinates, angle, multiple object position can be managed in my PLC with an array
8.- Camera will send the signal when it detects the part and mapping the position all the frame space according the movement to storage in the .PCS part coordinate system
9.- the Ethernet shield needs to be setup.
10.- The Camera has his own IDE to be programmed with micropython
11.- everything in OpenMV camera it has a SD card to store the pics.
12.- embedded web page for calibration tools.
13.- Industrial environment.
Here is an Idea of how the AI give the solution :
To send position and rotation data from an OpenMV N6 to a Codesys PLC via the PoE shield, you must first calculate the world coordinates in MicroPython and then transmit them using a protocol like Modbus TCP, which is natively supported by Codesys. [1, 2]
1. Coordinate & Rotation Calculation
The N6 can detect objects (blobs) and calculate their centroid \((cx, cy)\) and rotation angle. For a top-down view at a fixed height, use linear scaling to convert pixels to millimeters or centimeters. [1]
python
import sensor, image, time
# Calibration: Pixels per world unit (e.g., mm) at your specific height
P_SCALE = 0.52 # Example: 1 pixel = 0.52 mm
OFFSET_X, OFFSET_Y = 160, 120 # Origin offset (e.g., center of image)
def get_world_data(blob):
# Convert pixels to world units relative to origin
world_x = (blob.cx() - OFFSET_X) * P_SCALE
world_y = (blob.cy() - OFFSET_Y) * P_SCALE
# Blob rotation is returned in degrees (0-180 or 0-360 depending on method)
rotation = blob.rotation_deg()
return int(world_x), int(world_y), int(rotation)
Use code with caution.
2. Sending Data to Codesys (Modbus TCP)
Codesys typically acts as a Modbus TCP Server (Slave). Your OpenMV N6 will act as a Client (Master) to write the data into the PLC's holding registers. [1, 2]
You can use a library like micropython-modbus or a simple raw socket implementation to send the data.
OpenMV MicroPython Snippet:
python
import network, usocket
# 1. Initialize PoE Ethernet
lan = network.LAN()
lan.active(True)
while not lan.isconnected(): time.sleep(1)
# 2. Simple Modbus TCP "Write Multiple Registers" (Function Code 16)
# Writing X, Y, and Rotation to registers 0, 1, and 2
def send_to_plc(ip, x, y, rot):
# Modbus TCP Header + Function Code 16 payload
# This is a simplified byte-level example
header = b'\x00\x01\x00\x00\x00\x0d\x01\x10\x00\x00\x00\x03\x06'
payload = x.to_bytes(2, 'big') + y.to_bytes(2, 'big') + rot.to_bytes(2, 'big')
with usocket.socket() as s:
s.settimeout(1.0)
try:
s.connect((ip, 502))
s.send(header + payload)
except Exception as e:
print("PLC Connection Failed:", e)
Use code with caution.
3. Codesys Configuration
1. Add Device: In your project tree, right-click the Ethernet adapter and add a Modbus TCP Slave Device.
2. Mapping: In the "Modbus TCP Slave I/O Mapping" tab, map the first three holding registers (usually %IW0, %IW1, etc.) to your PLC variables (e.g., iWorldX, iWorldY, iRotation).
3. Data Format: Ensure the PLC expects 16-bit signed integers to match the int values sent from the OpenMV. [1, 2]
Performance Tip
The PoE shield supports high-speed data (90 Mb/s), but PLC cycle times are often \(>5\text{ms}\). To avoid overwhelming the PLC, use a small delay (e.g., time.sleep_ms(20)) in your OpenMV loop. [1, 2, 3]
Would you like a more detailed Modbus library implementation or a specific Codesys variable mapping example?