Shop OBEX P1 Docs P2 Docs Learn Events
Model RailRoad DCC Projects — Parallax Forums

Model RailRoad DCC Projects

shanghai_foolshanghai_fool Posts: 149
edited 2014-01-04 14:49 in Propeller 1
Has anyone written any objects for DCC decoding? My search has not turned up anything other than the basic DCC driver in OBEX.

Donald
·
«1

Comments

  • SRLMSRLM Posts: 5,045
    edited 2009-04-10 05:18
    I'm pretty sure that it's proprietary (at least at the G scale). You could probably use an oscilloscope to figure out the commands though and reverse engineer it.
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-10 06:08
    Actually, it is public domain. The structure itself is published by NMRA so that equipment from different manufacturers could be used together. This document explains it. There are several designs using other MCU's. I was wondering if anyone had developed Propeller code.

    It shouild not be too hard for an experienced programer as the structure is fairly straight forward. I will work on it if no one has already done it. I just hate reinventing the wheel but there is so much more could be done using the propeller as its brain. The shortest bits are ~50us so it should be easily doable, even·in Spin.

    The largest commercial decoders operate a maximum of 8 turnouts (switches). A single propeller could operate dozens.



    Donald
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-10 08:00
    There is some DCC code in the Object Exchange. It's sending DCC commands, not decoding them, but maybe it's a good starting point.

    A year ago I also build my own DCC Booster. I had a command-terminal running on the PC and could send all commands bitwise. Unfortunately it's AVR code because I did not have a propeller that time. But to be honest - using a propeller as command station makes sense, but as decoder I'd never use a propeller. Why would you like to waste so much computing power (and money) for such a simple task?

    Where it would make sense is maybe a DCC testing device. Using it's TV or VGA output to monitor what's going on on your DCC lines.
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-10 09:15
    Yes, I could buy 8 PIC's for the price of a Propeller but that is not the point. I just want to start with a decoder. I have lots of ideas that I can go from there that would definitely make use of the Prop. Including the DCC testing.

    Besides, I had much rather write Spin code.

    Donald
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-04-10 10:15
    One of the projects I have wanted to do was a DCC command station with the Propeller. The Propeller would be perfect for handling all that is involved in a command station like sending data to the DCC booster, managing a network or two of other devices, etc. The Propeller would also be good as an advanced function decoder and response system. I unfortunately haven't done anything more on this idea though because of lack of space for a layout in my HK apartment. Perhaps in time that will change. Writing a decoder or encoder shouldn't be too bad, but I don't have the equipment to test it on at the moment.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
    www.tdswieter.com
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-10 10:38
    Of course for the learning it makes sense to use the propeller. The propeller is excellent for rapid prototyping. And there might be decoder applications I don't have in mind where the power is needed. Usually decoders are very small ( I have N scale ) and relly don't have much to do. Read the signal, decode the adress and switch some outputs.

    Did you find some documents yet? Otherwise I can have a look if I have some english documentation of DCC.
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-04-10 10:41
    Is this what you are looking for?

    en.wikipedia.org/wiki/Digital_Command_Control
    www.nmra.org/standards/standards.html
    www.nmra.org/standards/sandrp/consist.html

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
    www.tdswieter.com
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-10 11:40
    That is what I am using to try and decode the data. I have built the MiniDcc command station and a booster to start with. The trouble comes in turnout decoders. The different systems access turnouts differently. I would like to build a universal decoder that would work with any type.

    I have the "1"'s and "0"'s decoded so I just need to combine them into bytes and packets. Then I will try to see the methods used.
    ·
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-10 14:00
    I now remember something which I have heard before.

    "Sometimes the act of observing changes that which is being observed."

    While taking a TV break, I think I am not seeing what is really there. Spin, especially when using the terminal, may not have enough time to properly decode the data.

    I will continue tomorrow.

    Donald
    ·
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-10 16:21
    Yes, that's it. The DCC sends the data with ~250kbit/sec. So you have only 20_000_000 / 250_000 = 80 PASM instructions you can run in that time. SPIN needs some hundred PASM instructions per SPIN instruction. So you need a PASM driver to read the DCC commands.
  • JoJo Posts: 55
    edited 2009-04-10 17:33
    If anyone is interested, I built a full up DCC system using a propeller for my son (partly for fun, partly educational, partly coz it was cheaper). I have schematics, SPIN code etc. Supports running, programming, runs up to 4 trains (technically nothing stops doing more, but that is all I could fit on a 4x20 text LCD), has a fast clock, etc
    Don't have the system here at work, which is the only reason not posting it straight away.
    Basic components:
    LMD18200 H-bridge, driven by a propeller (prototype used a Propeller Demo board; final version uses a custom PCB)
    output: serial 4x20 lcd (from moderndesign.com)
    input: PS2 keyboard
    power: being supplied by the old train power supply, with the throttle set so that output is at 14v

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    Jo
  • DaveJensonDaveJenson Posts: 375
    edited 2009-04-10 21:38
    I am certainly interested! Please post as much as you are willing.



    Dave
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-10 22:13
    @ Jo
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-04-10 23:25
    Jo
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-11 00:10
    I discovered there is not enough time in Spin to shift bits and display data. I will have to go PASM to get bytes/packets.
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-13 07:16
    Some success.

    After offloading the packet reading to another cog, I am able to decipher the packets. The basic reading object in spin has plenty of time to decode the bits and transfer the bytes to a buffer.

    I have 4+ ms to decipher the packet. So far I have decoded the basic packet and some of the extended packets. I am not seeing all the data I expected, however.

    I can read the address, speed and direction but I fail to see the proper functions operate. If anyone has a DCC controlled layout and willing to assist, I will post the code I have so far.

    Donald
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-14 05:15
    Got it!!
    Works great.
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-04-14 05:15
    Do post! Oh what circuit are you using also?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
    www.tdswieter.com
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-14 06:23
    There is not much of a "circuit" yet. I just use an optoisolator 6N137 between the booster (track) and Prop. I will add the drivers later. They are pretty simple. I will use·several L293D quad half 'H' drivers to actually drive the 12 volt Tortoise motors. I will probably use 24 output pins and 74LV04 type inverters to drive the lower half. 1 pin is used for input.
    I am using a couple of pins to sync scope and test timing of procedures. These will be removed later.
    There are 2 different type os turnout mechanisms used. One is the pulse type which just uses a solenoid and a momentary contact. The Tortoise uses a 12 v bipolar continuous output. The Prop output can be made to use either with different hardware.
    I want to add writing to the upper eeprom to save the last position for next power up. There is so much more I could do with this but need to wait for ideas.
    Attached is "quick & dirty" code. I will clean up later. I am open to suggestions and ideas about what else can be done now that we have the data. I should add decoding of the other functions but they have more to do with CV programming and I don't have a programming station·so no way to test it.

    Have Fun

    Donald

    Basic Decode object:
    {{DCC Test Program
       This program uses the packet Object to get the data from the booster(rails).
       It also uses the PC_Interface to display the data
       I use a 6N137 optoisolator with the LED connected to the rails through a 1.2k resistor.
       The output is pulled up to 5v through a 33k resistor and connected to port 0 through
       a 2.7k resistor.
       I use port 1 and 2 as troubleshooting pins for development. Port 1 is high while
       waiting for preamble. It is useful for triggering scope. Port 2 is taken high while
       processing the data. It was to confirm how long the process was taking. 
       
       }}
    con
      _clkmode = xtal1+pll16x
      _xinfreq = 5_000_000
    var
      long temp
      long pnum
      long eaddr 'extended address
      byte addr
      byte cmd
      byte index
      byte buffer[noparse][[/noparse]30]
    obj
      text : "PC_Interface"
      rd: "packet"
    pub main | i,j,each
      text.start(31,30)
      text.out(0)
      dira[noparse][[/noparse]2] := 1
      outa[noparse][[/noparse]2] := 0
      text.str(string("DCC Test Program"))
      waitcnt(cnt + 80_000_000)
      text.out(0)
      text.str(string("Loco SPD L4321 8765 "))
      pnum := 0
      index := 0
      'clear buffer
      repeat 30
        buffer[noparse][[/noparse]index] := 0
      temp := rd.start(@pnum,@index,@buffer)
      'text.dec(temp)
      setpos(1,1)
      repeat while pnum == 0
      repeat  
        waitpeq(2,2,0)
        outa[noparse][[/noparse]2] := 1
        addr := buffer[noparse][[/noparse]0] 
        cmd := buffer[noparse][[/noparse]1]
        if addr < 128
          setpos(0,addr)
          text.dec(addr)
          setpos(4,addr)
          CASE cmd & 224
            %01000000 :      'Reverse
              text.str(string("R  "))
              setpos(6,addr)
              temp := (cmd & 15) << 1
              temp := temp + ((cmd >>4) & 1)
              text.dec(temp)
              text.out(" ")
              
            %01100000 :       'Forward
              text.str(string("F  "))
              setpos(6,addr)
              temp := (cmd & 15) << 1
              temp := temp + ((cmd >>4) & 1)
              text.dec(temp)
              text.out(" ")
              
            %10000000 :       '100DDDDD  Function Group 1
              setpos(9,addr)
              text.bin(cmd,5)
            %10100000 :       '101SDDDD  Function Grooup 2
              if buffer[noparse][[/noparse]1] & 16    'Functions 5-8
                setpos(15,addr)
                text.bin(cmd,4)
              else                    'Functions 9-12
                setpos(20,addr)
                text.bin(cmd,4)
        else
          if addr <> 255    ' this gets rid of nop's
           ' Basic Accessory  Decoder
          '{preamble} 0 10AAAAAA 0 1AAACDDD 0 EEEEEEEE 1   -- What the NMRA says
          '             100AAAAA   1111AAAC       What I see with MiniDCC
            eaddr := ((addr & %00011111) <<2)+ ((cmd & %00000110)>>1) 
            if eaddr <> 0       
              setpos(0,11)
              text.dec(eaddr-3)
              text.out(" ")
              text.out((cmd &1)+48)
          
        outa[noparse][[/noparse]2] := 0    
        waitpeq(0,2,0)  ' wait for next packet
           
    
    PRI setpos(px, py)
      text.out(10)
      text.out(px)
      text.out(11)
      text.out(py)
       
           
    


    Get packet data object:
    {  This object continually gets the data from the rails thru optoisolator
    and transfers to main program.
     
    }
    VAR
      long  Stack[noparse][[/noparse]20]                      'Stack space for new cog
      byte  Cog                            'Hold ID of cog in use, if any   
      byte  data
      byte  bit
    PUB Start(pnum,index,buffer): Success
    {{Start new servo input process.  Return True if successful.}}
      Stop
      Success := (Cog   := cognew(Measure(pnum,index,buffer), @Stack) + 1)
    PUB Stop
    {{Stop toggling process, if any.}}
      if Cog
        cogstop(Cog~ - 1)
     
    PUB Active: YesNo
    {{Return TRUE if process is active, FALSE otherwise.}}
      YesNo := Cog > 0
          
    PUB Measure (pnum,index,buffer) | j,k, idx
       dira[noparse][[/noparse]1] := 1
       outa[noparse][[/noparse]1] := 0
       repeat  
          idx := 0
          outa[noparse][[/noparse]1] := 1
          getpre
          outa[noparse][[/noparse]1] := 0
          repeat while bit > 70
            data := 0
            repeat 8
              'waitpeq (0,1,0)
              data := data << 1
              waitpeq (1,1,0)
              j := cnt
              waitpeq (0,1,0)
              k := cnt
              bit := ((k - j) / 80)
              if bit < 70
                data++
              else
            BYTE[noparse][[/noparse]buffer][noparse][[/noparse]idx++] := data
            waitpeq (1,1,0)
            j := cnt
            waitpeq (0,1,0)
            k := cnt
            bit := ((k - j) / 80)
          BYTE[noparse][[/noparse]index] := idx
             
          LONG[noparse][[/noparse]pnum]++
    pri getpre | i, j ,k, l                  'get preamble
        i := 10
        repeat while i
          waitpeq (0,1,0)
          waitpeq (1,1,0)
          j := cnt
          waitpeq (0,1,0)
          k := cnt
          bit := ((k - j) / 80)
          if bit < 70
            i--
          else
            i := 10  'not enough, start over.
            ' ok got at least 10 1's
            ' now look for '0'
        repeat while bit < 70
          waitpeq (1,1,0)
          j := cnt
          waitpeq (0,1,0)
          k := cnt
          bit := ((k - j) / 80)
    
    
  • nohabnohab Posts: 96
    edited 2009-04-14 10:52
    @ Jo
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-04-14 11:23
    I have a Digitrax system so I am interested in Loconet, but like I said my system is gathering dust at the moment. Maybe I will have room to bring it to my new home and then I could do some development on the DCC/Loconet side of things.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
    www.tdswieter.com
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-14 11:43
    The Tortoise can be driven several ways as it only requires 12vdc at ~20ma. The problem is it needs bi-polar input, like a dc motor. The dual H bridge and a couple gates from a hex inverter will drive 2 motors so thats 1 1/3 chips for 2 motors. I looked at line drivers but this was the fewest/lowest cost solution I have come across so far. This will work for my layout but others may want a capacitor discharge type of circuit to drive solenoid type switches. If I get time, I will look into dual purpose hardware solution. All the switches I have now are Bachmann DCC solenoid type but they are track powered and everytime I have a derailment short, all the switches operate by themselves and I have to look at each one before I start the trains again.

    I am interested in LocoNet but I have to come up with a controller that will do what I want. I can't really afford the Digitrax controllers as the shipping is prohibitive and there are features that they don't have. Beside, what better way to get something going on the Propeller. I have gained a lot of knowledge about the DCC protocol with this project but I have lots more to learn before trying to design the controller. Both the Bachmann and the MiniDCC are too limited and the commercial units are too expensive. I think the Propeller would make a fantastic controller and it could certainly talk with LocoNet or any other proprietary network.

    It was kind of frustrating doing the decoder as I only have the 2 controllers and they handle turnouts completely different. The MiniDCC did not seem to follow the NMRA RP as I understand it. Thats why it took me so long. Also, I had to learn how to start and talk to another cog.

    This is a very inexpensive solution as the going prices of $50(US) for 8 point driver if I could get them here. This one for 24 points should cost less than $50. I probably will not do a PC layout for only one unit. I have a protoboard laying here that doesn't have an application and size is not a concern in this instance.

    I have an idea for a throttle but I will wait until I test it out before going public.

    Donald
  • DaveJensonDaveJenson Posts: 375
    edited 2009-04-22 15:32
    Yes, please post your LocoNetReader.
    nohab said...
    Anyone interested in LocoNet as well? (I've made a very raw LocoNetreader)
  • BasilBasil Posts: 380
    edited 2009-04-23 09:01
    Hey [noparse]:)[/noparse] I am also developing a DCC system, have a look at my blog below for details [noparse]:)[/noparse]

    Been on hold a bit but so far I have completed (untested) DCC & S88 drivers and am working on the control bus. UI will be next.

    Will post more details if requested [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -Alec

    Velden in N scale
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-04-23 14:18
    Post all the DCC and model railroad related details. It appears that several people have worked in parts and pieces of hardware and software design. If we can get projects and details posted, even in partial form, then others can build on that information.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
    www.tdswieter.com
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-23 14:36
    Shall I post my AVR code as well?
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-04-24 00:38
    If the AVR code will help someone port the design to the Propeller I would say so.

    Again, it sounds like several people have worked on this, but only Shanghai Fool has done some posting of the details. It would help everyone here (including those that do not post and just read the forums) to learn from posting more DCC examples. Perhaps together we can create some robust drivers and place them in the object exchange.

    Basil - I am interested in learning more about S88, do you have links? Why did you chose that? From what I understand Shanghai Fool was having trouble choosing a particular DCC system because of lack of turnout control or quantity of control. What have you found in your experience?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
    www.tdswieter.com
  • BasilBasil Posts: 380
    edited 2009-04-24 01:22
    Hi Tim,

    My code is on another PC which is at home at the moment, but Ill post it when I get a moment [noparse]:)[/noparse]

    S88 is straight forward as its effectively a giant shift register.

    Electrically speaking, each feedback unit has a 4044 latch and 4014 shift register and all the feedback units are cascaded. So on each CLK pulse, the bits are shifted one by one towards the Prop, making their way through the cascading registers, and after all bits have been collected, the latches are reset
    Heres a good overview

    and electrical...
    It offers no error correction whatsoever but because its so easy to implement and the update frequency can be quite high, any errors are smoothed over anyway.

    Only changes in state are recorded which can be performed with a simple XOR.

    I chose it because its easy and cheap to make the decoder, and due to its simplicity all datacollection and management can be performed in a single cog written in spin.

    ADDITION:
    Turnouts can each be connected to one of the register's bits so their state can be read.
    The DCC command to move the turnout will stay on the queue until the state read by the S88 bus matches the state of the turnout stores in HUB memory.

    Hope that makes sense :/

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -Alec

    Velden in N scale

    Post Edited (Basil) : 4/24/2009 2:12:34 AM GMT
  • BasilBasil Posts: 380
    edited 2009-04-24 05:10
    Right, attached is what I have so far.
    Note: I use looooong variable names :P
    An explanation of the different routines...

    PUB main: This is the startup COG and will also be the user interface once everything is up and running.
    PRI Xnet_manager: This manages communication with the Xpressnet devices and also processes all commands received and acts on them. INCOMPLETE. This is what I was working on last, just trying to streamline things rather than using a ton of if...thens.

    PRI DCC_Manager: Manages DCC queue and prioritise commands. I think its complete but probably full of errors because I had trouble wrapping my head around things at the time it was written

    PRI ID_Get_Ptr: Gets the pointer to a loco in the database based on loco id.

    PRI DCC_Send_cmd: Processes a DCC command ready for transmitting. Pretty much just determines how many bytes to send.

    PRI DCC_Loop: Does the dirty work. Outputs DCC command.

    PRI S88_Manager: Does all the S88 stuff and updates 2 arrays in HUB memory, Current status and changes since last update.

    PRI Wait_us: Ill let you figure this one out...

    Hope it helps! This was all written without testing as I have no prop. I also have never used DCC before so its all based around the NMRA documents for DCC, Lenz documents for Xpressnet and stuff on the web for S88.

    Oh, and its all written in BST [noparse]:D[/noparse]

    Feel free to ask questions!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -Alec

    Velden in N scale
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-04-24 08:26
    I do not understand what S88 is supposed to do. Please explain.
Sign In or Register to comment.