rasProject_01 / weSweetHome  R. 240
process control       /     RasPi software         by   weinert-automation
Loading...
Searching...
No Matches
weDCF77.h File Reference

DCF77 decoder on Raspberry Pi. More...

#include <basicTyCo.h>
#include "weGPIOd.h"
#include "weUtil.h"

Data Structures

struct  dcf77recPerData_t
 Data for one received DCF77 AM period. More...
 
struct  durDiscrPointData_t
 Values for discrimination of duration. More...
 

Macros

#define DCF77inpDEF
 Default GPIO for the DCF77 receiver's AM signal input. More...
 
#define DCF77recCNTdef
 Recommended default GPIO for the receiver control output. More...
 
#define DCF77RINGbufWRAP
 Ring buffer maximum Index for modulation period data received. More...
 
#define MXUI32
 Maximum value for uint32_t.
 

Functions

void dcf77receiveRec (int pi, unsigned gpio, unsigned level, uint32_t tick)
 DCF77 receive recorder. More...
 
int dcf77receiveRecDeregister (void)
 DCF77 receive function de-registration. More...
 
int dcf77receiveRecRegister (void)
 DCF77 receive recorder registration. More...
 
durDiscrPointData_tdisc5 (durDiscrPointData_t table[], uint32_t const value)
 Discriminating a value. More...
 
uint32_t initDCF77io ()
 Initialise the DCF77 signal input GPIO / pin. More...
 
void setReceiver (int const level)
 Set receiver On control. More...
 

Variables

unsigned curBCDnum
 Number decoded from period sequence parts. More...
 
int dcf77callbackID
 PiGpioD's call back ID for receiver function.
 
unsigned dcf77glitch
 DCF77 input's glitch filter time setting. More...
 
unsigned dcf77inp
 Input GPIO for the DCF77 receiver's AM signal. More...
 
unsigned dcf77invInp
 Inverted DCF77 receiver's signal. More...
 
unsigned dcf77lastLevel
 Last DCF77 modulation level. More...
 
unsigned dcf77PUD
 DCF77 input's pull resistor setting. More...
 
unsigned dcf77recCnt
 Control output GPIO of the DCF77 receiver's control. More...
 
unsigned dcf77recCntInv
 Receiver On control inverted. More...
 
dcf77recPerData_t dfc77actRecPer
 The actual respectively last modulation period data received.
 
dcf77recPerData_t dfc77ringBrecPer []
 Ring buffer of modulation period data received.
 
uint8_t dfc77ringBrecWInd
 Modulation period data received ring buffer write index.
 
unsigned const num02st [5]
 see numBCDinit, values 0 2
 
unsigned const num04st [5]
 see numBCDinit, values 0 4
 
unsigned const num08st [5]
 see numBCDinit, values 0 8
 
unsigned const num10st [5]
 see numBCDinit, values 0 10
 
unsigned const num20st [5]
 see numBCDinit, values 0 20
 
unsigned const num40st [5]
 see numBCDinit, values 0 40
 
unsigned const num80st [5]
 see numBCDinit, values 0 80
 
unsigned const numBCDinit [5]
 Initialisation or least significant BDC digit for modulation time. More...
 
durDiscrPointData_t perDiscH [5]
 Discrimination values for the modulation period. More...
 
durDiscrPointData_t perDiscP [5]
 Discrimination values for the modulation period. More...
 
durDiscrPointData_tperDiscUsed
 Discrimination values for the modulation period used. More...
 
durDiscrPointData_t timDiscH [5]
 Discrimination values for the 15% modulation time. More...
 
durDiscrPointData_t timDiscHs [5]
 Discrimination values for the 15% modulation time. More...
 
durDiscrPointData_t timDiscP [5]
 Discrimination values for the 15% modulation time. More...
 
durDiscrPointData_ttimDiscUsed
 Discrimination values for the 15% modulation time. More...
 

Detailed Description

DCF77 decoder on Raspberry Pi.

Copyright (c) 2020 Albrecht Weinert
weinert-automation.de a-weinert.de
/ / /\
/ /___ / \ |
\ /____\ /____\ | _|__
\ /\ / \ / \| |
\/ \/ \__/ \__/|_

Revision history

Rev. 255 29.10.2023
Rev. 233 17.10.2020 : new
Rev. 234 05.12.2020 : minor, comment
Rev. 239 02.03.2021 : functions from dcf77onPi.c ported here

This is a supplementary basic library to handle the signal of a DCF77 receiver. In the case of AM (amplitude) modulation a 1 (high) at the signal input means 15% amplitude and a 0 (low) 100% respectively full amplitude. The other way round is marked as dcf77invInp.

Receivers

Devices used and tested are the AM receiver modules from several sources. See the blog post for results.
The first one is relatively cheap and widespread but a bit of low grade (to put it mildly) in the sense of inserting spiky 1 signals and sensitivity to electromagnetic interferences (EMI).
On the other hand, being able to extract sensible DCF77 from the Pollin module's signal is good report for the decoding and filtering algorithms and or extra circuitry used.

Macro Definition Documentation

◆ DCF77recCNTdef

#define DCF77recCNTdef

Recommended default GPIO for the receiver control output.

This is the default setting for the receiver control output dcf77recCnt. It is currently PIN23, i.e. GPIO 11 on Pi3/4/0.

◆ DCF77inpDEF

#define DCF77inpDEF

Default GPIO for the DCF77 receiver's AM signal input.

This is the default setting for the modulation signal input dcf77inp. The current setting is PIN10, i.e. GPIO 15 (UART in) on Pi3/4/0. The UART in special function of PIN10 might enable the use of raw DCF77 input drivers for NTP servers. Their implementors chose to use a UART instead of a simple binary input for the AM signal.

◆ DCF77RINGbufWRAP

#define DCF77RINGbufWRAP

Ring buffer maximum Index for modulation period data received.

In the current implementation the value is fixed to 255 as it uses uint8_t for all indexes and counters utilising the wrap around. For any other value change all code in question.

Hint for changes;
The value should cover more than two minutes for handling startup and receiver noise.
And it should be (a power of 2) - 1.

Function Documentation

◆ setReceiver()

void setReceiver ( int const  level)

Set receiver On control.

Parameters
levelset receiver ON or OFF
See also
dcf77recCnt, dcf77recCntInv

◆ initDCF77io()

uint32_t initDCF77io ( )

Initialise the DCF77 signal input GPIO / pin.

The signal input dcf77inp and control output dcf77recCnt are initialised.

Returns
the bank mask of the output dcf77recCnt if given, 0 if PINig

◆ dcf77receiveRec()

void dcf77receiveRec ( int  pi,
unsigned  gpio,
unsigned  level,
uint32_t  tick 
)

DCF77 receive recorder.

This is a pigpiod callback function for an AM DCF77 receiver. It does no filtering nor decoding. It just fills dfc77actRecPer for the current modulation period and stores it in dfc77ringBrecPer when the next period begins.

◆ dcf77receiveRecRegister()

int dcf77receiveRecRegister ( void  )

DCF77 receive recorder registration.

This function registers the call back function dcf77receiveRec with the PiGpioDaemon.

Returns
register or error number; also stored in dcf77callbackID

◆ dcf77receiveRecDeregister()

int dcf77receiveRecDeregister ( void  )

DCF77 receive function de-registration.

This function de-registers the call back registered under dcf77callbackID.

Returns
0: OK, pigif_callback_not_found: otherwise

◆ disc5()

durDiscrPointData_t * disc5 ( durDiscrPointData_t  table[],
uint32_t const  value 
)

Discriminating a value.

In a discrimination table / array of length 5 this function returns a pointer to the highest table entry with value >= table[i].v
The entry returned must be treated as const.

Parameters
tablediscrimination table of length 5. With other lengths the function will fail. Must not be null.
valuethe number to be discriminated
Returns
the lowest table entry with value < table[i].v

Variable Documentation

◆ dcf77recCnt

unsigned dcf77recCnt
extern

Control output GPIO of the DCF77 receiver's control.

This output, if used and connected, controls the amplitude modulation (AM) receiver's control (On/Off) signal. If there is no such output (PINig) The receiver either has no such control input or it is tight to On.

default PINig; see also dcf77recCntInv, setReceiver()

◆ dcf77recCntInv

unsigned dcf77recCntInv
extern

Receiver On control inverted.

The receiver control output (dcf77recCnt), when used, would be set to ON (Hi, 3V) to enable the receiver. And it would be set OFF for a short time to reset a panicing or inactive receiver.
If dcf77recCntInv is true it is the other way round. The common receiver chips control input is low active, hence inverted and dcf77recCntInv should be true. As an open collector stage near the Pi for this output is highly recommended, nevertheless the default value is FALSE.

default FALSE; see also dcf77recCnt, setReceiver()

◆ dcf77inp

unsigned dcf77inp
extern

Input GPIO for the DCF77 receiver's AM signal.

This is the amplitude modulation (AM) level signal; the level is either 100% or 15% (for 100 or 200ms).

default PIN08; see also dcf77invInp, dcf77PUD, dcf77glitch

◆ dcf77invInp

unsigned dcf77invInp
extern

Inverted DCF77 receiver's signal.

In the case of AM (amplitude) modulation a 1 (high) at the signal input dcf77inp means 15% amplitude and a 0 (low) 100% respectively full amplitude, when dcf77invInp is OFF. ON, obviously, means other way round.

default: OFF; see also dcf77inp

◆ dcf77PUD

unsigned dcf77PUD
extern

DCF77 input's pull resistor setting.

default: PI_PUD_KEEP; see also dcf77inp

◆ dcf77glitch

unsigned dcf77glitch
extern

DCF77 input's glitch filter time setting.

The value for pigpiod's input filter time in μs. The allowed range is 0 ... 30000. The filtering only works for pins sampled by a callback function (like dcf77receiveRec()).

default: 0; glitch filter off; see also dcf77inp

◆ dcf77lastLevel

unsigned dcf77lastLevel
extern

Last DCF77 modulation level.

ON means 15% modulation amplitude; i.e. the signal.
OFF means 100% amplitude; i.e. just the 77,5 kHz carrier.

This variable is set by the receiver (callback) function and must not be modified by user software.

◆ timDiscP

durDiscrPointData_t timDiscP[5]
extern

Discrimination values for the 15% modulation time.

This is an array of fixed length 5 to discriminate dcf77recPerData_t::tim values.
The only good outcomes of discrimination are indices (durDiscrPointData_t::i) 1 and 3 meaning a recognisable bit 0 respectively 1.
Hint: index bit 0 set means no error.
Hint2: Name ending with P means designed for low grade AM receiver modules. The criteria values are extended quite far for guessing the meaning in the presence of timing faults. Spikes would have to be filtered in a next stage by combining two to four faulty periods in one. Low grade receivers would be not usable without such (complex) filter algorithms.

◆ perDiscP

durDiscrPointData_t perDiscP[5]
extern

Discrimination values for the modulation period.

This is an array of fixed length 5 to discriminate dcf77recPerData_t::per values.
The only good outcomes of discrimination are indices (durDiscrPointData_t::i) 1 and 3 meaning an acceptable 1s respectively 2s period.
Hint: See hints at timDiscP.

◆ timDiscH

durDiscrPointData_t timDiscH[5]
extern

Discrimination values for the 15% modulation time.

This is an array of fixed length 5 to discriminate dcf77recPerData_t::tim values.
The good outcomes have indices (durDiscrPointData_t::i) 1 and 3 meaning a recognisable bit 0 (FALSE) respectively 1 (TRUE).
Hint: index bit 0 set means no error.

Hint2: Name ending with H means designed for high grade AM receiver modules with virtually no timing faults or spikes. Hence, the criteria values are relatively tight, to recognise EMI or short outages as such. Trying to interpret those with filter algorithms may not be worth the effort with good receivers.

Hint3: Some lower grade AM receiver modules were enhanced with an inverting NPN transistor stage with a low capacity collector to ground capacitor implemented by three meter shielded signal and supply cable. This adding of a simple inverter stage is recommended for all receiver modules not equipped with an open collector (OC) output stage. And for some of them its a necessary filter stage.

◆ timDiscHs

durDiscrPointData_t timDiscHs[5]
extern

Discrimination values for the 15% modulation time.

This is an array of fixed length 5 to discriminate dcf77recPerData_t::tim values.
It is the same as timDiscH except for the extra note/hint 4.

Hint 4: The price for turning bad to good receivers by the circuit of Hint 3 was good pulses shortened well below 100 respectively 200 ms. Therefore this table allows for such shortened pulses noting it by the name's suffix s.

◆ perDiscH

durDiscrPointData_t perDiscH[5]
extern

Discrimination values for the modulation period.

This is an array of fixed length 5 to discriminate dcf77recPerData_t::per values.
The only good outcomes of discrimination are indices (durDiscrPointData_t::i) 1 and 3 meaning an acceptable 1s respectively 2s period.
Hint: See hints at timDiscHs.

◆ perDiscUsed

durDiscrPointData_t* perDiscUsed
extern

Discrimination values for the modulation period used.

This is a pointer to an array of fixed length 5 to discriminate dcf77recPerData_t::per values. The purpose is to hold the current filter values.
default: perDiscP

◆ timDiscUsed

durDiscrPointData_t* timDiscUsed
extern

Discrimination values for the 15% modulation time.

This is a pointer to an array of fixed length 5 to discriminate dcf77recPerData_t::per values. The purpose is to hold the current filter values.
default: timDiscP

◆ curBCDnum

unsigned curBCDnum
extern

Number decoded from period sequence parts.

This variable holds the (current) number evaluated by considering the sequence of disc5(timDiscUsed, modulationTime) in question. Here, with number sequences a false (level 1, 'F') means 0 and a true (level 3, 'T') means 1, 2, 4, 8, 10, 20, 40 or 80 depending on the place within the BCD coded number. Any other level (0 spike, 3 undef, 4 error) invalidates the whole number.
Values 0..99 (max year) are OK, a value above means an error in the sequence.

See also
disc5 timDiscUsed timDiscHs

◆ numBCDinit

unsigned const numBCDinit[5]
extern

Initialisation or least significant BDC digit for modulation time.

For the durDiscrPointData_t i value as index this constant array yields 0 or 1 — or respectively 2, 4 , 8, 10, 20, 40, 60 and 80 — for valid times and a high error value else.
The rationale is just adding up yields a correct value in the BCD range of 0 .. 99 while any higher value means error.

See also
timDiscUsed timDiscHs disc5() curBCDnum