Code Documentation

class CSListener : public DCCEXProtocolDelegate

Public Functions

void receivedTurntableList()

Create the TurntableDisplay object once the turntable info is received.

void receivedTurntableAction(int turntableId, int position, bool moving)

Print a turntable action to the console.

Parameters:
  • turntableId – ID of the turntable associated with the move

  • position – Position number being moved to

  • moving – Boolean indicating if a move is in progress

class Rotary

Public Functions

Rotary(char, char)
unsigned char process()

Private Members

unsigned char state
unsigned char pin1
unsigned char pin2
class TurntableDisplay

Public Functions

TurntableDisplay(TFT_eSprite &displaySprite, DCCEXProtocol &csClient, uint16_t backgroundColour, uint8_t pitOffset, uint16_t pitColour, uint16_t homeColour, uint16_t positionColour, uint16_t bridgeColour, uint16_t bridgeMovingColour, uint16_t bridgePositionColour, uint16_t positionTextColour, unsigned long blinkDelay)

Constructor for the TurntableDisplay object, results in the basic turntable drawn on screen.

Parameters:
  • displaySprite – Reference to an existing TFT_eSprite object

  • csClient – Reference to an existing DCCEXProtocol client object

  • textColour – 16 bit colour for the text

  • backgroundColour – 16 bit colour for the background

  • bridgeColour – 16 bit colour for the turntable bridge

  • bridgeMovingColour – 16 bit colour for the bridge when moving, or when user is selecting a new position

  • bridgePositionColour – 16 bit colour for the end of the bridge indicating the selected position

  • positionTextColour – 16 bit colour for the name of the selected position

  • blinkDelay – Delay in ms to blink position text and bridge when turntable is moving

void begin()

Draws the initial turntable and bridge position, only to be called when lists have been received.

void update()

Update the display - call this at least once per main loop iteration to respond to broadcasts and blink if moving.

void setNextPosition()

Set the bridge to the next available position (clockwise), moves through home as position 0.

void setPreviousPosition()

Set the bridge to the previous available position (counter-clockwise), moves through home as position 0.

void setPosition(uint8_t position)

Set the display’s bridge position - call from a broadcast message to update the display.

Parameters:

position – Position index

uint8_t getPosition()

Get the current user selected position index.

Returns:

Position index

Private Functions

void _drawTurntable(Turntable *turntable)

Draws the basic turntable on screen.

Parameters:

turntable – Pointer to a DCC-EX protocol Turntable object

void _drawBridge(Turntable *turntable)

Draw the currently selected bridge’s position on screen.

Parameters:

turntable – Pointer to a DCC-EX protocol Turntable object

void _drawPositionName(Turntable *turntable)

Draw the currently selected position’s name on screen.

Parameters:

turntable – Pointer to a DCC-EX protocol Turntable object

void _getCoordinates(uint16_t x, uint16_t y, float *xp, float *yp, uint16_t r, float a)

Get coordinates of end of a line, pivot at x,y, length r, angle a, Taken from TFT_eSPI anti aliased clock demo

Parameters:
  • x – Starting X point to calculate coordinates from

  • y – Starting Y point to calculate coordinates from

  • xp – Reference to the resultant X point variable

  • yp – Reference to the resultant Y point variable

  • r – Length of the desired object to be drawn (typically a line)

  • a – Angle it is to be drawn at

float _calculateAngle(float relativeAngle)

Calculate the correct angle to draw a line on screen relative to the home position.

Parameters:

relativeAngle – Relative angle of the position to be drawn

Returns:

The absolute angle to draw the line on screen

Private Members

TFT_eSprite &_displaySprite
DCCEXProtocol &_csClient
uint16_t _backgroundColour
uint8_t _pitOffset
uint16_t _pitColour
uint16_t _homeColour
uint16_t _positionColour
uint8_t _bridgePosition
uint16_t _bridgeColour
uint16_t _bridgeMovingColour
uint16_t _bridgePositionColour
uint16_t _positionTextColour
unsigned long _blinkDelay
unsigned long _lastBlinkTime
bool _blinkState
bool _needsRedraw
const float _degreesToRadians = 0.0174532925
float _homeAngle
module conf

Variables

shell
project = "DCC-EX Turntable Controller"
copyright = '2024, Peter Cole'
author = 'Peter Cole'
extensions = ['sphinx.ext.autodoc','sphinx.ext.autosectionlabel','sphinxcontrib.spelling','sphinx.ext.todo','sphinx_sitemap','sphinx_design','breathe']
autosectionlabel_prefix_document = True
spelling_lang = 'en_AU'
tokenizer_lang = 'en_AU'
spelling_word_list_filename = ['spelling_wordlist.txt']
templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
html_theme_options = {# 'style_nav_header_background': 'white','logo_only': False,# Toc options'includehidden': True,'titles_only': True,'collapse_navigation': False,'navigation_depth': 3,'analytics_id': 'G-HBTV6STT77','analytics_anonymize_ip': False,'prev_next_buttons_location': 'both',}
html_context = {'display_github': True,'github_user': 'peteGSX-Projects','github_repo': 'DCCEXTurntableController','github_version': 'sphinx/docs/',}
html_css_files = ['css/peteGSX-theme.css',]
html_js_files = []
html_baseurl = 'https://petegsx-projects.github.io/DCCEXTurntableController/'
html_extra_path = ['robots.txt',]
breathe_projects = {"DCCEXTurntableController": "_build/xml/"}
breathe_default_project = "DCCEXTurntableController"
breathe_default_members = ()
file CommandStationClient.cpp
#include “CommandStationClient.h
#include “CommandStationListener.h

Functions

void setupCSClient(Stream &consoleStream, Stream &csConnectionStream)

Setup EX-CommandStation client:

  • associates the console and CommandStation connections with the client object

  • sets up the listener for broadcasts/responses

Parameters:
  • consoleStream – Reference to the console stream object

  • csConnectionStream – Reference to the CommandStation connection stream object

void processCSClient()

Process CommandStation client to listen for broadcasts/responses:

  • requests lists from CommandStation if not received

  • retries up to 5 times

  • 2 second delay between retries

Variables

const unsigned long retrieveTurntableRetryDelay = 2000
unsigned long lastRetrieveTurntableRetry = 0
uint8_t retrieveTurntableRetries = 5
bool retrievalErrorDisplayed = false
DCCEXProtocol csClient
CSListener csListener
file CommandStationClient.h
#include <Arduino.h>
#include <DCCEXProtocol.h>

Functions

void setupCSClient(Stream &consoleStream, Stream &csConnectionStream)

Setup EX-CommandStation client:

  • associates the console and CommandStation connections with the client object

  • sets up the listener for broadcasts/responses

Parameters:
  • consoleStream – Reference to the console stream object

  • csConnectionStream – Reference to the CommandStation connection stream object

void processCSClient()

Process CommandStation client to listen for broadcasts/responses:

  • requests lists from CommandStation if not received

  • retries up to 5 times

  • 2 second delay between retries

Variables

DCCEXProtocol csClient
file CommandStationListener.cpp
#include “CommandStationClient.h
#include “CommandStationListener.h
#include “DisplayFunctions.h
file CommandStationListener.h
#include “Defines.h
#include <Arduino.h>
#include <DCCEXProtocol.h>
file Defines.h
#include <TFT_eSPI.h>

Defines

CONSOLE
CS_CONNECTION
ROTARY_BTN
ROTARY_DT
ROTARY_CLK
HALF_STEP
GC9A01_BL
GC9A01_ROTATION
BACKGROUND_COLOUR
POSITION_TEXT_COLOUR
BRIDGE_COLOUR
BRIDGE_MOVING_COLOUR
PIT_COLOUR
BRIDGE_POSITION_COLOUR
HOME_COLOUR
POSITION_COLOUR
TEXT_FONT
PIT_OFFSET
DCCEX_DCC
DCCEX_EX
DCCEX_BACKGROUND
DCCEX_FONT
DCCEX_SMALL_FONT
DCCEX_VERSION_FONT
file DeviceFunctions.cpp
#include “DeviceFunctions.h

Functions

void resetDevice()
file DeviceFunctions.h
#include <Arduino.h>

Functions

void resetDevice()
file DisplayFunctions.cpp
#include “CommandStationClient.h
#include “Defines.h
#include “DisplayFunctions.h
#include “Version.h
#include <SPI.h>
#include <TFT_eSPI.h>

Functions

void setupDisplay()

Set initial display state - show version then clear.

void createTurntableDisplay()

Create the turntable display when info is received.

void updateDisplay()

Placeholder to keep the display up to date.

Variables

TFT_eSPI display = TFT_eSPI()
TFT_eSprite displaySprite = TFT_eSprite(&display)
TurntableDisplay turntableDisplay = TurntableDisplay(displaySprite, csClient, BACKGROUND_COLOUR, PIT_OFFSET, PIT_COLOUR, HOME_COLOUR, POSITION_COLOUR, BRIDGE_COLOUR, BRIDGE_MOVING_COLOUR, BRIDGE_POSITION_COLOUR, POSITION_TEXT_COLOUR, BLINK_DELAY)
file DisplayFunctions.h
#include “TurntableDisplay.h

Functions

void setupDisplay()

Set initial display state - show version then clear.

void createTurntableDisplay()

Create the turntable display when info is received.

void updateDisplay()

Placeholder to keep the display up to date.

Variables

TurntableDisplay turntableDisplay
file conf.py
file InputFunctions.cpp
#include “CommandStationClient.h
#include “DeviceFunctions.h
#include “DisplayFunctions.h
#include “InputFunctions.h
#include “Rotary.h
#include “avdweb_Switch.h”

Functions

Switch encoderButton(ROTARY_BTN)
void processEncoderButton()

Process rotary encoder button input method.

void processEncoder()

Process rotary encoder input method.

void sendPositionChange()

Send a position change to the CommandStation on single click.

void sendHome()

Send the home command to the CommandStation on double click.

Variables

Rotary encoder = Rotary(ROTARY_DT, ROTARY_CLK)
file InputFunctions.h
#include “Defines.h
#include <Arduino.h>

Functions

void processEncoderButton()

Process rotary encoder button input method.

void processEncoder()

Process rotary encoder input method.

void sendPositionChange()

Send a position change to the CommandStation on single click.

void sendHome()

Send the home command to the CommandStation on double click.

file myConfig.example.h
file README.md
file Rotary.cpp
#include “Arduino.h”
#include “Rotary.h

Defines

R_START
R_CCW_BEGIN
R_CW_BEGIN
R_START_M
R_CW_BEGIN_M
R_CCW_BEGIN_M

Variables

const unsigned char ttable[6][4] = {{R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START}, {R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START}, {R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START}, {R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START}, {R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW}, {R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW},}
file Rotary.h
#include <Arduino.h>
#include “Defines.h

Variables

const byte DIR_CW = 0x10
const byte DIR_CCW = 0x20
file TurntableDisplay.cpp
#include “Defines.h
#include “TurntableDisplay.h
file TurntableDisplay.h
#include <Arduino.h>
#include <DCCEXProtocol.h>
#include <TFT_eSPI.h>
file Version.h

Defines

VERSION
page md__home_runner_work_DCCEXTurntableController_DCCEXTurntableController_README

This is a controller for DCC-EX turntables, operating as a native DCC-EX protocol client to utilise a turntable object and allow a user to operate it.

Turntable operations are displayed on a round LCD.

Hardware required

This software has been written explicitly for an STM32F411CEU6 Blackpill microprocessor, with a connected rotary encoder and GC9A01 based LCD.

It also requires a serial connection to a DCC-EX CommandStation.

A future version may implement support for an ESP32 based microprocessor to provide a WiFi client connection to the DCC-EX CommandStation.

Pins and connections

The below pins are used on the Blackpill to connect to the CommandStation’s serial port, rotary encoder, and GC9A01 LCD.

Remember to cross Rx/Tx so that the Blackpill Rx connects to the CommandStation’s Tx, and vice versa. Also be sure to connect a common ground, and take into account if the CommandStation uses 3.3V or 5V logic, as the Blackpill is a 3.3V uC.

  • Serial Rx - PA10

  • Serial Tx - PA9

  • Rotary encoder button - PB15

  • Rotary encoder DT - PB14

  • Rotary encoder CLK - PB13

  • GC9A01 DIN - PA7

  • GC9A01 CLK - PA5

  • GC9A01 CS - PA4

  • GC9A01 DC - PA3

  • GC9A01 RST - PA2

  • GC9A01 BL - PA1

Installation and configuration

This repository is setup to enable PlatformIO to be used with VSCode and will automatically install the required libraries:

  • DCC-EX/DCCEXProtocol

  • bodmer/TFT_eSPI

  • avandalen/Switch

If you prefer, you can also use the Arduino IDE, which means you will need to:

If you wish to customise the pins, colours, and font in use, you can copy the included “myConfig.example.h” to “myConfig.h” and edit it to suit. Instructions are in the file.