Results 1 to 18 of 18

Thread: DCC & PIC Microcontrollers

  1. #1
    Join Date
    Dec 2016
    Location
    Grass Valley CA, USA
    Posts
    114
    Thanks
    1
    Thanked 37 Times in 20 Posts
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    Default DCC & PIC Microcontrollers

    I'm trying to understand how to treat the DCC pulse train (you should pardon the expression) coming down the rails into something I can use to decode a single function from a PIC microcontroller (No arduino or other system, please). All I want to do is pick an unused DCC code on my system (say, just for random sake, 18) to give me a pulse output if that code comes down the line. What magic I do with it then is mine to play with. I"ve got a couple of REAL OLD (20 years ago) articles that don't really show what is going on, just some incomprehensible code that is SUPPOSED to work. No feedback on whether or not it does work.

    I've also got the NMRA standard on DCC. If I paid somebody to make the standard incomprehensible to the average moderately talented engineer, I doubt I could have found anybody to make it worse.

    On a completely different subject, has anybody ever tried to make a reflective train detection system with a pair of infrared LEDS with one output led modulated with an audio waveform and the other led used as a synchronous detector?

    Thanks,

    Jim

  2. #2
    Join Date
    Apr 2008
    Location
    Ashburn, VA, USA
    Posts
    1,137
    Thanks
    231
    Thanked 1,710 Times in 523 Posts
    Mentioned
    31 Post(s)
    Tagged
    0 Thread(s)

    Default

    I have code working on a PIC16 if that helps. I can share when back at a real keyboard.
    --
    Leo Bicknell

  3. #3
    Join Date
    Jan 2012
    Posts
    1,274
    Thanks
    1,970
    Thanked 1,720 Times in 715 Posts
    Mentioned
    44 Post(s)
    Tagged
    0 Thread(s)

    Default

    I'm not aware of any PIC DCC decoders, but there are bound to be quite a lot of them around

    The best documentation I've found is with the AVR-based (not Arduino, but not PIC either, I know) OpenDCC OpenDecoder: https://www.opendcc.de/elektronik/op...decoder_e.html - maybe that info can help you to adapt a PIC solution (or code fragments, whatever you find) to your needs.

    Have fun,
    Heiko

  4. The Following User Says Thank You to Heiko For This Useful Post:


  5. #4
    Join Date
    Sep 2013
    Location
    Fulton, NY
    Posts
    830
    Thanks
    938
    Thanked 1,268 Times in 446 Posts
    Mentioned
    42 Post(s)
    Tagged
    0 Thread(s)

    Default

    Back years ago, when I was just getting into the hobby, and DCC was just starting to become more popular, I did a ton of research into making my own decoders. While I eventually realized it was cheaper to just buy the decoders commercially for the small amounts I needed, I did find quite a bit of information. One such website offered DIY PIC based decoders: https://www.merg.org.uk/merg_resources/dcc_download.php

    Scroll down to decoders, there's information and code there.

    Andrew

  6. The Following 2 Users Say Thank You to conrailandrew For This Useful Post:


  7. #5
    Join Date
    Nov 2019
    Location
    Brunswick, Ohio
    Posts
    81
    Thanks
    38
    Thanked 206 Times in 69 Posts
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)

    Default

    Hi Jim,

    There's a lot of Arduino DCC decoder information and programming downloads for free on WWW.Model-Railroad-Hobbyist.com. My issues with it are the "black box" nature of using someone else's code in my project. That's a slight flaw in my character as I programmed in COBOL and BASIC for 43 years before retiring. I'm not a fan of C, so Arduino is not my first choice as a controller.

    I use Picaxe microcontrollers, based on PIC chips, in most of my projects because I don't need that much speed and it's far easier to program in Basic.
    Happy Modeling

    Bruce

  8. #6
    Join Date
    Jun 2014
    Posts
    786
    Thanks
    164
    Thanked 929 Times in 420 Posts
    Mentioned
    27 Post(s)
    Tagged
    0 Thread(s)

    Default

    I have a memory of the DCC signal line being read into the PIC
    from a line with a small capacitor.
    the cap is to isoate voltage I'd imagine...

    victor

  9. #7
    Join Date
    Dec 2016
    Location
    Grass Valley CA, USA
    Posts
    114
    Thanks
    1
    Thanked 37 Times in 20 Posts
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    Default

    Quote Originally Posted by bicknell View Post
    I have code working on a PIC16 if that helps. I can share when back at a real keyboard.
    Perfect. What I have in mind is to 3-d a bunch of small "switch houses" and "signal houses" near my switches and signals, use the code into an unused section of the PIC to perform the toggle function, and then drive an H-bridge with a timed pulse into the Kato switch. Or use part of the PIC to generate some 25 mA sonic pulses to modulate an IR LED and then see if I get enough "bounce" from a passing train to trigger a signal from green through yellow to red after the pulse train stops.

    Lots of stuff to play with going from profession to hobby.

    Thanks fer yer help ...

    Jim

  10. The Following User Says Thank You to jweir43 For This Useful Post:


  11. #8
    Join Date
    Apr 2008
    Location
    Ashburn, VA, USA
    Posts
    1,137
    Thanks
    231
    Thanked 1,710 Times in 523 Posts
    Mentioned
    31 Post(s)
    Tagged
    0 Thread(s)

    Default

    Doh. The code I uploaded was my first try on an Raspberry Pi. It’s at https://github.com/bicknell/rpi-dcc-decoder

    I do have working code on a PIC16. I will have to clean it up before I upload it though. The logic is almost the same...i made some minor improvements when I went over to the PIC. The RPi code may answer some of your questions though.
    --
    Leo Bicknell

  12. The Following 2 Users Say Thank You to bicknell For This Useful Post:


  13. #9
    Join Date
    Apr 2008
    Location
    Ashburn, VA, USA
    Posts
    1,137
    Thanks
    231
    Thanked 1,710 Times in 523 Posts
    Mentioned
    31 Post(s)
    Tagged
    0 Thread(s)

    Default

    Quote Originally Posted by jweir43 View Post
    I'm trying to understand how to treat the DCC pulse train (you should pardon the expression) coming down the rails into something I can use to decode a single function from a PIC microcontroller (No arduino or other system, please). All I want to do is pick an unused DCC code on my system (say, just for random sake, 18) to give me a pulse output if that code comes down the line. What magic I do with it then is mine to play with. I"ve got a couple of REAL OLD (20 years ago) articles that don't really show what is going on, just some incomprehensible code that is SUPPOSED to work. No feedback on whether or not it does work.
    Let me illuminate in text form first.

    The DCC pulse train is a series of 0's and 1's, formed by using different duration pulses. To feed this into a PIC, use either a high ohm resistor (e.g. 10kOhm) or a Opto-Isolator. The signal is inverted on the other rail, for most decoder applications just reading one rail is fine. Basically, rectify power off the line to power your circuit, and hook one rail into a GPIO using a resistor or Opto-Isolator. See my RPi schematic.

    For decoding, interrupt on the line going high. From there you can do one of two things:

    1) Also interrupt on the line going low, calculate the low to high pulse time.
    2) Set a timer for a time midway between the short pulse and long pulse time. If it goes off and the line is still high, you have a long pulse.

    Basically you've now captured the string of one's and zero's, all that's left is to see if it is a valid DCC message. My RPi code shows the state machine here. Watch for a pre-amble, 12 or more 1's followed by a zero, and then start tracking the message. It's going to be 2-5 bytes, and you know the last byte as it has a 1 in the 9th bit. After collecting that, you have your 2-5 byte message, now it's just a matter of decoding.

    The decoding is wonky, clearly when this was developed 7 bit machines were the norm, and there's a lot of well, just strange bit pattern choices. It's just a bunch of if/case statements at that point to break it into all the commands. In fact, I just noticed I need to upload new code. The code on my RPi can decode a LOT more than is in the GitHub code -- but the GitHub code pretty much shows how it is done.

    Of course, once you've decoded a particular message you want, you can then kick off whatever output is necessary.

    There are several folks out there with open-source code on various platforms that can be used as further reference.

    This page is particularly useful: https://www.opendcc.de/elektronik/op...decoder_e.html
    --
    Leo Bicknell

  14. The Following 3 Users Say Thank You to bicknell For This Useful Post:


  15. #10
    Join Date
    Dec 2016
    Location
    Grass Valley CA, USA
    Posts
    114
    Thanks
    1
    Thanked 37 Times in 20 Posts
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    Default

    Quote Originally Posted by BruceNscale View Post
    Hi Jim,

    There's a lot of Arduino DCC decoder information and programming downloads for free on WWW.Model-Railroad-Hobbyist.com. My issues with it are the "black box" nature of using someone else's code in my project. That's a slight flaw in my character as I programmed in COBOL and BASIC for 43 years before retiring. I'm not a fan of C, so Arduino is not my first choice as a controller.

    I use Picaxe microcontrollers, based on PIC chips, in most of my projects because I don't need that much speed and it's far easier to program in Basic.
    Yes, I agree. I teach my freshman MECH students MELabs PicBasic and use a straight PIC because the delivery times on PicAxe are horrible AND I prefer to compile rather than interpret. I particularly line the 16F688 because it is straighforward, no messing around goesintas and goesoutas -- nearly student bulletproof (if there is such a thing). Of course there is always one in the class who likes to reverse power supply polarity "just to see what happens".

    Jim

  16. The Following 2 Users Say Thank You to jweir43 For This Useful Post:


  17. #11
    Join Date
    Dec 2016
    Location
    Grass Valley CA, USA
    Posts
    114
    Thanks
    1
    Thanked 37 Times in 20 Posts
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    Default

    [QUOTE=bicknell;572626] In fact, I just noticed I need to upload new code. The code on my RPi can decode a LOT more than is in the GitHub code -- but the GitHub code pretty much shows how it is done.

    /QUOTE]

    Any update on the new code? The GitHub code is pretty obtuse.

    Thanks,

    Jim

  18. #12
    Join Date
    Feb 2013
    Location
    Sequim WA
    Posts
    3,587
    Blog Entries
    1
    Thanks
    12,103
    Thanked 5,674 Times in 2,186 Posts
    Mentioned
    146 Post(s)
    Tagged
    0 Thread(s)

    Default

    Quote Originally Posted by jweir43 View Post
    Of course there is always one in the class who likes to reverse power supply polarity "just to see what happens".
    And are they gleeful at having freed the magic smoke? Or does the chip just get extremely hot before surrendering?
    Paul Schmidt

    Shasta (2008-2020) -- All good dogs should live forever

    Southern Railway's Slate Fork Branch

    Check out Appalachian Railroad Modeling!

  19. #13
    Join Date
    Jun 2014
    Posts
    786
    Thanks
    164
    Thanked 929 Times in 420 Posts
    Mentioned
    27 Post(s)
    Tagged
    0 Thread(s)

    Default

    Quote Originally Posted by Paul Schmidt View Post
    And are they gleeful at having freed the magic smoke? Or does the chip just get extremely hot before surrendering?
    v-regs often pop. the pics usually melt when they find an alternate way to power up...
    I like the "spin a motor by hand" and toast a pin you didn't know was wan't protected by a diode...

    victor

  20. The Following User Says Thank You to victor miranda For This Useful Post:


  21. #14
    Join Date
    Feb 2013
    Location
    Sequim WA
    Posts
    3,587
    Blog Entries
    1
    Thanks
    12,103
    Thanked 5,674 Times in 2,186 Posts
    Mentioned
    146 Post(s)
    Tagged
    0 Thread(s)

    Default

    Quote Originally Posted by victor miranda View Post
    I like the "spin a motor by hand" and toast a pin you didn't know was wan't protected by a diode...
    Paul Schmidt

    Shasta (2008-2020) -- All good dogs should live forever

    Southern Railway's Slate Fork Branch

    Check out Appalachian Railroad Modeling!

  22. #15
    Join Date
    Apr 2008
    Location
    Ashburn, VA, USA
    Posts
    1,137
    Thanks
    231
    Thanked 1,710 Times in 523 Posts
    Mentioned
    31 Post(s)
    Tagged
    0 Thread(s)

    Default

    I haven't forgotten about this, but I am slow.

    I got my RPi set back up today and figured out where I left off. I do have a working track decoder that just dumps what I'm seeing (think tcpdump but for dcc). It's almost in a state where I can upload it too GitHub. I'll see if I can get to that sometime over the weekend.

    It's the same framework you'd need for making your own decoder -- rather than dumping every command it would just key off the commands the unit should react to and then do the custom action. And while it's RPi, not Arduino or PIC, the difference is actually quite minimal. The difference is just how you read the GPIO and determine how much time has passed, everything after that is generic across all platforms.
    --
    Leo Bicknell

  23. #16
    Join Date
    Apr 2008
    Location
    Ashburn, VA, USA
    Posts
    1,137
    Thanks
    231
    Thanked 1,710 Times in 523 Posts
    Mentioned
    31 Post(s)
    Tagged
    0 Thread(s)

    Default

    Alright, I spent a few minutes playing with my code and looking at output from my system. I also uploaded a few bug fixes.

    To get the code, go to https://github.com/bicknell/rpi-dcc-decoder

    I'm going to do a short walk-through here, and mention where things are the same, or different, for a PIC micro-controller. I don't have working PIC code I can share, but I hope to clean that up soon too. I really recommend starting on the RPi though, it's a much faster way to learn how it all works.

    Step #1, you need a hardware interface. https://github.com/bicknell/rpi-dcc-.../schematic.png has a circuit design for what I'm using with the RPi. I just have a small bread board with the components installed on it. One of the RPi connector to breadboard adapters is extremely helpful here. I like the opto-isolator method here as it's the safest, electrically speaking. For a PIC Micro-Controller the exact same method can be used, and in fact I use the same components with my PIC16.

    Step #2, the software needs to collect the timing pulses. DCC is a square wave signal, so the hardware above is basically going to give you a series of 1's and 0's on the GPIO pin, each with a different duration. Basically a DCC "one" is off-on-off where the on time is "short", and a DCC zero is off-on-off where the on time is "long", and can get really long because it is stretched. On the RPi the code uses the pigpio library to read the GPIO pin. Follow along here: https://github.com/bicknell/rpi-dcc-...r/dcc_decode.c

    Lines 510-525 set up the pigpio library. It triggers the "edges" function whenever there is a change in state (high or low) on the GPIO pin.

    Lines 526-549 are a forever loop that print some status data. I've commented out the debugging output. It still prints periodically the total number of DCC 1's, 0's, and out-of-range transitions during the last period.

    Step #3, the meat of figuring out what's in the DCC signal.

    Line 193: If the level goes 1 (high), record the time tick.

    Line 198: If the level goes 0 (low), calculate how long the last high period was. Lines 201-206 store the values in an array to help me debug, this is not strictly needed. Line 208 checks if we've exceeded a DCC message size, if so we're reading garbage and abort. Line 221 looks to see if the timing is in the range of a DCC one (short).

    Here's where it starts to branch out. A DCC message starts with a pre-amble of at least 12 ones. So I have a simple finite state machine, if we're looking for a preamble count the ones. How do we get out of the pre-amble state? Well, that requires a zero, so it's way down on line 425. Line 429 checks if we have 12 or more 1's followed by a zero, if so we move to the data state. Line 435 is if we get a zero after less than 12 pre-amble ones (for instance, we were connected to the track mid-preamble), and simply resets us to go look for a preamble again. If we're in the data state, line 446 records the 0 bit that just came across the wire into our buffer.

    Back up on line 400, this is an else for the if way up on line 229, but means we got a one in the middle of the message. Like the zero, we record it into our buffer.

    Line 229 is where the magic starts. We're in the data state, we're on the 9th bit of a byte, and it's a one! You see, DCC transmits an 8 bit byte followed by a 9th bit. If it's zero you do nothing, if it is 1 it indicates the end of the message. So this 9th bit being one means we've received an entire DCC packet.

    Basically Lines 230-399 are where the code would go to do something. For this project I just wanted to print out the commands coming across the wire, so these lines are a series of case and if statements to branch to all the possibilities and print them. For your decoder application it would probably be one if statement at the top (basically if address == my address) and then do something. There's actually a number of things I don't properly decode and print yet, if someone wanted to help add more, that would be great.


    Anyway, that's all there is to it. Now, if we think about a regular locomotive decoder, it would respond to the following:

    * Commands to set a CV would cause it to write the appropriate value to it's non-volatile RAM. And yes, plenty of the PIC micro-controllers have a small amount of EEPROM you can write to.

    * Commands for an address to move would be compared with the stored address (written by a CV write), and if they match would result in the decoder setting the motor output to the desired speed. The decoder may read other CV's, like say momentum, to decide how it changes the motor speed.

    * Commands for functions would be compared with the stored address, and if they match would result in the decoder turning on or off the appropriate function outputs, like a headlight. This behavior may be modified by things like a lighting rules CV it checks.


    I hope that helps you get started.
    --
    Leo Bicknell

  24. The Following User Says Thank You to bicknell For This Useful Post:


  25. #17
    Join Date
    Apr 2008
    Location
    Ashburn, VA, USA
    Posts
    1,137
    Thanks
    231
    Thanked 1,710 Times in 523 Posts
    Mentioned
    31 Post(s)
    Tagged
    0 Thread(s)

    Default

    After I wrote the explanation above, I realized I could make the code more clear. So I started a refactoring project. I've gotten to where the refactored code seems to produce the same results as the original code, so that's good. But I also realized there were some errors in my original code which I've been working on correcting.

    For the moment, they are on a branch on the repo called "CodeCleanup". If you're a programmer and want to go look please do. My description above is still good for the main branch.

    The refactored code seems to be working good for locomotives in forward and reverse, 128 and 14 speed step modes, and F0-F12. Things beyond that might still be a bit wonky.
    --
    Leo Bicknell

  26. #18
    Join Date
    Apr 2008
    Location
    Ashburn, VA, USA
    Posts
    1,137
    Thanks
    231
    Thanked 1,710 Times in 523 Posts
    Mentioned
    31 Post(s)
    Tagged
    0 Thread(s)

    Default

    I merged the CodeCleanup branch and committed a few other things this morning. As a result the line numbers I referenced above are no longer right. That said, the code is much easier to follow now, and has much better comments. It also in theory decodes a lot more, although there is still a lot of code to add.
    --
    Leo Bicknell

Similar Threads

  1. Homebrew DCC and Microcontrollers
    By Bryan in forum DCC
    Replies: 0
    Last Post: 13th Apr 2008, 10:52 PM
  2. Replies: 10
    Last Post: 16th Nov 2004, 02:19 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •