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, 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 – Pointer to an existing TFT_eSprite 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(Turntable *turntable)

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

Parameters:

turntable – Pointer to an existing DCCEXProtocol turntable object

Turntable *getTurntable()

Get the DCCEXProtocol turntable object associated with this display.

Returns:

Pointer to the turntable object

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()

Draws the basic turntable on screen.

void _drawBridge()

Draw the currently selected bridge’s position on screen.

void _drawPositionName()

Draw the currently selected position’s name on screen.

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
Turntable *_turntable
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
#include “Defines.h
#include “DisplayFunctions.h

Functions

void connectCSClient()

Connect to the CommandStation and ensure it’s alive.

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
bool csConnected = false
DCCEXProtocol csClient
CSListener csListener
file CommandStationClient.h
#include <Arduino.h>
#include <DCCEXProtocol.h>

Functions

void connectCSClient()

Connect to the CommandStation and ensure it’s alive.

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

SERIAL_CLIENT
WIFI_CLIENT
CONSOLE
CLIENT_TYPE
HALF_STEP
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
TURNTABLE_ID
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()

Setup display object.

void displaySoftwareInfo()

Display DCC-EX logo and software version.

void displayConnectingScreen()

Display connecting status.

void displayRetrievingInfo()

Display retrieving info after connect successful.

void createTurntableDisplay()

Create the turntable display when info is received.

void updateDisplay()

Placeholder to keep the display up to date.

void displayConnectionError()

If a connection to the CommandStation cannot be made, display error.

void displayObjectRetrievalError()

If retrieving the turntable object fails, display error.

void displayStatus(const char *status)

Display the provided status text.

Parameters:

status – Char array of status text

Variables

TFT_eSPI display = TFT_eSPI()
TFT_eSprite displaySprite = TFT_eSprite(&display)
TurntableDisplay turntableDisplay = TurntableDisplay(&displaySprite, BACKGROUND_COLOUR, PIT_OFFSET, PIT_COLOUR, HOME_COLOUR, POSITION_COLOUR, BRIDGE_COLOUR, BRIDGE_MOVING_COLOUR, BRIDGE_POSITION_COLOUR, POSITION_TEXT_COLOUR, BLINK_DELAY)
uint16_t statusX
uint16_t statusY
uint16_t dccexDCCColour = 0x01C8
uint16_t dccexEXColour = 0x03B6
uint16_t dccexBackgroundColour = 0xFFFF
const GFXfont *dccexFont = &FreeSansBold12pt7b
const GFXfont *dccexSmallFont = &FreeMono9pt7b
const GFXfont *dccexVersionFont = &FreeMonoBold9pt7b
file DisplayFunctions.h
#include “TurntableDisplay.h

Functions

void setupDisplay()

Setup display object.

void displaySoftwareInfo()

Display DCC-EX logo and software version.

void displayConnectingScreen()

Display connecting status.

void displayRetrievingInfo()

Display retrieving info after connect successful.

void createTurntableDisplay()

Create the turntable display when info is received.

void updateDisplay()

Placeholder to keep the display up to date.

void displayConnectionError()

If a connection to the CommandStation cannot be made, display error.

void displayObjectRetrievalError()

If retrieving the turntable object fails, display error.

void displayStatus(const char *status)

Display the provided status text.

Parameters:

status – Char array of status text

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
file WiFiFunctions.cpp
#include “WiFiFunctions.h
file WiFiFunctions.h
#include “Defines.h
#include <Arduino.h>
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.

This README is very brief, and for the full documentation refer to Pete’s Pages.

Hardware required

This software has been written for either an STM32F411CEU6 Blackpill or Espressif ESP32 Dev board, with a connected rotary encoder and GC9A01 based LCD.

It also requires a serial connection to a DCC-EX CommandStation (either Blackpill or ESP32), or a WiFi connection (ESP32 only).

Pins and connections

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

Remember to cross Rx/Tx so that the Blackpill/ESP32 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 both the Blackpill and ESP32 are 3.3V uCs.

Connection

Blackpill pin

ESP32 pin

Serial Rx

PA10

16

Serial Tx

PA9

17

Rotary encoder button

PB15

25

Rotary encoder DT

PB14

26

Rotary encoder CLK

PB13

27

GC9A01 DIN

PA7

19

GC9A01 CLK

PA5

18

GC9A01 CS

PA4

15

GC9A01 DC

PA3

2

GC9A01 RST

PA2

4

GC9A01 BL

PA1

21

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:

  • Install board support for both STM32 and Espressif boards

  • Install the above libraries

  • Configure TFT_eSPI manually according to the library’s documentation

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.