DIRECTION_PIN not resetting after RDM response

Questions concerning any LXSeries open source projects.
Comments and requests can also be posted on GitHub.
xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

DIRECTION_PIN not resetting after RDM response

Postby xldaedalus » Sun Jul 17, 2022 12:17 am

As mentioned, something about the RDM packet is not being recognized by the DMXit.

The bigger problem is, the DIRECTION_PIN is not resetting to LOW, so that the SAMD21 can't "listen" to further data.

I can see that you have a transmissionComplete() function where in

...
} else if ( _dmx_send_state == DMX_STATE_IDLE ) { //after data completely sent
if ( _rdm_task_mode == DMX_TASK_SEND_RDM )

you set the DIRECTION_PIN LOW

But something is preventing this after the RDM packet is sent by the SAMD21. Since I can't step through the code to see what's going wrong, can you please offer some suggestions?

Thanks.

admin
Site Admin
Posts: 114
Joined: Mon Nov 20, 2017 4:31 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby admin » Sun Jul 17, 2022 12:31 pm

I'm not sure how you know that the direction pin is not low. The way to do this accurately is with a logic probe and that is how you have to see what is going on. Use some extra pins and set them high/low in the code and then trace the timing with the logic probe. It takes a while because you'll capture a lot of data. But, you can eventually find the moment you are looking for.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby xldaedalus » Sun Jul 17, 2022 11:31 pm

I'm using an oscilloscope and double checking with a logic probe, in case DIRECTION_PIN sets low several seconds after the transmit, and the oscope isn't catching it returning to LOW.

In this part of the code

if ( pid == RDM_DISC_MUTE ) {
if ( destination == SAMD21DMX.THIS_DEVICE_ID ) {
// discovery_enabled = 0; //<-------------- comment out here
// send ACK
// UID source;
// source.setBytes(&rdmdata[RDM_IDX_SOURCE_UID]);
// SAMD21DMX.sendMuteAckRDMResponse(RDM_DISC_COMMAND_RESPONSE, source, RDM_DISC_MUTE); // to here

}

I can see on the oscope the DIRECTION_PIN going HIGH and LOW as it should @ 1ms. The return UID is sent 10 times as follows. I see all 10 pulses of the DIRECTION_PIN going HIGH and LOW

CC0124FFFFFFFFFFFF43540000000032010000001000010C000000000000FFFFFFFFFFFF0DCCFEFEFEFEFEFEFEAAEE7DFA7DAF5FAA5FAE5DAE5FAF57BB550000
CC01186C780F0A0C0E43540000000033010000001000020002D900
CC01186C780F0A0C0E43540000000034010000001000020002DA00
CC01186C780F0A0C0E43540000000035010000001000020002DB00
CC01186C780F0A0C0E43540000000036010000001000020002DC00
CC01186C780F0A0C0E43540000000037010000001000020002DD00
CC01186C780F0A0C0E43540000000038010000001000020002DE00
CC01186C780F0A0C0E43540000000039010000001000020002DF00
CC01186C780F0A0C0E4354000000003A010000001000020002E000
CC01186C780F0A0C0E4354000000003B010000001000020002E100
CC01186C780F0A0C0E4354000000003C010000001000020002E200
CC0124FFFFFFFFFFFF4354000000003D010000001000010C000000000000FFFFFFFFFFFF0DD7FEFEFEFEFEFEFEAAEE7DFA7DAF5FAA5FAE5DAE5FAF57BB550000

And both the DMXit Discovery CMD and the RDMserial Test repeat endlessly.

When I uncomment the same code I get something like

CC0124FFFFFFFFFFFF43540000000048010000001000010C000000000000FFFFFFFFFFFF0DE2FEFEFEFEFEFEFEAAEE7DFA7DAF5FAA5FAE5DAE5FAF57BB550000
CC01186C780F0A0C0E43540000000049010000001000020002EF00

after which DIRECTION_PIN remains HIGH and nothing happens.

I've managed to get RDMDeviceTest_SAMD21 running as .cpp on PlatformIO, and its a lot easier to jump around to all the code, I'm rechecking the DIRECTION_PIN function as PIO caught an error that Arduino IDE did not.

// ***************** input callback function *************

void gotDMXCallback(int slots) {
got_dmx = slots;
}

void gotRDMCallback(int len) {
// rdm start code and checksum are validated before this is called
got_rdm = len;
}

was not in the correct place - due to my own mistake. However, PIO is reporting an error here

SAMD21DMX.setDataReceivedCallback(&gotDMXCallback); //gotDMXCallback this is defined
SAMD21DMX.setRDMReceivedCallback(&gotRDMCallback); // <-- error identifier "gotRDMCallback" is undefinedC/C++(20)

Yet I can see it is defined in the code, as can you. I tried changing (int len) to (int RDMlen) as len is a common variable name in string maniputlation. For what its worth, in PIO, (int slots), the word slots is light blue, yet (int len) is white. I'll try to post a pix. The code compiles, even with this error, but maybe its part of the problem.

RDMcallbackError.jpg
RDMcallbackError.jpg (147.45 KiB) Viewed 333 times

admin
Site Admin
Posts: 114
Joined: Mon Nov 20, 2017 4:31 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby admin » Mon Jul 18, 2022 2:02 pm

I think this is a c++ issue. I'm not sure why the syntax coloring but that's probably a clue if you can figure out what it means. Arduino IDE simplifies c++ for the sketch. One of the things it does is to not require function templates. In regular c/c++ these are in the header (.h) file and the function definition is in the .c or .cpp file. You can legally have the function template followed by the function itself:

Code: Select all

// callback functions
void gotDMXCallback(int slots);
void gotRDMCallback(int len);


setup() {
   ...
   SAMD21DMX.setDataReceivedCallback(&gotDMXCallback);
   SAMD21DMX.setRDMReceivedCallback(&gotRDMCallback);
   ...
}

void gotDMXCallback(int slots) {
  got_dmx = slots;
}

void gotRDMCallback(int len) {
  // rdm start code and checksum are validated before this is called
  got_rdm = len;
}


I don't believe that the name of the function parameter makes a difference, unless that name is a global variable somewhere else in your code. So, using len as the parameter to gotRDMCallback should not have any conflict with any library functions as the scope is limited to gotRDMCallback. One reason that RDMlen might be colored differently is that it is used as a global variable in another place outside of the gotRDMCallback definition. And that could make a difference.

admin
Site Admin
Posts: 114
Joined: Mon Nov 20, 2017 4:31 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby admin » Mon Jul 18, 2022 2:05 pm

There is a reply about the direction pin at the end of the previous topic:


It is possible that the interrupt handler is not getting called. You can try changing

Code: Select all

DMX_SERCOM->USART.INTENSET.reg =  SERCOM_USART_INTENSET_TXC | SERCOM_USART_INTENSET_ERROR;


to

Code: Select all

DMX_SERCOM->USART.INTENSET.reg =  SERCOM_USART_INTENSET_TXC | SERCOM_USART_INTENSET_ERROR | SERCOM_USART_INTENSET_DRE;


in LXSAMD21DMX.cpp line 450 in sendRawRDMPacket() to insure that the interrupt trips and the outgoing RDM is sent.

This would involve restoring the lines you commented out which are responsible for sending a reply to the RDM tester's query. Without sendMuteAckRDMResponse, the tester will never know your device is there.

I don't know a downside to doing this. It is possible that there was a leftover interrupt that triggered the handler when the example was first tested. But, this was just by chance, rather than a guarantee that the interrupt is tripped every time sendRawRDMPacket() is called.

Also, there is a wait loop at the end of sendRawRDMPacket() and you can set a pin or some other debugging device to see if the code ever gets past that loop.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby xldaedalus » Mon Jul 18, 2022 10:58 pm

Thank you very much. I like the PlatformIO IDE better than the Arduino IDE because its easier to explore the underlying code, easier to find where things are defined. I can go back and forth between IDEs when I get to developing my own library of RDM responses. I I'm sure there are other differences I haven't found yet. I don't know that much yet about C and C++. So I apologize for asking stupid questions. I will give your suggestion a try.

Sorry, this might be a dumb question, but when the RDMDevicetester forms a response to the Master Device, shouldn't the "Destination UID" be that of the Master. This is the RDMDeviceTest I captured.

RDMDevice Test SEND packet to discovery CMD (LXSAMD21DMX = 6C78 Manufacturer ID Claude Heinz Design)
(values in HEX 2 ascii character together = hex value. ie CC = 0xCC 6C78 = 0x6C78, so, value F = 0F = 0x0F)

CC01186C780F0A0C0E4354000000002E010000001000020002D400

CC = Start code
01 = Substart code
18 = # of bytes to follow 18hex = 24 bytes
6C78:0F0A0C0E = Destination UID <----- Since 6C78:0F0A0C0E is sending this message shouldnt "Destination" be 4354:00000000
4354:00000000 = Source UID <---- In other words, RDMDevicetester should reverse Destination and Source UID's?
2E = Transaction #
01 = Port ID / response
00 = Message count
00 00 = Root Device
10 = command class
00 02 = Parameter ID
00 = parameter data length <--- if parameter data is 0x02 shouldn't parameter data len = 0x01?
02 = parameter data
D5 = Checksum HIGH
00 = Checksum LOW

Discovery CMD from the MASTER (DMXit 4354 Manufacture ID City Theatrical)
CC0124FFFFFFFFFFFF43540000000032010000001000010C000000000000FFFFFFFFFFFF0DCCFEFEFEFEFEFEFEAAEE7DFA7DAF5FAA5FAE5DAE5FAF57BB550000
CC = Start code
01 = Substart code
24 = # of bytes to follow 24hex = 36 bytes
FFFF:FFFFFFFF = Destination UID
4354:00000000 = Source UID <--- Master, Source = sender of packet??
32 = Transaction #
01 = Port ID / response
00 = Message count
00 00 = Root Device
10 = command class
00 01 = Parameter ID
0C = parameter data length 12 bytes
000000000000FFFFFFFFFFFF = parameter data
>>not sure how the rest of the Discovery Packet goes yet<<

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby xldaedalus » Tue Jul 19, 2022 12:43 am

I tried your suggested code change. It doesn't seem to make a difference. And the PlatformIO does compile but nothing works at all. And I think its because it is still listing as errors the two Callback functions. I don't know enough yet to be able to fix it. I tried declaring them in LXSAMD21DMX.h but that created different errors. So I made the code change you suggested to LXSAMD21DMX.cpp with Xcode and compiled with Arduino IDE. Either way looks like as below. I think what might be happening is that the return Discovery packet is being sent, and something about the follow up mute function(s), is where the my program is sticking the DIRECTION_PIN on - it happens 3mS after the RDMDeviceTest sends its Discovery response. Trying to figure out how to add debugging pin toggles in LXSAMD21DMX.cpp
DIRECTION_PIN.jpg
DIRECTION_PIN.jpg (109.51 KiB) Viewed 327 times
.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby xldaedalus » Tue Jul 19, 2022 5:40 am

FYI I set up debug pin toggles as you suggested in at the WAIT loop at the end of LXSAMD21DMX::sendRawRDMPacket( uint8_t len )

There was no pulse. I checked the pulse code elsewhere and it works on the oscope. But I see the RDMDeviceTest packet being sent. There is a notation in the definition of the function: // only valid if connection started using startRDM()

So maybe the first response is sent other way?

digitalWrite(PIN_A4, !digitalRead(PIN_A4)); // Starts LOW, this sets HIGH ##_DEBUG_##
delay(1);
while ( _rdm_task_mode ) { //wait for packet to be sent and listening to start

delay(1); //_rdm_task_mode is set to 0 (receive) after RDM packet is completely sent
}
digitalWrite(PIN_A4, !digitalRead(PIN_A4)); // HIGH toggles to LOW - should create a 1 or 2mS pulse on Pin 18 ##_DEBUG_##

Investigating further with debug pin.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby xldaedalus » Tue Jul 19, 2022 6:07 am

Correction. The above tests were made with the code change you suggested. Of course, I may have typed it wrong.

DMX_SERCOM->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC | SERCOM_USART_INTENSET_ERROR | SERCOM_USART_INTENSET_DRE;

and, as above, the pin did not toggle. I change the code back to your original

DMX_SERCOM->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC | SERCOM_USART_INTENSET_ERROR;

Now pin toggles, so I made the following change

while ( _rdm_task_mode ) { //wait for packet to be sent and listening to start
digitalWrite(PIN_A4, !digitalRead(PIN_A4)); // ##_DEBUG_##
delay(1);
digitalWrite(PIN_A4, !digitalRead(PIN_A4)); // ##_DEBUG_##
delay(1);

// delay(1); //_rdm_task_mode is set to 0 (receive) after RDM packet is completely sent
}
digitalWrite(PIN_A4, LOW); // last line before exiting ##_DEBUG_##

Now, the pin toggles HIGH to LOW in 1ms pulses for about 350ms before finishing LOW sometimes, finishing HIGH other times, which seems to indicate it never reaches the last line which could set if LOW for sure. This would indicate that the program is sticking in this WHILE loop, leaving the DIRECTION_PIN stuck HIGH.
Attachments
DEBUG_PIN WHILE _rdm_task_mode.jpg
DEBUG_PIN WHILE _rdm_task_mode.jpg (71.7 KiB) Viewed 327 times

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: DIRECTION_PIN not resetting after RDM response

Postby xldaedalus » Wed Jul 20, 2022 6:01 am

Investigating further, I put a debug pin toggle in this interrupt

void LXSAMD21DMX::byteReceived(uint8_t c) {

It captured 24 bytes - I counted with pin toggles HIGH->LOW for each interrupt on the Oscope. 48uS between rising edges, each toggle 2us, except the last, which was 8us

That corresponds to the 24byte response packet being "sent" by the RDMDeviceTest - itself.
CC01186C780F0A0C0E4354000000002E010000001000020002D400

This doesn't make sense to me. How and why would a function "byteReceived" be capturing what is being sent, unless it is your intent to capture what is being sent to make sure it is correct?

It seems to me it should have "received" the discovery command from the DMXit, or 36bytes captured by the RS485 line monitor.
CC0124 FFFFFFFFFFFF 435400000000 32 01 00 0000 10 0001 0C 000000000000FFFFFFFFFFFF 0DCCFEFEFEFEFEFEFEAA EE7DFA7DAF5FAA 5FAE5DAE5FAF57BB55 000

I double checked my connections are correct Rx(31-SER5:3) and Tx(30 SER-5:2) Is it possible the SERCOM the pins or pads are reversed or otherwise wrong? Or is this how SERCOM works?
byteReceiveInterrupt.jpg
byteReceiveInterrupt.jpg (158.98 KiB) Viewed 322 times