UM6 bad checksums

Hello everyone.

I wanted to post on Chrobotics forum, but I can’t seem to find any. :þ Seems that this is a good place to ask, though. Maybe someone had similar problem alrady.

So I’m trying to make CHR-UM6 working, and I have trouble with understanding its behaviour. Maybe I’ve missed something in the data sheet, I don’t know. I don’t think it’s the hardware problem, since communication generally seems to work, only that sometimes I’m getting packets with wrong checksums or the sensor reports “bad checksum” packet in response to my packets. I’ve made sure that there are no issues with my code, I also created some graphs on my oscilloscope to make sure that I really send what I mean to send.

What I do:

  • I disable broadcast mode by writing to COMMUNICATION register.
  • I write again to COMMUNICATION register, get OK from the sensor.
  • write to MISC register, get OK.
  • issue GET_FW_VERSION, get a “bad checksum” packet.
  • issue GET_FW_VERSION again, get proper version: “UM2B”.
  • read EKF process variance
  • write new process variance
  • issue RESET_EKF, get “bad checksum”.
  • repeat RESET_EKF, get OK.

This is what it looks like, if I disable broadcast mode. If I enable it, I often get packets with wrong checksum, or packets that obviously look cut, in the initial burst of data (first read from sensor, skipped to the first ‘snp’ sequence, and then one or two packets with wrong checksums). Maybe it has something to do with sensor’s UART buffers? What works without problems, though, is after I manage to initialize the sensor, and normally periodically read data from it, I never get any errors. It works flawlessly, then.

So my conclusion is that problem occurs only when I write to the sensor. Am I supposed to wait certain amount of time before sending some commands? Is there certain allowed sequence, on which commands should be sent? Or maybe I build command packets wrong way? (GET_FW_VERSION = 73:6e:70:00:aa:01:fb), but why would it work after second try?

I made sure that what you see here is what is transmitted over UART. I’ve had bugs in my code, obviously, when I first wrote it, but I’m pretty sure I eliminated at least those which would affect the communication. I also use my serial code with other devices (GPS) and it works correctly with them. This is the log of communication between my program and UM6, also graphs from the communication are attached. There’s fair amount of under and overshots visible, which I later fixed by adding 3.9nF capacitor between RX/TX lines and the ground. This has also reduced noise on the other line, when first was transmitting data. But the result is still all the same.

Is there someone from CHrobotics reading this forum? I’m not an expert, when it comes to electrical engineering, I’m a programmer myself. Maybe there’s some problem with my serial cable? It’s supposed to be TTL level USB-to-serial cable, I got it from Adafruit. It works with GPS, raspberry Pi, Beagle Bone black, without any issues.

More details follow:

Power: 5V from USB
Drawn current: about 48 mA most of the time, power source is able to deliver at least 0.5 A.
UART levels: 3.3V, not pulled up (it doesn’t work, anyway, I suppose there might be zener diodes inside my USB-serial cable, or something similar).
Speed: I’m using 115 kbps since it’s default, but it’s irrelevant since the same exact behaviour is on lower baud rates.

You can see the log from transmission, all bytes transmitted and received (denoted by SERIAL keyword).

1384005223.7507 [io/chr-um6                    #                    ] Opening device /dev/ttyUSB0
1384005223.7527 [io/chr-um6                    #                    ] Setting baud rate: 115200, data bits: 8, parity: none, stop bits: 1
1384005223.7528 [io/chr-um6                    #                    ] Connected.
1384005223.7528 [io/chr-um6                    #                    ] 
1384005223.7529 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 0
1384005223.7529 [io/chr-um6                    #                    ]  * make_packet (0x0, Write, 0x7500504)
1384005223.7529 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:80:00:07:50:05:04:02:31  should write 11, wrote 11
1384005224.5533 [io/chr-um6                    #                    ] SERIAL --> 73:6e:70:00:00:01:51
1384005224.5534 [io/chr-um6                    #                    ]  * process_packet (0x0, failed=0, has_data=0, data=0x0)
1384005224.5534 [io/chr-um6                    #                    ] 
1384005224.5534 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 1
1384005224.5535 [io/chr-um6                    #                    ]  * make_packet (0x1, Write, 0xf0000000)
1384005224.5535 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:80:01:f0:00:00:00:02:c2  should write 11, wrote 11
1384005224.5591 [io/chr-um6                    #                    ] SERIAL --> 73:6e:70:00:01:01:52
1384005224.5591 [io/chr-um6                    #                    ]  * process_packet (0x1, failed=0, has_data=0, data=0x0)
1384005224.5591 [io/chr-um6                    #                    ] 
1384005224.5591 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 2
1384005224.5592 [io/chr-um6                    #                    ]  * make_packet (0xaa, Command, 0x0)
1384005224.5592 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:aa:01:fb  should write 7, wrote 7
1384005224.7551 [io/chr-um6                    #                    ] SERIAL --> 73:6e:70:00:fd:02:4e
1384005224.7552 [io/chr-um6                    #                    ]  * process_packet (0xfd, failed=0, has_data=0, data=0x0)
1384005224.7552 [io/chr-um6                    #                    ] Command failed: bad checksum.
1384005224.7553 [io/chr-um6                    #                    ] 
1384005224.7553 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 2
1384005224.7553 [io/chr-um6                    #                    ]  * make_packet (0xaa, Command, 0x0)
1384005224.7553 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:aa:01:fb  should write 7, wrote 7
1384005224.7619 [io/chr-um6                    #                    ] SERIAL --> 73:6e:70:80:aa:55:4d:32:42:03:91
1384005224.7620 [io/chr-um6                    #                    ]  * process_packet (0xaa, failed=0, has_data=1, data=0x554d3242)
1384005224.7621 [io/chr-um6                    #                    ] Firmware version: UM2B
1384005224.7621 [io/chr-um6                    #                    ] 
1384005224.7621 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 3
1384005224.7621 [io/chr-um6                    #                    ]  * make_packet (0xa, Read, 0x0)
1384005224.7622 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:0a:01:5b  should write 7, wrote 7
1384005224.7631 [io/chr-um6                    #                    ] SERIAL --> 73
1384005224.7632 [io/chr-um6                    #                    ] SERIAL --> 6e
1384005224.7644 [io/chr-um6                    #                    ] SERIAL --> 70:80:0a:3f:00:00:00:02:1a
1384005224.7645 [io/chr-um6                    #                    ]  * process_packet (0xa, failed=0, has_data=1, data=0x3f000000)
1384005224.7645 [io/chr-um6                    #                    ] EKF process variance: 0.5
1384005224.7645 [io/chr-um6                    #                    ] 
1384005224.7645 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 4
1384005224.7645 [io/chr-um6                    #                    ]  * make_packet (0xa, Write, 0x3f000000)
1384005224.7646 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:80:0a:3f:00:00:00:02:1a  should write 11, wrote 11
1384005224.7667 [io/chr-um6                    #                    ] SERIAL --> 73
1384005224.7668 [io/chr-um6                    #                    ] SERIAL --> 6e:70
1384005224.7670 [io/chr-um6                    #                    ] SERIAL --> 00
1384005224.7671 [io/chr-um6                    #                    ] SERIAL --> 0a:01
1384005224.7672 [io/chr-um6                    #                    ] SERIAL --> 5b
1384005224.7672 [io/chr-um6                    #                    ]  * process_packet (0xa, failed=0, has_data=0, data=0x0)
1384005224.7672 [io/chr-um6                    #                    ] 
1384005224.7672 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 5
1384005224.7673 [io/chr-um6                    #                    ]  * make_packet (0xad, Command, 0x0)
1384005224.7673 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:ad:01:fe  should write 7, wrote 7
1384005224.7689 [io/chr-um6                    #                    ] SERIAL --> 73:6e:70
1384005224.7691 [io/chr-um6                    #                    ] SERIAL --> 00
1384005224.7692 [io/chr-um6                    #                    ] SERIAL --> fd
1384005224.7693 [io/chr-um6                    #                    ] SERIAL --> 02:4e
1384005224.7694 [io/chr-um6                    #                    ]  * process_packet (0xfd, failed=0, has_data=0, data=0x0)
1384005224.7694 [io/chr-um6                    #                    ] Command failed: bad checksum.
1384005224.7694 [io/chr-um6                    #                    ] 
1384005224.7694 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 5
1384005224.7694 [io/chr-um6                    #                    ]  * make_packet (0xad, Command, 0x0)
1384005224.7695 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:ad:01:fe  should write 7, wrote 7
1384005224.7724 [io/chr-um6                    #                    ] SERIAL --> 73
1384005224.7726 [io/chr-um6                    #                    ] SERIAL --> 6e:70
1384005224.7727 [io/chr-um6                    #                    ] SERIAL --> 00:ad
1384005224.7728 [io/chr-um6                    #                    ] SERIAL --> 01
1384005224.7730 [io/chr-um6                    #                    ] SERIAL --> fe
1384005224.7730 [io/chr-um6                    #                    ]  * process_packet (0xad, failed=0, has_data=0, data=0x0)
1384005224.7730 [io/chr-um6                    #                    ] 
1384005224.7730 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 6
1384005224.7730 [io/chr-um6                    #                    ]  * make_packet (0xaf, Command, 0x0)
1384005224.7731 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:af:02:00  should write 7, wrote 7
1384005224.7745 [io/chr-um6                    #                    ] SERIAL --> 73:6e
1384005224.7746 [io/chr-um6                    #                    ] SERIAL --> 70:00
1384005224.7747 [io/chr-um6                    #                    ] SERIAL --> af:02
1384005224.7749 [io/chr-um6                    #                    ] SERIAL --> 00
1384005224.7749 [io/chr-um6                    #                    ]  * process_packet (0xaf, failed=0, has_data=0, data=0x0)
1384005224.7750 [io/chr-um6                    #                    ] 
1384005224.7750 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 7
1384005224.7750 [io/chr-um6                    #                    ]  * make_packet (0xb0, Command, 0x0)
1384005224.7751 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:b0:02:01  should write 7, wrote 7
1384005224.7765 [io/chr-um6                    #                    ] SERIAL --> 73
1384005224.7766 [io/chr-um6                    #                    ] SERIAL --> 6e:70
1384005224.7767 [io/chr-um6                    #                    ] SERIAL --> 00:b0
1384005224.7769 [io/chr-um6                    #                    ] SERIAL --> 02:01
1384005224.7769 [io/chr-um6                    #                    ]  * process_packet (0xb0, failed=0, has_data=0, data=0x0)
1384005224.7769 [io/chr-um6                    #                    ] 
1384005224.7769 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 8
1384005224.7769 [io/chr-um6                    #                    ]  * make_packet (0xac, Command, 0x0)
1384005224.7770 [io/chr-um6                    #                    ] SERIAL <-- 73:6e:70:00:ac:01:fd  should write 7, wrote 7
1384005224.7785 [io/chr-um6                    #                    ] SERIAL --> 73
1384005224.7786 [io/chr-um6                    #                    ] SERIAL --> 6e:70
1384005224.7787 [io/chr-um6                    #                    ] SERIAL --> 00
1384005224.7788 [io/chr-um6                    #                    ] SERIAL --> ac:01
1384005224.7789 [io/chr-um6                    #                    ] SERIAL --> fd
1384005224.7790 [io/chr-um6                    #                    ]  * process_packet (0xac, failed=0, has_data=0, data=0x0)
1384005224.7790 [io/chr-um6                    #                    ] Gyros zeroed.
1384005224.7790 [io/chr-um6                    #                    ] 
1384005224.7790 [io/chr-um6                    #                    ] NEXT INITIALIZATION STEP 9
1384005225.8063 [io/chr-um6                    #                    ] SERIAL --> 73:6e:70:c8
1384005225.8064 [io/chr-um6                    #                    ] SERIAL --> 0b:ff
1384005225.8068 [io/chr-um6                    #                    ] SERIAL --> e3:00:1c:00:07
1384005225.8069 [io/chr-um6                    #                    ] SERIAL --> 00
1384005225.8071 [io/chr-um6                    #                    ] SERIAL --> 00:04:29
1384005225.8072 [io/chr-um6                    #                    ]  * process_packet (0xb, failed=0, has_data=1, data=0xffe3001c)
1384005225.8072 [io/chr-um6                    #                    ] Unhandled address 0xb.
1384005225.8072 [io/chr-um6                    #                    ]  * process_packet (0xc, failed=0, has_data=1, data=0x70000)
1384005225.8073 [io/chr-um6                    #                    ] Unhandled address 0xc.




I’m from CH Robotics and can help out.

The UM6 and the UM6-LT don’t typically behave in the manner that you describe - when we connect to and test the UM6 using our Serial Interface Software, the very first operation performed is to read the firmware revision, and we don’t see bad checksum packets. We also issue commands to zero the rate gyros and don’t typically see bad checksums.

It is possible that the USB-TTL cable that you are using could be part or all of the problem. We haven’t tried that particular cable, but we have found that some converters have a hard time keeping up and sometimes drop one or more bytes during transmission. If the behavior you describe persists even at much lower baud rates, it seems less likely that the cable could be the source of the problem, but it is worth looking at in either case.

There is no delay required before sending commands to the sensor.

From the logic analyzer images that you posted, it looks like there is a lot of noise on the TX line - almost 1V in amplitude. Is this caused by the USB-serial cable? That could conceivably be causing problems as well.

Wow, great. Thank you for your response.

Yes, that noise looks like 200 kHz (as measured by a scope) sawtooth from the USB cable. There are also under+overshots and noise on the second line, when other is switching. I measured it to last about 17 ns (screenshots), do you think they could be problem here? Do you know maybe how to eliminate them properly?

Since you suggested that the cable really might be an issue, I have taken my time to finally configure UARTs on my Beaglebone Black (ehh, it wasn’t so straightforward, especially that I’m not using default’s distribution but Archlinux instead, but I had to do this eventually :wink:), to see how it behaves when it’s connected to the board. On BBB I don’t have any 200 kHz noise, but there are still under and overshots. As for actual test, the result is the same: always first GET_FW_VERSION packet is reported as with bad checksum, then second one works perfectly.




Do you think it’s safe to downgrade firmware to version UM2A from UM2B? I’d like to check if it works with that.

I also ran Windows for a moment to see what the Serial Interface does, when it talks to the sensor, and it seems that it just repeats failed command. This workaround seems to work perfectly, so I’ll do this in my driver, too. :wink: But I also noticed something strange, when I press “connect”, it sends following bytes to the sensor: { 0x3a, 0x62, 0x0d, 0x0a } repeated 3 times (screenshot attached). Why is it doing this? This shot is from USB-UART cable:


Yes, I have tried with slower speeds, but it’s a bit of hassle to disable broadcasting, switch them, save to flash, etc, so I just did that once with 9600, to see if that would help, but it didn’t. I’d like to stay at 115200 for “production”, anyway. (“production” = one piece of flying machine :wink:)

As for now, I’m partially happy with my driver just repeating commands upon receiving BAD_CHECKSUM. Everything else just works and sensor sends valid data, so if I can’t fix it completely, I’ll stay with what I have.

Regards,
Michał