DCC (block current) Detector
This runs on a local block detector MCU.
In addition to interpreting channel 1 messages elsewhere, we monitor the block for occupancy, detecting non RailCom decoders and other loads. E.g coaches with lighting etc. This detection uses the same raw hardware detection as the RailCom channel 1 detector, but the signal is processed differently within the detector hardware and interpreted differently here.
The RailCom output from the detector is a digital signal, whereas this uses an analog output from the detector.
The detected current is amplified within the detector such that 1mA of track current appears at the analog input as cf * gain mV where cf is the track current to detector conversion factor (1.8) and gain (100) is the gain of the detector op. amp. This equates to 1mA => 180 mV. The signal is centred around a nominal 0V.
The op. amp. runs on 5 V and its outputs will saturate at about ± 14mA of input current. If using resistor wheel sets, a typical value is 10 kΩ and thresholds can be set at c. 1mA to detect these.
This inherits from the Device Class.
- Block status may be:
- empty
- occupied
- unknown (start of day)
- unpowered (no DCC power)
| Method | __init__ |
Construct the block current detector |
| Method | report |
Report Event |
| Async Method | wait |
Wait for the new state available event |
| Property | index |
Block Logical Index Number |
| Property | sensor |
Current block state |
| Async Method | _get |
Get Reading Pair |
| Async Method | _monitor |
Coroutine to monitor current |
| Class Variable | _i2c |
Undocumented |
| Instance Variable | _av |
Undocumented |
| Instance Variable | _blk |
Undocumented |
| Instance Variable | _id |
Undocumented |
| Instance Variable | _index |
Undocumented |
| Instance Variable | _offset |
block state may be unknown, empty, occupied |
Construct the block current detector
This constructs the block current detector.
The base Device class is initiated with the block name and type. Inititial values are set.
| Parameters | |
| blk | the name of the block |
| i | logical block number |
Report Event
This overrides the Device.report_event method. It sets the event flag to indicate block status change.
| Parameters | |
| event | updated Block status code. |
| data | a tuple containing address type, address & orientation |
Block Logical Index Number
Index number as supplied. May be used for line number on screen and LED indicator.
Current block state
This returns the current sensor state. The block status may be: - Device.UNKNOWN: the block state is unknown - Device.BLK_EMPTY: the block is empty - Device.BLK_OCC: the block is occupied
Get Reading Pair
We take a set of raw readings. Currently hard coded at ten. Raw readings may be +ve or -ve. The set is processed to determine the absolute maximum value relative to the zero offset. We also determine the average value. This is used to determine the zero offset.
Both values are returned.
Coroutine to monitor current
This periodically reads the current sense analog input pin.
The readings are processed to derrive two values.
Firstly the base value representing 0 current is obtained. This assumes that over a period of time that is sufficiently long compared with the DCC frequency and other periodic factors, the net current flow is zero. I.e there is no DC component in the current flow. Note that RailCom doesn't permit '0' stretching. The readings are filtered using a low pass Infinite Impulse Response (IIR) digital filter and the result is taken as being the zero offset. In theory the DCC signal measurement now uses a differential ADC so the offset should be 0 but in practice a small offset remains, possibly due to an offset error in the analogue amplifier.
Secondly the value representing the current load is calculated. The input to this is the magnatude of the difference between the zero offset value and the reading. I.e. the absolute value without sign. The reading sampling runs asynchronously with respect to DCC and RailCom cutout timings. Atypically low values are assumed to be samples taken at DCC polarity change or during the RailCom cutout.
The filtered values are compared with two thresholds to determine whether the block is occupied. The thresholds apply hysterisis to avoid hunting.
The coroutine task runs forever.