Python ProXR ncd-io / Industrial-Relay-Control Help

I am using a ProXR 2007 (ADR4ProXR Rev. A) and controlling with a PC via the serial cable. I am using python to control the device. I downloaded (GitHub - ncd-io/Industrial-Relay-Control). I have newer ProXRs (2014 and 2021) and I am able to use the library from Github to control those without any errors. However, when I try to control a relay on the 2007 board, the relay turns on or off, but then I get the following error. I adjusted the wait time to 2 seconds, but the error still occurred. I’m guessing the older board isn’t returning the values that are expected by the newer ncd library. Please note the baud rate is 38400, the board would not run with the faster 115200 baud rate. Any help is appreciated!!

import serial
import socket
import ncd_industrial_relay as ncd
serial_port = serial.Serial(“COM1”, 38400, timeout = 1)
board1 = ncd.Relay_Controller(serial_port)

File “C:\Experiments\Psychopy\Python and Psychopy - For testing\Psychopy Relay V3 Infrared_lastrun.py”, line 896, in
run(
File “C:\Experiments\Psychopy\Python and Psychopy - For testing\Psychopy Relay V3 Infrared_lastrun.py”, line 538, in run
board1.turn_off_relay_by_index(1)
File “C:\Experiments\Psychopy\Python and Psychopy - For testing\ncd_industrial_relay.py”, line 31, in turn_off_relay_by_index
return self.process_control_command_return(self.send_command(command, 4))
File “C:\Experiments\Psychopy\Python and Psychopy - For testing\ncd_industrial_relay.py”, line 160, in process_control_command_return
bytes_back = self.check_bytes_back(data)
File “C:\Experiments\Psychopy\Python and Psychopy - For testing\ncd_industrial_relay.py”, line 187, in check_bytes_back
return ord(data[1:2]) == (len(data)-3)
TypeError: ord() expected a character, but string of length 0 found
################# Experiment ended with exit code 1

Hi,

These older models don’t support the turn_on_relay_by_index command. I would recommend the turn_on_relay_by_bank command instead.

The Python library wasn’t designed with these older models in mind. These older models don’t support the API wrapper so you would want to rewrite sections of the library in order to not wrap the command with the api.

i.e.

def turn_on_relay_by_bank(self, relay, bank = 1):
	command = self.wrap_in_api([254, 107+relay, bank])
	return self.process_control_command_return(self.send_command(command, 4))

would be:

def turn_on_relay_by_bank(self, relay, bank = 1):
	command = [254, 107+relay, bank]
	return self.process_control_command_return_no_api(self.send_command(command, 1))

You would also need to add a new function to handle the response without an API like this:

def process_control_command_return_no_api(self, data):
	return [True, self.hex_to_decimal(data)]

Hi Jacob,
Thank you for your very helpful and quick reply. Your suggested changes fixed turning on and off the relay.

I am also reading from A/D 1. I tried to apply the same logic you used for the relay on/off to reading AD 1, but with no success. It is currently returning as empty. I’ve attached the modified library.

Any help is appreciated!
ncd_industrial_relayV2.py (10.1 KB)

I would assume the issue is in the get_payload method. Specifically the for byte in range(2, len(data)-1)

You can probably just skip the get_payload method and return the raw data like:

def process_read_command_return_no_api(self, data):
	return data

But you the get_payload is turning it into an ord() so that might be necessary in which case you could probably use this:

def process_read_command_return_no_api(self, data):
	return ord(data)

Keep in mind this will only support reading a single adc @ 8 bits. If you wanted to support the other commands as well this replacement might work with what you currently have:

def get_payload(self, data):
	payload = []
	for byte in range(0, len(data)-1):
		payload.append(ord(data[byte:byte+1]))
	return payload

When I used the 2nd method - I received the following data (209 indicates the voltage change I’m interested in). This worked!
0
0
0
209
209
209
0
0
0

When I used the 3rd method - I received the following data - this was harder to interpret
b’\xd0’
b’\xd1’
b’\xd0’
b’\xd1’
b’\xd0’
b’\x00’
b’\x00’

Have any of the changes we’ve made compromised any of the checks on whether relay on/off commands issued have been completed? It’s not a big deal, everything seems very reliable on my end, but if it’s something I should be aware of, then I’ll keep an eye out for missed commands going forward.

Thank you!

There shouldn’t be any issues. Without API mode the worst that should happen is the comms will be slightly slower as the microprocessor has to rely on a timeout process to check for a full command.