Skip to main content
Version: 1.0.2

IO Controller

Hardware​

The AutomatePro is equipped with comprehensive onboard current and voltage monitoring systems. This reduces the need for external sensors and enables effective downstream monitoring, facilitating early detection of potential issues. The monitored power supply diagram is shown below.

AutomatePro power supply diagram

ROS API​

Node: io_controller​

The IO controller topics and services use the default reliable QoS.

Publishers​

TopicTypeDescription
/diagnostic/io_controller_hwautomatepro_interfaces
/msg/IOControllerDiagnostic
Hardware and board diagnostics, including rail voltages and currents, power-good states, digital-drive faults, and board temperature. Published every second; the values are smoothed with an exponential moving average (factor 0.8).
/diagnostic/io_controller_fwautomatepro_interfaces
/msg/IOFirmwareDiagnostic
Firmware diagnostics, including controller uptime and fault codes.

IOControllerDiagnostic publishes these fields:

FieldTypeDescription
headerstd_msgs/HeaderMessage timestamp; the frame ID is io.
vbatt_voltage_monitorfloat32Battery voltage in V.
v12_io_smps_current_monitorfloat3212V IO SMPS current in A.
v12_io_smps_voltage_monitorfloat3212V IO SMPS voltage in V.
main_sbc_smps_current_monitorfloat32Main SBC SMPS current in A.
main_sbc_smps_voltage_monitorfloat32Main SBC SMPS voltage in V.
v5_io_smps_voltage_monitorfloat325V IO SMPS voltage in V.
v5_io_smps_current_monitorfloat325V IO SMPS current in A.
amp_total_power_monitorfloat32Main SBC power (main SBC SMPS voltage times current) in W.
v12_io_power_goodbool12V IO rail power-good state.
v5_io_power_goodbool5V IO rail power-good state.
v3_3_io_power_goodbool3.3V IO rail power-good state.
main_sbc_power_goodboolMain SBC rail power-good state.
v5_sbc_power_goodbool5V SBC rail power-good state.
v3_3_sbc_power_goodbool3.3V SBC rail power-good state.
v1_8_sbc_power_goodbool1.8V SBC rail power-good state.
digital_drive_fault_1boolDigital-drive fault 1 state.
digital_drive_fault_2boolDigital-drive fault 2 state.
digital_drive_fault_3boolDigital-drive fault 3 state.
digital_drive_fault_4boolDigital-drive fault 4 state.
board_tempint8Board temperature in degrees Celsius.

IOFirmwareDiagnostic publishes these fields:

FieldTypeDescription
headerstd_msgs/HeaderMessage timestamp; the frame ID is io.
uptimeuint32IO controller firmware uptime in seconds.
fault_codeuint8[10]Firmware fault-code array.

Parameters​

All parameters are read-only and report the hardware and firmware of the IO controller.

ParameterTypeDescription
hardware.version.majorintHardware major version.
hardware.version.minorintHardware minor version.
hardware.uuid_1 to hardware.uuid_4intHardware unique ID, in four parts.
hardware.configintHardware configuration.
firmware.version.majorintFirmware major version.
firmware.version.minorintFirmware minor version.
firmware.version.patchintFirmware patch version.
Developer Notes: IO controller CLI

The installer provides /usr/local/bin/io_controller, which controls the IO controller MCU from the compute module:

CommandAction
io_controller resetResets the IO controller MCU. automatepro-io-agent.service runs it before each start.
io_controller normal_modeSets the MCU to normal mode and resets it.
io_controller flashing_modeSets the MCU to flashing mode.
io_controller flash <path/to/hex> [options]Sets flashing mode, writes the firmware hex file over UART, and returns the MCU to normal mode.
io_controller install <path/to/tgz>Installs the Renesas flash programmer CLI from a .tgz archive into /opt/automatepro/bin.

Example​

This example prints diagnostic information about the IO controller by subscribing to the /diagnostic/io_controller_hw topic. The tutorial package is available in the AutomatePro tutorials repository, and its README explains how to build and run the examples.

Source: io_controller.py

import rclpy
from rclpy.executors import ExternalShutdownException
from rclpy.node import Node
from automatepro_interfaces.msg import IOControllerDiagnostic


class IOControllerDiagnosticSubscriber(Node):

def __init__(self):
super().__init__('io_controller_diagnostic_subscriber')
self.subscription = self.create_subscription(
IOControllerDiagnostic,
'/diagnostic/io_controller_hw',
self.listener_callback,
10)

def listener_callback(self, msg):
self.get_logger().info('Received IOControllerDiagnostic message:')
self.get_logger().info(f'Battery Voltage: {msg.vbatt_voltage_monitor:.3f} V')
self.get_logger().info(f'12V IO SMPS Current: {msg.v12_io_smps_current_monitor:.3f} A')
self.get_logger().info(f'12V IO SMPS Voltage: {msg.v12_io_smps_voltage_monitor:.3f} V')
self.get_logger().info(f'Main SBC SMPS Current: {msg.main_sbc_smps_current_monitor:.3f} A')
self.get_logger().info(f'Main SBC SMPS Voltage: {msg.main_sbc_smps_voltage_monitor:.3f} V')
self.get_logger().info(f'5V IO SMPS Voltage: {msg.v5_io_smps_voltage_monitor:.3f} V')
self.get_logger().info(f'5V IO SMPS Current: {msg.v5_io_smps_current_monitor:.3f} A')
self.get_logger().info(f'Main SBC Power: {msg.amp_total_power_monitor:.3f} W')
self.get_logger().info(f'12V IO Power Good: {msg.v12_io_power_good}')
self.get_logger().info(f'5V IO Power Good: {msg.v5_io_power_good}')
self.get_logger().info(f'3.3V IO Power Good: {msg.v3_3_io_power_good}')
self.get_logger().info(f'Main SBC Power Good: {msg.main_sbc_power_good}')
self.get_logger().info(f'5V SBC Power Good: {msg.v5_sbc_power_good}')
self.get_logger().info(f'3.3V SBC Power Good: {msg.v3_3_sbc_power_good}')
self.get_logger().info(f'1.8V SBC Power Good: {msg.v1_8_sbc_power_good}')
self.get_logger().info(f'Motor Drive Fault 1: {msg.digital_drive_fault_1}')
self.get_logger().info(f'Motor Drive Fault 2: {msg.digital_drive_fault_2}')
self.get_logger().info(f'Motor Drive Fault 3: {msg.digital_drive_fault_3}')
self.get_logger().info(f'Motor Drive Fault 4: {msg.digital_drive_fault_4}')
self.get_logger().info(f'Board Temperature: {msg.board_temp} °C')


def main(args=None):
rclpy.init(args=args)
node = IOControllerDiagnosticSubscriber()
try:
rclpy.spin(node)
except (KeyboardInterrupt, ExternalShutdownException):
pass
finally:
node.destroy_node()
rclpy.try_shutdown()


if __name__ == '__main__':
main()

Run the node using the following command:

ros2 run automatepro_python_tutorials io_controller_diagnostic_node