Using Python

Robot communication

Now let's make the two robots communicate so they can coordinate safely when entering a shared space (in our case, the ramp area).

Step 3: Physically connect the robots for communication

We will use the digital I/O ports located on the back panel of each robot.

To enable communication in both directions, connect the robots as follows:

  • DI1 of Robot A → DO1 of Robot B
  • DI1 of Robot B → DO1 of Robot A
  • GND of Robot A ↔ GND of Robot B (common ground is essential for proper signal transmission)

Step 4: Programming robot communication in Python

Now that the robots are wired, let's make them talk! The idea is simple: whenever a robot wants to access the shared zone, it sends a signal to notify the other robot, and waits until the zone is free before moving in.

Here's how it works:

  1. Before entering the shared zone, the robot sets DO1 to HIGH -> saying "I'm going in."
  2. Once finished, it sets DO1 back to LOW -> saying "The area is free now."

In Python, we use this function to control the output:

# Set the DO1 to LOW 
robot.digital_write('DO1', PinState.LOW)
# Set the DO1 to HIGH 
robot.digital_write('DO1', PinState.HIGH)

Next, we make sure the robot checks the signal from the other one before entering the shared zone:

  • If DI1 is HIGH, the other robot is using the area → wait.
  • If DI1 is LOW, the area is free → proceed.

Use this code to wait until the shared area becomes available:

while robot.digital_read('DI1') == PinState.HIGH:
        robot.wait(0.1)

Step 5: Updated programs with communication logic

Master robot program

At the start of the program, we set DO1 to LOW to indicate we are not in the shared area. Then, before entering, we wait until DI1 is LOW (area is free), send our "I’m entering" signal (DO1 HIGH), and finally perform the task.

We’ve also added the conveyor activation at the beginning of the program.

from pyniryo import *

robot_ip_address = "IP ADRESS TO CHANGE"
robot = NiryoRobot(robot_ip_address)
robot.calibrate_auto()

robot.update_tool()
robot.set_conveyor()


robot.run_conveyor(ConveyorID.ID_1, speed=100, direction=ConveyorDirection.BACKWARD)
robot.digital_write('DO1', PinState.LOW)
while True:
    # ensure tool ready to pick
    robot.release_with_tool()
    # Home position
    robot.move(JointsPosition(-0.001, 0.499, -1.251, -0.001, -0.008, -0.003))
    while robot.digital_read('DI1') == PinState.HIGH:
        robot.wait(1)
    robot.digital_write('DO1', PinState.HIGH)
    # Intermediate position
    robot.move(JointsPosition(-1.017, 0.066, -0.475, -0.146, -1.324, -0.006))
    # Approach position to the ramp
    robot.move(JointsPosition(-0.981, -0.472, -0.42, -0.463, -1.042, -0.003))
    # pick on the ramp
    robot.move(JointsPosition(-1.022, -0.507, -0.475, -0.408, -0.878, -0.003))
    robot.grasp_with_tool()
    robot.move(JointsPosition(-0.981, -0.472, -0.42, -0.463, -1.042, -0.003))
    robot.digital_write('DO1', PinState.LOW)
    # approach to the conveyor
    robot.move(JointsPosition(0.238, -0.208, -0.781, 0.06, -0.595, -0.008))
    # Place on the conveyor
    robot.move(JointsPosition(0.24, -0.332, -0.804, 0.049, -0.448, -0.009))
    robot.release_with_tool()

Slave robot program

The logic is the same on the second robot. Before entering the shared zone, the robot waits for DI1 to be LOW, then sets DO1 to HIGH, performs its action, and sets DO1 back to LOW once it’s done.

from pyniryo import *

robot_ip_address_2 = "IP ADRESS TO CHANGE" 
robot2 = NiryoRobot(robot_ip_address_2)
robot2.calibrate_auto()

robot2.update_tool()
robot2.digital_write('DO1', PinState.LOW)
while True:
    # ensure tool ready to pick
    robot2.release_with_tool()
    # Home position
    robot2.move(JointsPosition(-0.001, 0.499, -1.251, 0, -0.002, 0.002))
    # Approach conveyor
    robot2.move(JointsPosition(-0.301, -0.076, -0.808, 0.06, -0.672, 0.46))
    # pick conveyor
    robot2.move(JointsPosition(-0.288, -0.167, -0.816, 0.042, -0.629, 0.468))
    robot2.grasp_with_tool()
    robot2.move(JointsPosition(-0.301, -0.076, -0.808, 0.06, -0.672, 0.46))
    # Intermediate position
    robot2.move(JointsPosition(0.433, 0.327, -0.736, 0.18, -1.315, 0.072))
    while robot2.digital_read('DI1') == PinState.HIGH:
        robot2.wait(0.1)
    robot2.digital_write('DO1', PinState.HIGH)
    # Approach Top of the ramp
    robot2.move(JointsPosition(1.635, 0.252, -0.681, 0.482, -1.121, 1.45))
    # Place on the ramp
    robot2.move(JointsPosition(1.681, 0.189, -0.763, 0.525, -0.982, 1.353))
    robot2.release_with_tool()
    # Home position
    robot2.move(JointsPosition(-0.001, 0.499, -1.251, 0, -0.002, 0.002))
    robot2.digital_write('DO1', PinState.LOW)

That’s it! Your robots can now coordinate safely and avoid collisions in shared zones using simple digital signals.