Hier das Testprogramm zum vorherigen Beitrag:
/*************************************************************************
Testprogramm zum Testen von DCF-Modulen und DCF-Softwarefiltern
Es können entweder zwei DCF-Module gegeneinander getestet werden
Dazu die zwei Dateneingänge mit den Pins DCF_A_MODULE und DCF_B_MODULE verbinden
und die Zeile "#define B_IS_FILTERED_A" auskommentieren
Oder es kann ein DCF-Modul gegen einen Softwarefilter getestet werden
Beispielhaft ist der hier vorgestellte Filter eingebaut:
http://arduino.cc/forum/index.php?topic=135153.0
Dazu das DCF-Modul an den Pin DCF_A_MODULE anschliessen und
die Zeile "#define B_IS_FILTERED_A" in den Code einfügen
(Der Pin DCF_B_MODULE bleibt dann frei.)
**************************************************************************/
// Pin fuer DATA-Ausgang des DCF-Moduls
#define DCF_A_MODULE 2
// Pin fuer DATA-Ausgang des zweiten DCF-Moduls oder den Software-Filter
#define DCF_B_MODULE 3
// die nachfolgende Zeile auskommentieren, wenn zwei Module getestet werden sollen
#define B_IS_FILTERED_A
// (wenn "#define B_IS_FILTERED_A" gesetzt ist, den Pin für das DCF_B_MODULE freilassen!)
// legt fest, an welchem Pin eine LED blinken soll
#define LED 13
#ifdef B_IS_FILTERED_A
#include <MsTimer2.h>
#endif
char error[]="SYNC";
char noerror[]="";
void setup() {
Serial.begin(9600);
Serial.println();
pinMode(DCF_A_MODULE, INPUT);
pinMode(DCF_B_MODULE, INPUT);
pinMode(LED, OUTPUT);
#ifdef B_IS_FILTERED_A
pinMode(DCF_B_MODULE, OUTPUT);
MsTimer2::set(1, low_pass_filter);
MsTimer2::start();
#endif
}
#ifdef B_IS_FILTERED_A
void low_pass_filter() {
// http://en.wikipedia.org/wiki/Low-pass_filter#Continuous-time_low-pass_filters
// I will use fixed point arithmetics with 5 decimals
const uint16_t decimal_offset = 10000;
static uint32_t smoothed = 0*decimal_offset;
const uint32_t input = digitalRead(DCF_A_MODULE) * decimal_offset;
// const uint32_t input = analogRead(dcf77_analog_sample_pin)>200? decimal_offset: 0;
// compute N such that the smoothed signal will always reach 50% of
// the input after at most 50 samples (=50ms).
// N = 1 / (1- 2^-(1/50)) = 72.635907286
const uint16_t N = 72;
smoothed = ((N-1) * smoothed + input) / N;
// introduce some hysteresis
static uint8_t square_wave_output = 0;
if ((square_wave_output == 0) == (smoothed >= decimal_offset/2)) {
// smoothed value more >= 50% away from output
// ==> switch output
square_wave_output = 1-square_wave_output;
// ==> max the smoothed value in order to introduce some
// hysteresis, this also ensures that there is no
// "infinite memory"
smoothed = square_wave_output? decimal_offset: 0;
digitalWrite(DCF_B_MODULE, square_wave_output); //changed jurs
}
}
#endif
boolean
BdcfState,AdcfState,
lastBdcfState=false,
lastAdcfState=false;
byte
AdcfBitval,BdcfBitval;
long
looptime,
lastAdcfH,lastAdcfL,
lastBdcfH,lastBdcfL,
AdcfShortPulses,BdcfShortPulses,
AdcfLastPulse,BdcfLastPulse,
AdcfHighcycle, BdcfHighcycle;
void loop() {
// looptime=millis()%100000L; // last 5 digits
looptime=millis();
AdcfState=digitalRead(DCF_A_MODULE);
BdcfState=digitalRead(DCF_B_MODULE);
digitalWrite(LED,BdcfState);
CheckForHighCycle(looptime, AdcfState, lastAdcfState, AdcfHighcycle, lastAdcfH, lastAdcfL, AdcfShortPulses);
CheckForHighCycle(looptime, BdcfState, lastBdcfState, BdcfHighcycle, lastBdcfH, lastBdcfL, BdcfShortPulses);
printIfValidPulse('A', looptime, AdcfHighcycle, AdcfLastPulse, AdcfShortPulses, AdcfBitval, BdcfBitval, BdcfLastPulse);
printIfValidPulse('B', looptime, BdcfHighcycle, BdcfLastPulse, BdcfShortPulses, BdcfBitval, AdcfBitval, AdcfLastPulse);
}
void printIfValidPulse(char c, long ltime, long &Highcycle, long &LastPulse, long &ShortPulses, byte &Bitval, byte OtherBitval, long LastOtherPulse)
{
char *msg;
char bitError;
char buf[32];
if ((Highcycle>=50)&&(Highcycle<=250))
{
// Falls mehr als 1500 ms kein Impuls ==> SYNC (Minutenimpuls oder Sync-Error)
if (looptime>LastPulse+1500) msg=error; else msg=noerror;
// > 150 ms HIGH => 1-Bit, 50...150 ms HIGH => 0-Bit
if (Highcycle>150) Bitval=1; else Bitval=0;
// Biterror falls innerhalb der letzten 500 ms ein anderes Bit am anderen Eingang gemeldet wurde
bitError=' ';
// Biterror erkennen, falls weniger als 500 ms vorher ein anderes Bit am anderen Eingang erkannt wurde
if ((looptime<LastOtherPulse+500)&&(Bitval!=OtherBitval)) bitError='*';
// Biterror erkennen, falls der letzte Pulse vom selben Eingang kam
if (LastPulse>LastOtherPulse) bitError='#';
LastPulse=looptime;
sprintf(buf,"%c %d %3ld %3ld %05ld%c%s", c, Bitval, Highcycle, ShortPulses,looptime%100000L,bitError,msg);
Serial.println(buf);
Highcycle=0;
ShortPulses=0;
}
}
void CheckForHighCycle(long looptime, boolean &State, boolean &lastState, long &Highcycle, long &lastH, long &lastL, long &ShortPulses)
{
if (State!=lastState)
{
if (State==LOW)
{
Highcycle=looptime-lastH;
if (Highcycle<50) ShortPulses++;
lastL=looptime;
}
else lastH=looptime;
lastState=State;
}
}