B3000 Identify Optomux Type response

I have no SNAP analog modules to test so I want to know how the B3000 responds to this command. Mine responds with A00 digital type. If one address contains both digital and analog SNAP modules, how does it respond? It seems likely that digital and analog modules could be located at different consecutive addresses if this makes the Identify Optomux Type response more meaningful.

Answering my own question. The B3000 has 4 addresses. The first two report digital, and the second two report analog.

I’ve been writing some python stuff under linux to talk to the B3000 using the Optomux protocol just for grins in retirement. Almost all commands are now working. However, I do have a need for a couple of SNAP 2 channel analog I/O modules for testing analog commands. All I have is digital.

If I was still working, I’d shell out the money for a couple of new ones, but being retirement poor, I’m looking for something on the surplus market. Noting quite right on ebay yet.

Are you going to put your code on Github so others can use?

I may just put on github after I verify analog portion. However I have no analog modules, so I have a bid on ebay for yet another b3000/rack/module combo. We’ll see if the seller accepts or counters. Since I have 4 B3000s, 4 8 module racks, and 16 ODC and 16 IDC modules I really just wanted the analog modules.

Here’s a sample Python 3.4 terminal session with what I’ve written so far.

>>> on.reset(4)
(‘A’, 0)
>>> on.set_timer_resolution(4,1)
(‘A’, 0)
>>> on.set_timer_resolution(0,10)
(‘A’, 0)
>>> on.set_pulse_trigger_polarity(4,15)
(‘A’, 0)
>>> on.read_and_clear_pulse_duration_counters(4,15)
(‘A’, (0, 0, 0, 0))
>>> on.read_pulse_complete_bits(4)
(‘A’, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.start_on_pulse(0,15,50)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
(‘A’, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.trigger_on_positive_pulse(4,15)
(‘A’, 0)
>>> on.start_on_pulse(0,15,50)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
(‘A’, (1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.read_and_clear_pulse_duration_counters(4,15)
(‘A’, (499, 500, 499, 500))
utl.start_logging()
logging started
>>> on.set_pulse_trigger_polarity(4,15)
OmuxNET.set_pulse_trigger_polarity(address=4,positions=15)
OmuxNET.send_receive(address=4,command=28,{‘positions’: 15})
OmuxNET.build_packet(address=4,command=28,{‘positions’: 15})
OmuxTTY.write(pkt=>04a000F9B)
OmuxTTY.read(n=2)
OmuxNET.process_response(command=28,rsp=A)
(‘A’, 0)
>>> on.start_on_pulse(0,15,50)
OmuxNET.start_on_pulse(address=0,positions=15,time=50)
OmuxNET.send_receive(address=0,command=73,{‘positions’: 15, ‘data’: 50})
OmuxNET.build_packet(address=0,command=73,{‘positions’: 15, ‘data’: 50})
OmuxTTY.write(pkt=>00k000F3206)
OmuxTTY.read(n=2)
OmuxNET.process_response(command=73,rsp=A)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
OmuxNET.read_pulse_complete_bits(address=4)
OmuxNET.send_receive(address=4,command=31)
OmuxNET.build_packet(address=4,command=31)
OmuxTTY.write(pkt=>04dC8)
OmuxTTY.read(n=8)
OmuxNET.process_response(command=31,rsp=A0000C0)
OmuxNET.optomux_data_to_tuple(data=0000)
(‘A’, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.read_and_clear_pulse_duration_counters(4,15)
OmuxNET.read_and_clear_pulse_duration_counters(address=4,positions=15)
OmuxNET.send_receive(address=4,command=33,{‘positions’: 15})
OmuxNET.build_packet(address=4,command=33,{‘positions’: 15})
OmuxTTY.write(pkt=>04f000FA0)
OmuxTTY.read(n=20)
OmuxNET.process_response(command=33,rsp=A000000000000000000)
OmuxNET.optomux_data_to_tuple(data=0000000000000000,bits=16)
(‘A’, (0, 0, 0, 0))
>>> on.trigger_on_positive_pulse(4,15)
OmuxNET.trigger_on_positive_pulse(address=4,positions=15)
OmuxNET.send_receive(address=4,command=29,{‘positions’: 15})
OmuxNET.build_packet(address=4,command=29,{‘positions’: 15})
OmuxTTY.write(pkt=>04b000F9C)
OmuxTTY.read(n=2)
OmuxNET.process_response(command=29,rsp=A)
(‘A’, 0)
utl.stop_logging()
logging stopped
>>> on.start_on_pulse(0,15,50)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
(‘A’, (1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.read_and_clear_pulse_duration_counters(4,15)
(‘A’, (499, 500, 499, 500))

What module are you looking for?

I have an ebay order coming in with 2 10V output modules and and 2 +/-10VDC inputs modules. I won’t have any special function things like pH/ORP, Quadrature, RTD/Thermocouple, current loop, etc. I’m hoping the basic analog modules will allow me to test my analog commands.

Once I get Optomux functioning, I plan to play with Mistic some. Tha’s one reason I liked the B3000. It’s old but supports two protocols.

I liked Optomox back when we made our own controllers. They were super simple to talk to. I think that was the basis for Johnson Controls N2 as well. Do you have any Misitc hardware to test with?

I have 5 B3000s, 4 8 module and 1 16 module racks, 37 digital and 4 analog modules. The B3000 claims to support Mistic based on a jumper. When they went to B3000-B they split firmware into 2 part numbers.

So I’m assuming I can write and test most of my driver stuff by moving a jumper. Obviously B3000 being older may have some work arounds. So far just a hobby unless I find an Opto Partner in Tallahassee, FL area interested in some part time software contract help.

Heres a sample python terminal session with logging off as I am testing initiate_square_wave using counters. Address 0 outputs (0,1,2,3) wired to Address 4 inputs (0,1,2,3).

        >>> on.reset(4)
        ('A', 0)
        >>> on.start_counters(4,15)
        ('A', 0)
        >>> on.initiate_square_wave(0,15,1,1)
        ('A', 0)
        >>> on.read_counters(4,15)
        ('A', (5, 5, 5, 5))
        >>> on.stop_counters(4,(0,2))
        ('A', 0)
        >>> on.read_counters(4)
        ('A', (8, 10, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
        >>> on.turn_off_time_delay_or_square_wave(0,(1,3))
        ('A', 0)
        >>> on.read_counters(4,15)
        ('A', (8, 21, 8, 21))
        >>> on.read_counters(4,15)
        ('A', (8, 21, 8, 21))
        >>> on.start_counters(4,(0,2))
        ('A', 0)
        >>> on.read_counters(4,15)
        ('A', (12, 21, 12, 21))
        >>> on.turn_off_time_delay_or_square_wave(0,15)
        ('A', 0)
        >>> on.read_and_clear_counters(4,15)
        ('A', (16, 21, 16, 21))
        >>> on.read_counters(4,15)
        ('A', (0, 0, 0, 0))

On my B3000 Optomux firmware, I am having trouble with the ‘Set Trigger Pulse Polarity’ command. It does not seem to function, but the ‘Trigger On Positive Pulse’ and ‘Trigger On Negative Pulse’ do work. Here is a python terminal dump showing the problem.

>>> on.date_of_firmware(4)
OmuxNET.date_of_firmware(address=4)
OmuxNET.send_receive(address=4,command=80)
OmuxNET.build_packet(address=4,command=80)
OmuxTTY.write(pkt=>04`C4)
OmuxTTY.read(n=28)
OmuxNET.process_response(command=80,rsp=A810A09149809020100300000C8)
('A', '09/14/98')
>>> on.date_of_firmware(0)
OmuxNET.date_of_firmware(address=0)
OmuxNET.send_receive(address=0,command=80)
OmuxNET.build_packet(address=0,command=80)
OmuxTTY.write(pkt=>00`C0)
OmuxTTY.read(n=28)
OmuxNET.process_response(command=80,rsp=A810A09149809020100300000C8)
('A', '09/14/98')

>>> on.reset(4)
(‘A’, 0)
>>> on.set_timer_resolution(4,1)
(‘A’, 0)
>>> on.set_timer_resolution(0,10)
(‘A’, 0)
>>> on.set_pulse_trigger_polarity(4,15)
(‘A’, 0)
>>> on.read_and_clear_pulse_duration_counters(4,15)
(‘A’, (0, 0, 0, 0))
>>> on.read_pulse_complete_bits(4)
(‘A’, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.start_on_pulse(0,15,50)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
(‘A’, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.trigger_on_positive_pulse(4,15)
(‘A’, 0)
>>> on.start_on_pulse(0,15,50)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
(‘A’, (1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.read_and_clear_pulse_duration_counters(4,15)
(‘A’, (499, 500, 499, 500))
utl.start_logging()
logging started
>>> on.set_pulse_trigger_polarity(4,15)
OmuxNET.set_pulse_trigger_polarity(address=4,positions=15)
OmuxNET.send_receive(address=4,command=28,{‘positions’: 15})
OmuxNET.build_packet(address=4,command=28,{‘positions’: 15})
OmuxTTY.write(pkt=>04a000F9B)
OmuxTTY.read(n=2)
OmuxNET.process_response(command=28,rsp=A)
(‘A’, 0)
>>> on.start_on_pulse(0,15,50)
OmuxNET.start_on_pulse(address=0,positions=15,time=50)
OmuxNET.send_receive(address=0,command=73,{‘positions’: 15, ‘data’: 50})
OmuxNET.build_packet(address=0,command=73,{‘positions’: 15, ‘data’: 50})
OmuxTTY.write(pkt=>00k000F3206)
OmuxTTY.read(n=2)
OmuxNET.process_response(command=73,rsp=A)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
OmuxNET.read_pulse_complete_bits(address=4)
OmuxNET.send_receive(address=4,command=31)
OmuxNET.build_packet(address=4,command=31)
OmuxTTY.write(pkt=>04dC8)
OmuxTTY.read(n=8)
OmuxNET.process_response(command=31,rsp=A0000C0)
OmuxNET.optomux_data_to_tuple(data=0000)
(‘A’, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.read_and_clear_pulse_duration_counters(4,15)
OmuxNET.read_and_clear_pulse_duration_counters(address=4,positions=15)
OmuxNET.send_receive(address=4,command=33,{‘positions’: 15})
OmuxNET.build_packet(address=4,command=33,{‘positions’: 15})
OmuxTTY.write(pkt=>04f000FA0)
OmuxTTY.read(n=20)
OmuxNET.process_response(command=33,rsp=A000000000000000000)
OmuxNET.optomux_data_to_tuple(data=0000000000000000,bits=16)
(‘A’, (0, 0, 0, 0))
>>> on.trigger_on_positive_pulse(4,15)
OmuxNET.trigger_on_positive_pulse(address=4,positions=15)
OmuxNET.send_receive(address=4,command=29,{‘positions’: 15})
OmuxNET.build_packet(address=4,command=29,{‘positions’: 15})
OmuxTTY.write(pkt=>04b000F9C)
OmuxTTY.read(n=2)
OmuxNET.process_response(command=29,rsp=A)
(‘A’, 0)
utl.stop_logging()
logging stopped
>>> on.start_on_pulse(0,15,50)
(‘A’, 0)
>>> on.read_pulse_complete_bits(4)
(‘A’, (1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
>>> on.read_and_clear_pulse_duration_counters(4,15)
(‘A’, (499, 500, 499, 500))

I now have analog modules. I am testing the 10vdc output code. I have found that all of the ‘Enhanced Output Waveform’ shapes work except for the square wave. If you look at the logging info, I create a triangle wave and a square wave, changing only the waveform type. The triangle works but the square doesn’t. B3000 ACKs both messages as correct but for some reason does not actually generate the square wave. When I say it doesn’t work, I have a scope on the output pin.

>>> on.enhanced_output_waveform(3,15,4,0xff0,0x00c,120)
OmuxNET.enhanced_output_waveform(address=3,positions=15,shape=4,hi_limit=4080,lo_limit=12,period=120)
OmuxNET.send_receive(address=3,command=50,{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 4})
OmuxNET.build_packet(address=3,command=50,{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 4})
OmuxNET.verify_address(address=3)
OmuxNET.verify_command(command=50)
OmuxNET.verify_positions(command=50,afmt=['V', 'positions', 'modifiers', 'data'],{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 4})
OmuxNET.verify_modifiers(command=50,afmt=['V', 'positions', 'modifiers', 'data'],{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 4})
OmuxNET.verify_single_modifier(command=50,modifier=4)
OmuxNET.verify_data(command=50,afmt=['V', 'positions', 'modifiers', 'data'],{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 4})
OmuxNET.verify_list_of_data_values(command=50,values=(4080, 12, 120))
OmuxTTY.flush_input_buffer()
OmuxTTY.rx_bytes_available()
OmuxTTY.write(pkt=>03V000F4FF000C0078F1\r)
Response timeout is 0.047497 secs
OmuxTTY.rx_bytes_available()
OmuxTTY.rx_bytes_available()
OmuxTTY.read(n=2)
Response time took 0.022140 secs
OmuxNET.process_response(command=50,rsp=A\r)
('A', 0)
>>> on.enhanced_output_waveform(3,15,1,0xff0,0x00c,120)
OmuxNET.enhanced_output_waveform(address=3,positions=15,shape=1,hi_limit=4080,lo_limit=12,period=120)
OmuxNET.send_receive(address=3,command=50,{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 1})
OmuxNET.build_packet(address=3,command=50,{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 1})
OmuxNET.verify_address(address=3)
OmuxNET.verify_command(command=50)
OmuxNET.verify_positions(command=50,afmt=['V', 'positions', 'modifiers', 'data'],{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 1})
OmuxNET.verify_modifiers(command=50,afmt=['V', 'positions', 'modifiers', 'data'],{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 1})
OmuxNET.verify_single_modifier(command=50,modifier=1)
OmuxNET.verify_data(command=50,afmt=['V', 'positions', 'modifiers', 'data'],{'positions': 15, 'data': (4080, 12, 120), 'modifiers': 1})
OmuxNET.verify_list_of_data_values(command=50,values=(4080, 12, 120))
OmuxTTY.flush_input_buffer()
OmuxTTY.rx_bytes_available()
OmuxTTY.write(pkt=>03V000F1FF000C0078EE\r)
Response timeout is 0.047498 secs
OmuxTTY.rx_bytes_available()
OmuxTTY.rx_bytes_available()
OmuxTTY.read(n=2)
Response time took 0.024945 secs
OmuxNET.process_response(command=50,rsp=A\r)
('A', 0)
>>> on.date_of_firmware(3)
OmuxNET.date_of_firmware(address=3)
OmuxNET.send_receive(address=3,command=80)
OmuxNET.build_packet(address=3,command=80)
OmuxNET.verify_address(address=3)
OmuxNET.verify_command(command=80)
OmuxNET.verify_positions(command=80,afmt=['`'])
OmuxNET.verify_modifiers(command=80,afmt=['`'])
OmuxNET.verify_data(command=80,afmt=['`'])
OmuxTTY.flush_input_buffer()
OmuxTTY.rx_bytes_available()
OmuxTTY.write(pkt=>03`C3\r)
Response timeout is 0.047498 secs
OmuxTTY.rx_bytes_available()
OmuxTTY.rx_bytes_available()
OmuxTTY.read(n=28)
Response time took 0.024361 secs
OmuxNET.process_response(command=80,rsp=A812210240104200100320000A1\r)
('A', '10/24/01')
>>>