dcc

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2021 License: MIT Imports: 6 Imported by: 0

README

go-dcc

GoDoc Build Status codecov

NRMA Digital Command Control (DCC) implementation in Go.

This module implements the DCC protocol for controlling model trains.

It includes a Raspberry Pi driver and a dccpi command line application for easy use on this platform, although it is easily extensible to other systems.

The implementation is based on the:

Index

Features

You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

Joe Armstrong

go-dcc is aims to to provide a minimal feature set to control DCC-based locomotives. Although the original aim is to support Raspberry Pi as a Command Station, it can easily incorporate drivers for other platforms and be integrated in projects with larger scope. It is not a support-all, complex, multi-protocol, ui-included, buy-my-hardware solution. For this, there are better solutions like RocRail, JMRI, SPROG, GertBot etc.

go-dcc is inspired in dccpi(https://github.com/hsanjuan/dccpi), a Python library of similar characteristics. Go has the advantage that it requires no C dependencies, it is faster and less prone to errors. Some of the features supported are:

  • Easy to build and install (using go get or simply downloading the binaries)
  • Easy to adapt to new platforms
  • Well tested and documented
  • Supports Raspberry Pi Model B+ and newer
  • Control DCC locomotives using a simple command line interface or Go
  • Set speed (28 speed steps) and direction
  • Set FL (lights), F1-F4 functions

Note go-dcc does not yet implement any advanced features like decoder registry operations (i.e. set address).

Hardware requirements

  • A Raspberry Pi (developed/tested on model B+ v1.2). It should work with newer, more powerful models.
  • DCC-decoder-equipped locomotives
  • Train tracks
  • Booster circuit: needed to provide the signal to the tracks. See below.
  • A power adapter with ~12-24V DC output. I use an AC-DC adapter with an output of 18V, 2A.

go-dcc should work on any common scale. DCC decoders take a wide range of voltage outputs (up to 24v). This has been tested on N-scale with a 18v booster circuit.

Booster circuit

Here is an example booster using LMD18200 H-Bridge from TI:

Booster schematics

These are the parts:

Here is an image of a dccpi printed PCB plugged to a Raspberry Pi:

dccpi-board.jpg

Software requirements

  • Go: https://golang.org/dl/

Installation

dccpi

To build/install:

> git clone https://github.com/hsanjuan/go-dcc
> cd go-dcc/dccpi
> go install

and the dccpi application will be installed in your $GOPATH/bin folder.

Running

Raspberry Pi driver

The Raspberry Pi driver is a submodule located at drivers/dccpi/dccpi.go.

By default, The Raspberry Pi will output the signal (which goes from 0v-Low to 3.3v-High) on BCM GPIO pin 17, which is Physical Pin 11 (Model B+). The booster is in charge of converting this signal into the DCC signal ranges (i.e. 18v to -18v).

The Raspberry Pi will also output a brake signal (HIGH) when the controller is stopped on BCM GPIO pin 27, which is Pysical Pin 13 (Model B+). This can be used to stop the signal on the tracks if your booster supports it (see booster schematics). Otherwise locos will receive DC current directly and probably turn into analog DC mode and start going at full speed.

The pins mentioned above are configurable.

dccpi usage

The dccpi application allows to control locomotives and other DCC devices. Execute it and you will be taken to the dccpi console.

This is a summary of the available commands:

dccpi> help

Available commands (use "help <command>" for information):

direction - Control locomotive direction
fl - Control the headlight of a locomotive
exit - Exit from dccpi
help - Show this help
power - Control track power
speed - Control locomotive speed
status - Show information about devices
register - Add DCC device
unregister - Remove DCC device
save - Save current devices in configuration file

The dccpi application tries to read a JSON configuration file which specifies the configuration of the DCC decoders in the system. The configuration file default path is ~/.dccpi and looks like:

{
    "locomotives": [
        {
            "name": "loco1",
            "address": 6,
        },
        {
            "name": "loco2",
            "address": 7,
            "fl": true
        },
        {
            "name": "DCCThing",
            "address": 8,
            "f1": true,
            "f2": true,
            "f3": true,
            "f4": false,
        }
    ]
}

This will allow to send packets to the three defined DCC devices directly without the need to register them when running the application.

Go Library Documentation

The Go documentation is maintained with GoDoc. See: https://godoc.org/github.com/hsanjuan/go-dcc .

Additional drivers

Additional drivers for go-dcc must implement the dcc.Driver interface.

Questions and contributions

PRs accepted. Please open an issue if you have any questions.

License

MIT. Copyright 2017 Hector Sanjuan. See LICENSE.

Documentation

Overview

Package dcc implements the DCC protocol for controlling model trains. It can support a number of different encoders, which are in charge of translating DCC packages into electrical signals. By default, a Raspberry Pi driver is provided.

The implementation follows the S-91 Electrical Standard (http://www.nmra.org/sites/default/files/standards/sandrp/pdf/s-9.1_electrical_standards_2006.pdf), the S-92 DCC Communications Standard (http://www.nmra.org/sites/default/files/s-92-2004-07.pdf) and the S-9.2.1 Extended Packet Formats for Digital Command Control standard (http://www.nmra.org/sites/default/files/s-9.2.1_2012_07.pdf).

Index

Constants

View Source
const (
	BitOnePartMinDuration  = 55 * time.Microsecond
	BitOnePartMaxDuration  = 61 * time.Microsecond
	BitZeroPartMinDuration = 95 * time.Microsecond
	BitZeroPartMaxDuration = 9900 * time.Microsecond
	PacketSeparationMin    = 5 * time.Millisecond
	PacketSeparationMax    = 30 * time.Millisecond
	PreambleBitsMin        = 14
)

DCC protocol-defined values for reference.

Variables

View Source
var (
	BitOnePartDuration  = 55 * time.Microsecond
	BitZeroPartDuration = 100 * time.Microsecond
	PacketSeparation    = 15 * time.Millisecond
	PreambleBits        = 16
)

Some customizable DCC-related variables.

View Source
var CommandMaxQueue = 3

CommandMaxQueue specifies how many commands can queue before sending a new command blocks the sender

View Source
var CommandRepeat = 30

CommandRepeat specifies how many times a single packet is sent.

View Source
var HeadlightCompatMode = false

HeadlightCompatMode controls if one bit in the speed instruction is reserved for headlight. This reduces speed steps from 32 to 16 steps.

Functions

This section is empty.

Types

type Config

type Config struct {
	Locomotives []*Locomotive `json:"locomotives"`
}

Config allows to store configuration settings to initialize go-dcc.

func LoadConfig

func LoadConfig(path string) (*Config, error)

LoadConfig parses a configuration file and returns a Config object.

func (*Config) Save

func (c *Config) Save(path string) error

type Controller

type Controller struct {
	// contains filtered or unexported fields
}

Controller represents a DCC Control Station. The controller keeps tracks of the DCC Locomotives and is in charge of sending DCC packets continuously to the tracks.

func NewController

func NewController(d Driver) *Controller

NewController builds a Controller.

func NewControllerWithConfig

func NewControllerWithConfig(d Driver, cfg *Config) *Controller

NewControllerWithConfig builds a new Controller using the given configuration.

func (*Controller) AddLoco

func (c *Controller) AddLoco(l *Locomotive)

AddLoco adds a DCC device to the controller. The device will start receiving packets if the controller is running.

func (*Controller) Command

func (c *Controller) Command(p *Packet)

Command allows to send a custom Packet to the tracks. The packet will be sent CommandRepeat times.

func (*Controller) GetLoco

func (c *Controller) GetLoco(n string) (*Locomotive, bool)

GetLoco retrieves a DCC device by its Name. The boolean is true if the Locomotive was found.

func (*Controller) Locos

func (c *Controller) Locos() []*Locomotive

Locos returns a list of all registered Locomotives.

func (*Controller) RmLoco

func (c *Controller) RmLoco(l *Locomotive)

RmLoco removes a DCC device from the controller. There will be no longer packets sent to it.

func (*Controller) Start

func (c *Controller) Start()

Start starts the controller: powers on the tracks and starts sending packets on them.

func (*Controller) Stop

func (c *Controller) Stop()

Stop shuts down the controller by stopping to send packets and removing power from the tracks.

type Direction

type Direction byte

Direction represents the locomotive direction and can be Forward or Backward.

const (
	Backward Direction = 0
	Forward  Direction = 1
)

Direction constants.

type Driver

type Driver interface {
	// Low sets the output to low state.
	Low()
	// High sets the output to high.
	High()
	// TracksOn turns the tracks on. The exact procedure is left to the
	// implementation, but tracks should be ready to receive packets from
	// this point.
	TracksOn()
	// TracksOff disables the tracks. The exact procedure is left to the
	// implementation, but tracks should not carry any power and all
	// trains should stop after calling it.
	TracksOff()
}

Driver can be implemented by any module to allow using go-dcc on different platforms. dcc.Driver modules are in charge of producing an electrical signal output (i.e. on a GPIO Pin)

type Locomotive

type Locomotive struct {
	Name      string    `json:"name"`
	Address   uint8     `json:"address"`
	Speed     uint8     `json:"speed"`
	Direction Direction `json:"direction"`
	Fl        bool      `json:"fl"`
	F1        bool      `json:"f1"`
	F2        bool      `json:"f2"`
	F3        bool      `json:"f3"`
	F4        bool      `json:"f4"`
	// contains filtered or unexported fields
}

Locomotive represents a DCC device, usually a locomotive. Locomotives are represented by their name and address and include certain properties like speed, direction or FL. Each locomotive produces two packets: one speed and direction packet and one Function Group One packet.

func (*Locomotive) Apply

func (l *Locomotive) Apply()

Apply makes any changes to the Locomotive's properties to be reflected in the packets generated for it and, therefore, alter the behaviour of the device on the tracks.

func (*Locomotive) String

func (l *Locomotive) String() string

type Packet

type Packet struct {
	// contains filtered or unexported fields
}

Packet represents the unit of information that can be sent to the DCC devices in the system. Packet implements the DCC protocol for converting the information into DCC-encoded 1 and 0s.

func NewBaselinePacket

func NewBaselinePacket(d Driver, addr byte, data []byte) *Packet

NewBaselinePacket returns a new generic baseline packet. Baseline packets are different because they use a 128 address space. Therefore the address is forced to start with bit 0.

func NewBroadcastIdlePacket

func NewBroadcastIdlePacket(d Driver) *Packet

NewBroadcastIdlePacket returns a new broadcast baseline DCC packet on which decoders perform no action.

func NewBroadcastResetPacket

func NewBroadcastResetPacket(d Driver) *Packet

NewBroadcastResetPacket returns a new broadcast baseline DCC packet which makes the decoders erase their volatile memory and return to power up state. This stops all locomotives at non-zero speed.

func NewBroadcastStopPacket

func NewBroadcastStopPacket(d Driver, dir Direction, softStop bool, ignoreDir bool) *Packet

NewBroadcastStopPacket returns a new broadcast baseline DCC packet which tells the decoders to stop all locomotives. If softStop is false, an emergency stop will happen by cutting power off the engine.

func NewFunctionGroupOnePacket

func NewFunctionGroupOnePacket(d Driver, addr byte, fl, fl1, fl2, fl3, fl4 bool) *Packet

NewFunctionGroupOnePacket returns an advanced DCC packet which allows to control FL,F1-F4 functions. FL is usually associated to the headlights.

func NewPacket

func NewPacket(d Driver, addr byte, data []byte) *Packet

NewPacket returns a new generic DCC Packet.

func NewSpeedAndDirectionPacket

func NewSpeedAndDirectionPacket(d Driver, addr byte, speed byte, dir Direction) *Packet

NewSpeedAndDirectionPacket returns a new baseline DCC packet with speed and direction information.

func (*Packet) Length

func (p *Packet) Length() int

Length returns the length of the DCC-encoded representation of a packet.

func (*Packet) PacketPause

func (p *Packet) PacketPause()

PacketPause performs a pause by sleeping during the PacketSeparation time.

func (*Packet) Send

func (p *Packet) Send()

Send encodes and sends a packet using the Driver associated to it.

func (*Packet) String

func (p *Packet) String() string

Directories

Path Synopsis
driver

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL