|
RDM General Implementation Discussion General Discussion and questions relating to implementing RDM in a product. |
|
Thread Tools | Search this Thread | Display Modes |
January 12th, 2022 | #1 |
Junior Member
Join Date: Jan 2022
Posts: 4
|
Discovery response not recognized
I am developing a new lighting device, and need to implement the RDM protocol. I am new to DMX and RDM, but I have the DMX working fine. I am having a problem getting the controller that I am using to recognize my response to the discovery message.
I'm using an ENTTEC USB PRO MK2 for testing, and am trying to get it to recognize my board in the RDM discovery process. It is not seeing my responses to the DISC_UNIQUE_BRANCH message, and I'm not sure why. I can see my response on the RS485 bus using a scope. I know it is seeing my response, because it is continuing to send discovery messages with a narrowing range of IDs, so it thinks there is a collision on the bus. I'm thinking that my checksum is not correct? I saw two examples of source code on the web for this, and they both use the same algorithm to encode the response. However, in looking at the protocol document (ANSI E1.20), there is a disconnect somewhere. Here is the suggested code from the web to send a response: _rdmCheckSum = 6 * 0xFF; for (byte i = 0; i < 7; i++) disc->headerFE[i] = 0xFE; disc->headerAA = 0xAA; for (byte i = 0; i < 6; i++) { disc->maskedDevID[i+i] = _devID[i] | 0xAA; disc->maskedDevID[i+i+1] = _devID[i] | 0x55; _rdmCheckSum += _devID[i]; } disc->checksum[0] = (_rdmCheckSum >> 8) | 0xAA; disc->checksum[1] = (_rdmCheckSum >> 8) | 0x55; disc->checksum[2] = (_rdmCheckSum & 0xFF) | 0xAA; disc->checksum[3] = (_rdmCheckSum & 0xFF) | 0x55; I have two issues with this. 1. Why do they initialize the checksum to 6 * 0xFF instead of zero? 2. The checksum should be adding the actual bytes sent after they are ORed, not the original bytes. So, I tried changing it to this, to comply with the protocol: _rdmCheckSum = 0; for (byte i = 0; i < 7; i++) disc->headerFE[i] = 0xFE; disc->headerAA = 0xAA; for (byte i = 0; i < 6; i++) { u32 idx = i+i; disc->maskedDevID[idx] = _devID[i] | 0xAA; _rdmCheckSum += disc->maskedDevID[idx]; idx++; disc->maskedDevID[idx] = _devID[i] | 0x55; _rdmCheckSum += disc->maskedDevID[idx]; } disc->checksum[0] = (_rdmCheckSum >> 8) | 0xAA; disc->checksum[1] = (_rdmCheckSum >> 8) | 0x55; disc->checksum[2] = (_rdmCheckSum & 0xFF) | 0xAA; disc->checksum[3] = (_rdmCheckSum & 0xFF) | 0x55; but I still don't get a MUTE message saying that the controller sees my response. Thanks for any help you can provide! |
January 13th, 2022 | #2 |
Task Group Member
Join Date: Aug 2008
Posts: 379
|
You can use this EUID calculator to see if the conversion is being done correctly.
http://rdm.openlighting.org/tools/uid-converter The converter is bidirectional, so you can enter your UID and see the expected EUID. You can also dump the EUID from the wire and decode it. |
January 13th, 2022 | #3 |
Junior Member
Join Date: Jan 2022
Posts: 4
|
Thanks for that link, ericthegeek.
It confirms that my re-write has the correct data. However, I'm still not getting a "MUTE" reply, the controller is just continuing to narrow the address range, thinking there is a collision. It really helps to rule that out. Now that I know that the data is correct, I can start looking at a possible hardware problem. The signal on my scope showing my output data does look a little weird. Any idea why the example software has those changes? -Like initializing the checksum to non-zero.. |
January 13th, 2022 | #4 |
Administrator
|
Welcome to the forums!
A couple random thoughts of things I've ran into before to also check: - Could be a timing issue in the response. Make sure everything is within the right timing window. - You might need to leave some additional time between sending the packet and shutting off the Tx drive. It is super easy to disable TX before the packet has fully been sent chopping off some bits at the end and causing the behavior you are seeing. Scott
__________________
Scott M. Blair RDM Protocol Forums Admin |
January 13th, 2022 | #5 |
Task Group Member
Join Date: Aug 2008
Posts: 379
|
Look at the 485 data on the wire with a scope and decode it. Then you can see what's actually being sent, not what you think you're sending. As Scott said, turning off Transmit Enable prematurely is a common problem. You need to wait for the shift register to finish sending the byte, not for the "TX FIFO empty" interrupt.
I ran the reference code you found through a C compiler and it does produce the correct output. It has some clever boolean optimizations to reduce the work at runtime. For example: If you add 0xAA and 0x55, you get 0xFF. If you add (0xAA.or.VALUE) to (0x55.or.VALUE) you get 0xFF+VALUE. Do this six times (for each byte of the UID), and you see why it init's the checksum to 6 * 0xFF. Last edited by ericthegeek; January 13th, 2022 at 11:30 AM. Reason: spelling correction |
January 13th, 2022 | #6 |
Junior Member
Join Date: Jan 2022
Posts: 4
|
Thanks so much for your responses, Scott and ericthegeek..
I found the problem, it was a bad ground on my RS485 driver chip! I did try adding a delay after sending the packet before enabling the receive, but that was allright, I am waiting till the Tx buffer is empty first. Anyway, I still have the question about the checksum initialization. ericthegeek, I understand what you said that 6 * 0xFF is the same as adding the header bytes, but the header isn't supposed to be included in the discovery response checksum! I am now getting a "MUTE" instruction addressed to my UID after discovery after initially setting the checksum to zero. Thanks again, this is a great forum! |
January 13th, 2022 | #7 | |||
Task Group Member
Join Date: Aug 2008
Posts: 379
|
Quote:
Quote:
The 6 * 0xFF isn't from the header (the header is 0xFE, not 0xFF). Each byte of the UID is Boolean OR'd with 0xAA and 0x55. We've established that (0xAA.or.VALUE)+(0x55.or.VALUE) == 0xFF+VALUE. If you expand that out 6 times, once for each byte of the EUID you get: (0xFF+UID_5)+(0xFF+UID_4)+(0xFF+UID_3)+(0xFF+UID_2)+(0xFF+UID_1)+(0xFF +UID_0) That can be simplified to (6*0xFF)+UID_5+UID_4+UID_3+UID_2+UID_1+UID_0, which is the calculation that's done on that code snippet. Whoever figured out that simplification is clearly smarter than I am. Quote:
That's why we're here. The goal is to keep RDM developers on track and to help improve interoperability for everyone. It's often worth browsing through older threads too, it can help you avoid many of the common pitfalls. |
|||
January 13th, 2022 | #8 |
Administrator
|
And that is exactly why I don't try to be clever in my code. I'll just end up confusing myself later. I don't recommend trying to be too smart in your code. Eric is one of the more brilliant people I know. If the code is trying to be too clever for him, then it's too clever for most anyone.
__________________
Scott M. Blair RDM Protocol Forums Admin |
January 13th, 2022 | #9 |
Junior Member
Join Date: Jan 2022
Posts: 4
|
Thanks, that actually makes sense now. But I absolutely agree that getting too tricky (to save a processor cycle or two) usually makes for un-decipherable code in the future.
|
Bookmarks |
Thread Tools | Search this Thread |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Discovery response format | FishFood6 | RDM General Implementation Discussion | 5 | November 19th, 2020 07:15 AM |
Discovery Response Preamble | prwatE120 | RDM General Implementation Discussion | 0 | January 20th, 2007 01:22 AM |