TCI serial output works from control box's root command line but not from URCap python daemon

SETUP
I am working on a UR5e trying to send serial data out of the TCI port on the arm from a Python daemon running in a URCap. I have enabled the communication interface in Installation > General > Tool IO > Tool Analog Inputs. I am using a modified version of this URCap, which itself is just a modified version of MyDaemonSwing from the URCap SDK. The only thing I’ve changed is the python script being run as the daemon.

Below is my python daemon code

#!/usr/bin/env python

import time
import logging as Logger
import os, sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)
import serial

from SimpleXMLRPCServer import SimpleXMLRPCServer

ser = serial.Serial(
    port='/dev/ttyTool',
    baudrate=115200,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS
)

def is_serial_open():
  return ser.is_open

def reachable():
  return True

def get_time():
  return time.time()

def serial_write(data):
  try:
    ser.write(data)
    return "wrote without errors"
  except Exception as e:
    return e


server = SimpleXMLRPCServer(("", 40408), allow_none=True)
server.RequestHandlerClass.protocol_version = "HTTP/1.1"
print("Listening on port 40408...")

server.register_function(is_serial_open, "is_serial_open")
server.register_function(reachable,"reachable")
server.register_function(get_time, "get_time")
server.register_function(serial_write, "serial_write")

server.serve_forever()

and here is the client code I’m running (the xs are the actual IP in the code)

import xmlrpc.client

with xmlrpc.client.ServerProxy("http://xxx.xxx.xxx.xxx:40408/", allow_none=True) as proxy:
    print("get_time: {}".format(proxy.get_time()))
    print(str(proxy.is_serial_open()))
    e = proxy.serial_write(b'hi')
    print(e)

This produces no output on the oscilloscope. The terminal output from this script is

get_time: 1636040062.593272
True
{}

So it seems an exception in serial_write() is being caught, but it is being returned to the client as an empty dictionary… Any thoughts about how to access this exception’s information from the client script?

WHAT I’VE TRIED SO FAR
The daemon seems to be running, as it’s page in Installation > URCaps shows “My Daemon Swing runs”

I have an oscilloscope hooked up to the RS485 lines coming out of the TCI port, and I can see correct output when I ssh into the control box as root and run the following command in the terminal

echo hello > /dev/ttyTool

I also see output on the oscilloscope when I run the following Python script as root in the control box’s terminal (along with copying the python serial module folder to the same directory as the script, since it’s not included in the UR’s python installation)

import serial

ser = serial.Serial(
	port='/dev/ttyTool',
	baudrate=115200,
	parity=serial.PARITY_NONE,
	stopbits=serial.STOPBITS_ONE,
	bytesize=serial.EIGHTBITS,
	timeout=1)

ser.write(b'hi')

However, calling the daemon’s serial_write() function produces no output on the oscilloscope, as mentioned above.

I thought it could be a permissions issue, since running commands from root shell works but not from the daemon so I changed the permissions from the command line with

chmod 777 /dev/ttyTool

Still nothing on the oscilloscope from the daemon.

Per this forum post I also have the serial module folder in the same directory as the python daemon being run

I have no other URCaps running.

Any thoughts or ideas would be greatly appreciated!

1 Like

The solution turned out to be that I created the serial object ser as a global variable… the solution is found in this forum post

Creating the serial object inside of my serial_write() function and closing the port after sending data works!

1 Like