tc420
tc420 copied to clipboard
Partial success
Hi,
I've installed according to the instructions, from source. I'm using Mint 20.2 (the Ubuntu based one), and setting the clock works fine. However, playing the example doesn't. Not uite sure where to look. On the same machine, using vbox/win10 and Pled, everything is fine.
lsusb says
Bus 001 Device 013: ID 0888:4000 MindMotion SOC Solutions MM32 Custom HID
This is the output:
/linux.sh
/home/chris/Public/tc420/tc420/__main__.py:286: DeprecationWarning: 'resultcallback' has been renamed to 'result_callback'. The old name will be removed in Click 8.1.
@cmd_group.resultcallback()
Syncing time... OK.
Initialize playing 'Play'... Traceback (most recent call last):
File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/home/chris/Public/tc420/tc420/__main__.py", line 304, in <module>
main()
File "/home/chris/Public/tc420/tc420/__main__.py", line 300, in main
cmd_group()
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/click/core.py", line 1137, in __call__
return self.main(*args, **kwargs)
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/click/core.py", line 1062, in main
rv = self.invoke(ctx)
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/click/core.py", line 1699, in invoke
rv.append(sub_ctx.command.invoke(sub_ctx))
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/click/core.py", line 763, in invoke
return __callback(*args, **kwargs)
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/click/decorators.py", line 26, in new_func
return f(get_current_context(), *args, **kwargs)
File "/home/chris/Public/tc420/tc420/__main__.py", line 205, in play
ctx.obj.dev.play(name=name, adapter=adapter, onchange_callback=onchange_callback)
File "/home/chris/Public/tc420/tc420/tc420.py", line 413, in play
res = self.send(PlayInitPacket(name))
File "/home/chris/Public/tc420/tc420/tc420.py", line 322, in send
res_pkt = TC420Packet(payload=self.in_ep.read(64, timeout=self.timeout))
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/usb/core.py", line 423, in read
return self.device.read(self, size_or_buffer, timeout)
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/usb/core.py", line 1029, in read
ret = fn(
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/usb/backend/libusb1.py", line 864, in intr_read
return self.__read(self.lib.libusb_interrupt_transfer,
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/usb/backend/libusb1.py", line 954, in __read
_check(retval)
File "/home/chris/Public/tc420/venv/lib/python3.8/site-packages/usb/backend/libusb1.py", line 602, in _check
raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBTimeoutError: [Errno 110] Operation timed out
Same exception when running tc420 demo
. I have it installed via pip3 on Ubuntu 18.04 and tc420 time-sync
works.
It may also be relevant that I'm getting an error when I chain mode
calls.
time-sync \
mode --name Default --bank 0 \
--step 08:00 0 0 0 0 0 \
--step 09:00 100 100 100 100 100 \
--step 21:00 100 100 100 100 100 \
--step 22:00 0 0 0 0 0 \
This results in an AssertionError: Setting step 2 in mode 'Default' has been failed!
and after which running a second time time-sync
reports ERROR!
rather than OK.
and it goes no further.
I encounter the same error. For debugging purposes I added the sent and received packets. I hope you have a chance to look at that @wallneradam, that would be much appreciated. Thank you.
python3 -m tc420 mode -n test1 -b 0 -s 08:00 100 100 0 0 0 -s 21:00 0 0 0 0 0
Setting mode 'test1' in bank 0... send:
bytearray(b'U\xaa\x12\x00\x07\x00\x02test1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\r\n')
response:
bytearray(b'\x00\x00\x12\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
send:
bytearray(b'U\xaa\x13\x00\x08\x08\x00dd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\r\n')
response:
bytearray(b'\xff\xff\x13\xff\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
Traceback (most recent call last):
File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/home/msquare/projects/tc420/tc420/__main__.py", line 304, in <module>
main()
File "/home/msquare/projects/tc420/tc420/__main__.py", line 300, in main
cmd_group()
File "/usr/lib/python3/dist-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python3/dist-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 1289, in invoke
rv.append(sub_ctx.command.invoke(sub_ctx))
File "/usr/lib/python3/dist-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3/dist-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python3/dist-packages/click/decorators.py", line 21, in new_func
return f(get_current_context(), *args, **kwargs)
File "/home/msquare/projects/tc420/tc420/__main__.py", line 141, in mode
check_result(ctx.obj.dev.mode(name=name, bank=bank, steps=steps, step_ready_cb=step_ready_cb))
File "/home/msquare/projects/tc420/tc420/tc420.py", line 365, in mode
assert res, f"Setting step {i+1} in mode '{name}' has been failed!"
AssertionError: Setting step 1 in mode 'test1' has been failed!
Looking for root causes I found this:
- Some of the packets sent to the TC420 need a bit of time to be processed.
- A subsequent package will fail if you send it too quickly. With modern CPUs and faster USB chips (and optimizations of the Python interpreter), this may have shifted to the bad.
- Some of the cli commands translate to a series of packages, therefore a 'mode' with several steps may encounter this. Same applies to chained commands, or even to complex single commands launched from a shell script in rapid sequence (this was my starting point!).
- Commands 'demo' and 'play' need to be cancelled, which on the packet level translates to a final ModeStopPacket. This regularly showed the USBTimeoutError too.
If my observations are correct, some calls to a short sleep(0.01) should fix it. Whether 10ms are sufficient for all possible packets, I don't know; it fixed all of above cases for me. I will create a PR.
The exception message looks similar to the one in issue #9. Since there is a fix available, it might be worth to try this. Unfortunately Adam did not accept the PR generated by me. He seems to be completely gone :-(
To make this and other fixes available I created a fork https://github.com/schwabix-1311/tc420 to add all new stuff there. Please feel free to re-raise the issue there. The HEAD of my fork includes all PRs found here, namely
- update to package click >= 8.1.0 => rename of resultcallback to result_callback
- non-sudo use of tc420
- USBTimeoutErrors
- multiple TC420 controllers connected to same system