Closed WouterJD closed 3 years ago
Looks like a problem with junk data or some kind of out-of-sync of commands and answers ...
For my brake FortiusAnt sometimes prints nothing and sometimes wrong values like
Motor Brake Unit Firmware=6918 Serial=37184 year=2078 type=T19164 Version2=0 MotorBrake=True
TTY1941 says:
firmwareVersion= 00.00.09.65, serial= 410502330 (Tacx T1941 Year 2005 #02330), Date= 0c.08 Unknown= 00.00
100ms should be safe to not overrun the serial communication. But it is difficult to sync commands and answers of the brake until you wait for an expected answer after doing some dummy reads to remove old data or junk communication pipe of the headunit-to-host communication.
Short test ... after repeating the version request in usbTrainer.py Line 2486 like this
self.SendToTrainer(True, modeMotorBrake)
time.sleep(0.1) # Allow head unit time to process
self._ReceiveFromTrainer_MotorBrake()
self.SendToTrainer(True, modeMotorBrake)
time.sleep(0.1) # Allow head unit time to process
self._ReceiveFromTrainer_MotorBrake()
self.SendToTrainer(True, modeMotorBrake)
time.sleep(0.1) # Allow head unit time to process
self._ReceiveFromTrainer_MotorBrake()
self.SendToTrainer(True, modeMotorBrake)
time.sleep(0.1) # Allow head unit time to process
self._ReceiveFromTrainer_MotorBrake()
self.SendToTrainer(True, modeMotorBrake)
time.sleep(0.1) # Allow head unit time to process
self._ReceiveFromTrainer_MotorBrake()
I got
13:19:04,860: Motor Brake Unit Firmware=0 Serial=85760 year=2088 type=T19164 Version2=0 MotorBrake=True
13:19:04,962: Motor Brake Unit Firmware=2405 Serial= 2330 year=2005 type=T1941 Version2=3080 MotorBrake=True
13:19:05,166: Motor Brake Unit Firmware=2405 Serial= 2330 year=2005 type=T1941 Version2=3080 MotorBrake=True
13:19:05,269: Motor Brake Unit Firmware=2405 Serial= 2330 year=2005 type=T1941 Version2=3080 MotorBrake=True
Result: After sending 5 request, I only got 4 answer: 1 wrong and 3 valid.
To conclude the whole thing:
There are a lot of buffers on the way
If you send a command from the host to the head unit you cannot ensure, that the next USB read is the direct answer on your request. If you startup the brake it even sends some junk.
Better you do some dummy reads on the USB before sending the first command. And maybe you should even send the version request more than one time, until you got a valid and expected version answer from the brake.
The "random" version messages I got in my test above are very probably old answers on a control command from the last run. So, a simple improvement may be to check the type of answer before decoding it to a specific type. Every answer on a version request starts (in bytes 24..27) with "0x03 0x0c 0x00 0x00" and every answer on a control command starts with "0x03 0x13 0x02 0x00".
Thanks for quick reply, I will add a sort-of initialization loop.
Now you mention it -we also found this- the MotorBrakeUnitSerial (see https://github.com/totalreverse/ttyT1941/wiki#t1941-motor-brake-version-message) is not always tt-YY-##### the actual serial number can also be ####; something for the wiki if you like.
I was put on the wrong leg because the MotorBrakeUnitSerial is received as int, but it better be processed as str(MotorBrakeUnitSerial).
In the meantime I heard from @bikebeppe64 that a magnetic brake returns MotorBrakeUnitSerial = 0. How easy can it be.
So, a simple improvement may be to check the type of answer before decoding it to a specific type.
Will do
In the meantime I heard from @BikeBeppe64 that a magnetic brake returns MotorBrakeUnitSerial = 0. How easy can it be.
Ok. In this case the head unit must emulate a serial number, because the old magnetic breaks are just too dump to report a serial.
Thanks
In the meantime I heard from @BikeBeppe64 that a magnetic brake returns MotorBrakeUnitSerial = 0. How easy can it be.
Pffff... this appears to be a misunderstanding
What would you think that T1932 returns for a magnetic brake?
Just went downstairs and connected my old eddy current brake to a T1932 head unit.
You need to switch on the magnetic brake. Then a version command
(hex) 02 00 00 00
triggers a 64 byte answer, which I splitted in three parts here
Bytes 0..23 is the standard head unit frame
Bytes 24..48 is the (emulated) brake frame and
the last part 49..63 are just padding bytes
07 db 07 00 00 02 00 00 09 00 00 00 00 00 00 00 00 00 0d 0a 00 00 00 00
03 0c 00 00 02 19 00 00 00 00 00 00 00 00 00 00 35 69 00 00 00 00 02 55 64
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
The important parts are bytes 24..27 (the standard version command answer header) and bytes 28..31, which converts to 0x00001902 if you read them as little endian encoded uint32. I think ,it is a good idea to check these 8 bytes.
Edit: FortiusAnt converts Hex 0x1902 to a Decimal and says:
Motor Brake Unit Firmware=6402 Serial= 0 year=2000 type=T190 Version2=0 MotorBrake=False
@totalreverse you're a great help; thank you very much. I'd like to have a beer together; if you do - you know how to find me. I will implement; and you can add to the wiki :-)
I'd like to have a beer together; if you do - you know how to find me.
Summer and better times will come. Would be a long ride for a beer, though; at least 330km. I live in southern germany and work in Lower Saxony.
That's a deal🍺🍻
bytes 28..31, which converts to 0x00001902
Which is quite funny, since that suggests the T1932 headunit operates in a sort of T1902 head unit mode, although the interface is different. Good reason to display the firmware in hex-format.
The code now is
self.MotorBrake = True # This sets the default
if len(data) < 40:
pass
else:
if self.MotorBrakeUnitType in (41, 46, 49):
self.MotorBrake = True # Explicitly Motor brake
if self.MotorBrakeUnitSerial == 0:
self.MotorBrake = False # Explicitly Magnetic brake
if self.clv.Tacx_MotorBrake: self.MotorBrake = True # Overrule from -t command line option
if self.clv.Tacx_MagneticBrake: self.MotorBrake = False
So it's always a motor-brake, unless a message is received with MotorBrakeUnitSerial OR -t MagneticBrake As always; suggestions welcome....
I do not only retry on the length but also the expected header. 6402 --> 0x1902 in version V
Thanks, some other steps forward
13:42:51,600: clsTacxNewUsbTrainer._ReceiveFromTrainer_MotorBrake()...
13:42:51,600: Trainer recv hdr=0x21303 data="array('B', [47, 80, 47, 0, 0, 2, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 10, 0, 0, 0, 0, 3, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 15, 4, 0, 0, 0, 0, 0, 0, 2, 85, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])" (len=64)
13:42:51,600: Retry because short buffer (len=64) or incorrect header received (expected: 0xc03 received: 0x21303)
13:42:51,702: Trainer recv hdr=0xc03 data="array('B', [47, 80, 47, 0, 0, 2, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 10, 0, 0, 0, 0, 3, 12, 0, 0, 2, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 105, 0, 0, 0, 0, 2, 85, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])" (len=64)
13:42:51,702: Motor Brake Unit Firmware=6402 Serial= 0 year=2000 type=T190 Version2=0 MotorBrake=False
13:42:51,702: ... returns True
13:42:51,808: FortiusAnt applies the MagneticBrake power curve
I would appreciate your view on the decision whether a T1932 is connected to a magnetic or motorbrake.
Current options:
BUT: there appear to be more types (e.g. 49) AND: not always a correct message is returned, even after retry causing FortiusAnt to behave like a magnetic brake, where a motor brake is connected
Issue: https://github.com/WouterJD/FortiusANT/issues/200
Code: https://github.com/WouterJD/FortiusANT/blob/5.1%2B4.2-Quality-upgrade/pythoncode/usbTrainer.py#L2516 https://github.com/WouterJD/FortiusANT/blob/5.1%2B4.2-Quality-upgrade/pythoncode/usbTrainer.py#L2141
Would 0.1 seconds wait-time be too short? According to good old code comment, 100ms should be safe ?? '# TRAINER- SHOULD WRITE THEN READ 70MS LATER REALLY