cagnulein / qdomyos-zwift

Zwift bridge for smart treadmills and bike/cyclette
https://www.qzfitness.com/
GNU General Public License v3.0
369 stars 109 forks source link

Add support for the Trixter X-Dream V1 bike #855

Open drmason789 opened 2 years ago

drmason789 commented 2 years ago

Full Details

The data comes in from the serial port at baud rate 115200 as 32-character text strings of characters 0-9 and a-f (lower case), i.e. hexadecimal text for 16 bytes. The bike this was measured on delivers packets at a rate of about 1 every 13ms.

                                     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
          (00) Header (0x6a) --------+  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
          (01) Steering ----------------+  |  |  |  |  |  |  |  |  |  |  |  |  |  |
          (02) Unknown (0x80)--------------+  |  |  |  |  |  |  |  |  |  |  |  |  |
          (03) Crank position ----------------+  |  |  |  |  |  |  |  |  |  |  |  |
          (04) Right brake ----------------------+  |  |  |  |  |  |  |  |  |  |  |
          (05) Left brake --------------------------+  |  |  |  |  |  |  |  |  |  |
          (06) Unknown (0xff)--------------------------+  |  |  |  |  |  |  |  |  |
          (07) Unknown (0xff)-----------------------------+  |  |  |  |  |  |  |  |
          (08) Button flags ---------------------------------+  |  |  |  |  |  |  |
          (09) Button flags ------------------------------------+  |  |  |  |  |  |
          (0A) Crank revolution time (high byte) ------------------+  |  |  |  |  |
          (0B) Crank revolution time (low byte) ----------------------+  |  |  |  |
          (0C) Flywheel Revolution Time (high byte) ---------------------+  |  |  |
          (0D) Flywheel Revolution Time (low byte) -------------------------+  |  |
          (0E) Heart rate (BPM) -----------------------------------------------+  |
          (0F) XOR of 00 to 0E----------------------------------------------------+

Header is always 0x6a Steering [0, 255] Crank Position [1,60] Left Brake [135, 250] (250 when released) Right Brake [135, 250] (250 when released) Button Flags are a bitmapped field. Flywheel revolution time F: RPM = 576000.0/F approximately. Crank revolution time C: RPM = 1/(C * 0.000006) approximately. Heart rate is in beats per minute. Unknowns 02, 06, 07 are always 128, 255 and 255. 0F is the XOR of the first 15 bytes.

Button flags combined into 1 16-bit unsigned integer and subtracted from 65535 form a bitmapped field:

None = 0
Seated = 8

BackGearUp = 32
BackGearDown = 64
FrontGearUp = 32768
FrontGearDown = 128

LeftArrow = 4096
RightArrow = 16384
UpArrow = 256
DownArrow = 1024

Blue = 8192
Red = 512
Green = 2048

For Zwift, preferences would be steering, heart rate, cumulative crank and flywheel rotations calculated from time between samples and the speed and cadence themselves.

The bike supports 251 resistance levels, and these are maintained by pushing an array of 6 bytes to the bike every 10ms or so. A resistance level of 0 is maintained by sending nothing.

Each resistance packet is as follows:

                    6a 00 00 00 00 00
00 Header (0x6a) ----+  |  |  |  |  |
01 Level (0..0xFA)------+  |  |  |  |
02 (Level+0x3C)%0xFF ------+  |  |  |
03 (Level+0x5A)%0xFF ---------+  |  |
04 (Level+0x78)%0xFF ------------+  |
05 XOR of 00..04 -------------------+

Unlike the incoming data, which is hexadecimal text, this outgoing data is sent as the actual bytes specified above.