Mega 2560 questions about hardware timer in fast-pwm-mode to create a DCC-bitstream

Microcontroller Arduino Mega 2560:

A DCC-signal has this kind of bitvalue encoding like shown in the picture
DCCSIG

A bit-value of 1 is encoded into a 50%-duty-cycle with 58µsec HIGH and 58 µsec LOW
A bit-value of 0 is encoded into a 50%-duty-cycle with 100µsec HIGH and 100 µsec LOW

Is there a special name for this way of bitvalue-econding?
.
.
A hardwaretimer inside the Mega 2560 can be configured to fast-pwm-mode.

First I want to describe it in general words without using the register-names.

My understanding of the fast-pwm-mode so far is:

The counter-register continuosly counts up from zero to a max-value and then is reset to zero.
Resetting the counter-register to zero can be triggered by different registers.

What these different kinds of resetting the counter-register have in common is:
If the allways counting up counter-register-value matches the value of configuration-register then the counter-register will be reset to zero.

If all involved registers are configured in the correct way.
The hardware-timer will switch the configured IO-pin LOW/HIGH
without a single line of code
= independent creation of the PWM-signal.

As the DCC-signal needs
a cycle-time of 116 µseconds for a bitvalue 1 (58 µsecs HIGH / 58 µsecs LOW)
and
a cycle-time of 200 µseconds for a bitvalue 0 (100 µsecs HIGH / 100 µsecs LOW)

The values inside the registers that control the cycle-time must be changed each time
the bitvalue changes.

As there can be any kind of bitpattern where at each bit-position there can be a 1 or a 0
each and every bit must be checked for its value beeing 1 or 0
and then setting register-values to make the "PWM-module" create a cycletime of 116 µseconds or 200 µseconds

The point in time to set the new cycle-time (116 µsec or 200 µsec) is always the end of each cycle.

This means the interrupt-control-registers must be configured to invoke an interrupt each time when a single pwm-cycle has finished.

The ISR-function takes the next bit of the DCC-message and sets that registers of the hardware-timer that control the cycle-time.

example send a byte with values 10011011

76543210
10011011

take bit 0 which has value 1 => set cycletime to 116 µseconds
if 116 µseconds have passed by an interrupt is invoked and the ISR-code does

take bit 1 which has value 1 => set cycletime to 116 µseconds
if 116 µseconds have passed by an interrupt is invoked and the ISR-code does

take bit 2 which has value 0 => set cycletime to 200 µseconds
if 200 µseconds have passed by an interrupt is invoked and the ISR-code does

take bit 3 which has value 1 => set cycletime to 116 µseconds
if 116 µseconds have passed by an interrupt is invoked and the ISR-code does
....
take bit 7 which has value 1 => set cycletime to 116 µseconds
if 116 µseconds have passed by an interrupt is invoked and the ISR-code does

After sending bit 7 one byte is send.
If message has mutliple bytes take next byte, reset bitcounter to 0
repeat processing all bits from bit 0 to bit 7

As switching of the IO-pin is done on the event

"value of counter-register matches some other register"

changing the value of the "match"-register right at the start of a cycle will work for pwm-frequencies that are not too high.

Example:

pwm-frequency results in a matchvalue of 1000
right at the beginning of a cycle the counter-register has value 0

now executing the commands for changing the cycletime needs some time
after this execution-time the counter-register (which is free running always counting up)
has reached value 350 which is below 1000

changing the match-value to 1500 is done before the matching is reached

result: cycletime longer

for changing the "match"-value back from 1500 to 1000 there is even more time
And as executing the code for changing the "match"-value takes only 350 counts

this works.

And using a single interrupt always invoked at the end of a pwm-cycle is sufficient to make it work.

Is this a correct description so far?

FSK (Frequency Shift Keying)

IMO too long and complicated. Both TOP and MATCH have to be changed for a frequency shift, where MATCH (OCRnn) is half the TOP value.

It's important that the registers are updated at the right time, different for OCRnA and ICRn. ICRn is updated immediately, while OCRnA is double buffered and updated only when TOP is reached.

1 Like

Maybe link to:

Hi @DrDiettrich

thank you very much for answering my question.

The pulse-train picture is taken from the wikipedia-site.
Though IMHO the wikipedia-website offers not much more additional information except some links.

May main focus is on getting feedback if my general worded description of how to create the bitstream by using a hardwaretimer in fast-pwm-mode is correct so far
or
if I have some misunderstandings

Main sources are the NMRA standard papers, which can be found here.
S-9.x are for the electrical standards, including DCC electrical and communication standards.

Hi @MicroBahner

thank you very much for adding links to information about the NMRA standards.

As you have already mentioned the timing must be very precise.

So my main question is:

Does the description that I have posted in the first post describe the basic principle of how to use the hardware-timer in fast pwm-mode correctly ?

The most simple answer would be the single word "yes" or the single word "no"

Any expansions on a single word "yes" or "no" much appreciated.

Or if my description is totally or partially wrong to correct my description.

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