I am working on an project to try and set our WWVB radio controlled clock using an Uno.
I was inspired by this project using an attiny chip. http://www.instructables.com/id/WWVB-radio-time-signal-generator-for-ATTINY45-or-A/.
I am using this PWM frequency library, http://forum.arduino.cc/index.php?topic=117425.0 to get a 60kHz wave.
I am modifying the duty cycle of the waveform in a similar fashion as the attiny project. I have about a 4 foot wire acting as my antenna connected to pin 9. I have verified that I do get a 60kHz wave on an oscilloscope. But my clock won’t set. Here is my sketch.
#include <PWM.h>
int led = 9; // the pin that the LED is attached to
int32_t frequency = 60000; //frequency (in Hz)
unsigned long previous_time ;
int frame = 0 ;
void setup() {
//initialize all timers except for 0, to save time keeping functions
InitTimersSafe();
//sets the frequency for the specified pin
bool success = SetPinFrequencySafe(led, frequency);
uint16_t frequency = Timer1_GetFrequency();
uint16_t decimalResolution = Timer1_GetTop() + 1;
uint16_t binaryResolution = GetPinResolution(led);
char strOut[75];
sprintf(strOut, "Frequency: %u Hz\r\n Number of Possible Duties: %u\r\n Resolution: %u bit\r\n", frequency, decimalResolution, binaryResolution );
Serial.begin(115200);
Serial.println(strOut);
// Use built-in LED to for visual confirmation of output signal.
pinMode(13, OUTPUT);
pwmWrite( led , 128 ) ;
digitalWrite(13, HIGH);
previous_time = millis() ;
}
// flash LED to mirror output signal.
void reduce_power( long time ) {
pwmWrite(led , 5 ) ;
digitalWrite(13, LOW);
delay( time ) ;
pwmWrite(led , 128 ) ;
digitalWrite(13, HIGH);
}
// Fake time and date
int hours = 6 ;
int minutes = 12 ;
int days_of_year = 267 ;
int year = 14 ;
void loop() {
unsigned long current_time = millis() ;
if ( current_time - previous_time > 1000 ) {
int signal ;
int hours_tens, hours_ones ;
int minutes_tens, minutes_ones ;
int temp_days_of_year, days_of_year_hundreds , days_of_year_tens , days_of_year_ones ;
int year_tens , year_ones ;
hours_tens = hours / 10 ;
hours_ones = hours - hours_tens * 10 ;
minutes_tens = minutes / 10 ;
minutes_ones = minutes - minutes_tens * 10 ;
days_of_year_hundreds = days_of_year / 100 ;
temp_days_of_year = days_of_year - days_of_year_hundreds * 100 ;
days_of_year_tens = temp_days_of_year / 10 ;
days_of_year_ones = temp_days_of_year - days_of_year_tens * 10 ;
year_tens = year / 10 ;
year_ones = year - year_tens * 10 ;
switch (frame) {
case 0 : signal = 2; break; // marker
case 1 : signal = (minutes_tens >> 2) & 1; break; // min 40
case 2 : signal = (minutes_tens >> 1) & 1; break; // min 20
case 3 : signal = (minutes_tens >> 0) & 1; break; // min 10
case 4 : signal = 0; break; // unused
case 5 : signal = (minutes_ones >> 3) & 1; break; // min 8
case 6 : signal = (minutes_ones >> 2) & 1; break; // min 4
case 7 : signal = (minutes_ones >> 1) & 1; break; // min 2
case 8 : signal = (minutes_ones >> 0) & 1; break; // min 1
case 9 : signal = 2; break; // marker
case 10 : signal = 0; break; // unused
case 11 : signal = 0; break; // unused
case 12 : signal = (hours_tens >> 1) & 1; break; // hour 20
case 13 : signal = (hours_tens >> 0) & 1; break; // hour 10
case 14 : signal = 0; break; // unused
case 15 : signal = (hours_ones >> 3) & 1; break; // hour 8
case 16 : signal = (hours_ones >> 2) & 1; break; // hour 4
case 17 : signal = (hours_ones >> 1) & 1; break; // hour 2
case 18 : signal = (hours_ones >> 0) & 1; break; // hour 1
case 19 : signal = 2; break; //marker
case 20 : signal = 0; break; // unused
case 21 : signal = 0; break; // unused
case 22 : signal = (days_of_year_hundreds >> 1) & 1; break; // day 200
case 23 : signal = (days_of_year_hundreds >> 0) & 1; break; // day 100
case 24 : signal = 0; break; // unused
case 25 : signal = (days_of_year_tens >> 3) & 1; break; // day 80
case 26 : signal = (days_of_year_tens >> 2) & 1; break; // day 40
case 27 : signal = (days_of_year_tens >> 1) & 1; break; // day 20
case 28 : signal = (days_of_year_tens >> 0) & 1; break; // day 10
case 29 : signal = 2; break ; // marker
case 30 : signal = (days_of_year_ones >> 3) & 1; break; // day 8
case 31 : signal = (days_of_year_ones >> 2) & 1; break; // day 4
case 32 : signal = (days_of_year_ones >> 1) & 1; break; // day 2
case 33 : signal = (days_of_year_ones >> 0) & 1; break; // day 1
case 34 : signal = 0; break; // unused
case 35 : signal = 0; break; // unused
case 36 : signal = 0; break; // DUT1 +sign
case 37 : signal = 1; break; // DUT1 -sign
case 38 : signal = 0; break; // DUT1 +sign
case 39 : signal = 2; break; // marker
case 40 : signal = 0; break; // DUT1 0.8
case 41 : signal = 0; break; // DUT1 0.4
case 42 : signal = 1; break; // DUT1 0.2
case 43 : signal = 1; break; // DUT1 0.1
case 44 : signal = 0; break; // unused
case 45 : signal = (year_tens >> 3) & 1; break; // year 80
case 46 : signal = (year_tens >> 2) & 1; break; // year 40
case 47 : signal = (year_tens >> 1) & 1; break; // year 20
case 48 : signal = (year_tens >> 0) & 1; break; // year 10
case 49 : signal = 2; break; // marker
case 50 : signal = (year_ones >> 3) & 1; break; // year 8
case 51 : signal = (year_ones >> 2) & 1; break; // year 4
case 52 : signal = (year_ones >> 1) & 1; break; // year 2
case 53 : signal = (year_ones >> 0) & 1; break; // year 1
case 54 : signal = 0; break; // unused
case 55 : signal = 0; break; // leap year indicator
case 56 : signal = 0; break; // leap second at end of month
case 57 : signal = 1; break; // DST status 2
case 58 : signal = 1; break; // DST status 1
case 59 : signal = 2; break; // marker
default : signal = 0; break; // unused (should not happen)
}
switch ( signal ) {
case 0: reduce_power(200) ; break ;
case 1: reduce_power(500) ; break ;
case 2: reduce_power(800) ; break ;
}
previous_time += 1000 ;
frame++ ;
if ( frame >= 60 ) {
frame = 0 ;
minutes++ ;
}
}
}
I’m not sure if I’m modulating the wave in a way a radio clock can pick up and understand, or if I have an error in my sketch. Could someone take a look?