NMRADCC utilisation

Hello everyone,
I try to use NMRADCC with my own central sation (currentlly operating on esp32). Everything is working well but when I want to use NMRADCC to read the packets for accessories I get an issue. For example, instead of reading the address 167, NMRADCC function reads 665.
I am sending the message 11111111111111111111 0 10100111 0 11011001 0 01111110 1
so 167 = 010100111 (101 is the complement of 010 in the second octet 10100111)
thanks for your help

#include <NmraDcc.h>

#define DCC_PIN 2

NmraDcc Dcc;

void notifyDccAccTurnoutOutput(uint16_t Addr, uint8_t Direction, uint8_t OutputPower) {

  Serial.print("Addr: ");Serial.print(Addr);
  Serial.print("Direction: ");Serial.print(Direction);
  Serial.print("OutputPower: ");Serial.print(OutputPower);
  Serial.println("-----------------------------");
  
}


void setup() {
Serial.begin(115200);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
 Dcc.pin(digitalPinToInterrupt(DCC_PIN),DCC_PIN, false);
Dcc.init( MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0 );

}

void loop() {
  Dcc.process();


}

How is this an Installation & Troubleshooting - Arduino Forum issue ??

Moved to a more appropriate sub forum.

Please do yourself a favour and please read How to get the best out of this forum and post accordingly (including code tags and necessary documentation for your ask).

Addressing of accessories is a bit tricky, because there are different possibilities to interpret the adressing information in a DCC packet: decoder addressing and output addressing.
Decoder addressing is based on the old turnout decoders, that could address 4 turnouts with one decoder. With this decoding the address information is split in two parts: The decoder address, and the turnout address within the decoder. This is what you do with your address computing with the result '167' ( omitting the turnout address within the decoder, bit 1 and 2 of the second octett ).

But when you use the notifyDccAccTurnoutOutput() call back, the address is interpreted differently. This callback uses output addressing. All turnouts are numbered sequentially, independent of a decoder address. The output address is (nearly) 4 times the decoder address. 'Nearly' because most central stations don't use the decoder address '0'. In this case the (binary)turnout addresses 0..3 are not used, therefore the output address is (decoderaddress*4) -3.
And that is what you get: 167*4-3 = 665.

Thanks a lot MicroBahner.
Do you know if there is a way to get 167? Do I need to change the packet format?
Thanks

The packet format is always the same. It's only a matter of interpreting it. If you want to use decoder addressing don't set the flag CV29_OUTPUT_ADDRESS_MODE when calling Dcc.init() and use the callback notifyDccAccTurnoutBoard() instead of notifyDccAccTurnoutOutput()

NB: If you have programmed your own central unit, you should use the same addressing scheme for the central unit as for the decoder. This would avoid confusion in the addresses. In my opinion Decoder addressing only makes sense if you also use corresponding decoders with 4 turnout outputs.

It s working!!!!!
Thanks a lot have a great day

Where can I find a detailed explanation for the constant we can use with the library NMRADCC?
FLAGS_DCC_ACCESSORY_DECODER
CV29_OUTPUT_ADDRESS_MODE
...etc
How can weuse them? What are their goals.
Thanks

The only documentation I know of are the comments in the NmraDcc.h file.
Most of the constants set bits in CV29 and thus influence the behaviour of the decoder. The meaning of these bits is described in the NMRA / NEM documents.

Thanks but I may have missed something what is the links between the bits in the Cv29 and the accessories? Thanks dor your time

My apologise. Bit 7!!!

Yes, that's it. Bit 7 in CV29 defines wether the decoder is a multifunction decoder ( for locomotives ) or an accessory decoder. The meaning of the other bits is dependent on this bit. Therefore you must tell the lib what type of decoder you want to use.

You can read about that in dokument s-9.2.2 of the NMRA, which defines all the CV values.

I see.
So for the dcc.init

(..,...,CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE,0)
Means that we put both bit 6 and 7 at 1?

I have seen some codes with

(...,..., FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER,0)

For the bits 29/541 put at 1 as well I guess?

What is the difference? What do you recommend?

Another question if I want to get the packets for locomotives and not only accessories what could I change?

I really appreciate the time you take for my very much naive questions. I am just a dummy and completly new in this area.

Thanks

As you can see from the NmraDcc.h:

    CV29_OUTPUT_ADDRESS_MODE = 0b01000000,	/** bit 6: "0" = Decoder Address Mode "1" = Output Address Mode */
    CV29_ACCESSORY_DECODER   = 0b10000000,	/** bit 7: "0" = Multi-Function Decoder Mode "1" = Accessory Decoder Mode */

and

#define FLAGS_OUTPUT_ADDRESS_MODE    0x40  // CV 29/541 bit 6
#define FLAGS_DCC_ACCESSORY_DECODER  0x80  // CV 29/541 bit 7

These defines are the same. I would prefer to use the FLAGS_... version, because these defines are meant for use in the init() Method. So you are sure if - for whatever reason - these may be defined differently in the future.

Well, the decoder must know what type it is, to interpret the packets correctly. But you can additionally get every packet as 'raw' packet with the

extern void    notifyDccMsg (DCC_MSG * Msg) __attribute__ ( (weak));

callback.

Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.