Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T1932 Brake type = Magnetic or Motor #20

Closed
WouterJD opened this issue Jan 10, 2021 · 15 comments
Closed

T1932 Brake type = Magnetic or Motor #20

WouterJD opened this issue Jan 10, 2021 · 15 comments

Comments

@WouterJD
Copy link

WouterJD commented Jan 10, 2021

I would appreciate your view on the decision whether a T1932 is connected to a magnetic or motorbrake.

Current options:

  • default = magnetic brake
  • if a motorbrake message is returned AND type = 41 or 46 then it's a motor brake

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: WouterJD/FortiusANT#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

@totalreverse
Copy link
Owner

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.

@totalreverse
Copy link
Owner

totalreverse commented Jan 10, 2021

To conclude the whole thing:

There are a lot of buffers on the way

  1. from the host to the head unit,
  2. from the head unit to the brake and then
  3. back to the head unit and
  4. back to the host.

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".

@WouterJD
Copy link
Author

WouterJD commented Jan 10, 2021

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).

@WouterJD
Copy link
Author

In the meantime I heard from @BikeBeppe64 that a magnetic brake returns MotorBrakeUnitSerial = 0.
How easy can it be.

@WouterJD
Copy link
Author

So, a simple improvement may be to check the type of answer before decoding it to a specific type.

Will do

@totalreverse
Copy link
Owner

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.

@WouterJD
Copy link
Author

Thanks

@WouterJD
Copy link
Author

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

  • T1932 with motor brake returns MotorBrakeUnitSerial = 0 !!
    I'm going to further investigate what is exactly returned, with the newly implemented recovery and CommandVersion check.

What would you think that T1932 returns for a magnetic brake?

  • No message
  • Or a message with zero-values?

@WouterJD WouterJD reopened this Jan 13, 2021
@totalreverse
Copy link
Owner

totalreverse commented Jan 13, 2021

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

@WouterJD
Copy link
Author

@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 :-)

@totalreverse
Copy link
Owner

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.

@WouterJD
Copy link
Author

That's a deal🍺🍻

@WouterJD
Copy link
Author

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.

@WouterJD
Copy link
Author

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....

@WouterJD
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants