OK, so I'm trying to play the GMT pips with my Arduino. It works great. Because I'm still waiting for my ethernet shield, I have no way of setting my RTC accurately (the compile delay means it's 15 seconds slow). If there's a way to say RTC.adjust(DateTime(__DATE__, __TIME__+15s)); it's news to me
At the moment I compensate for it in my code. This is OK as an interim solution.
If you are calling playTone(900,0), then you have a 'divide by zero' condition. I'm not sure what the Atmega does under those circumstances, but it might well explain your symptoms.
dxw00d:
If you are calling playTone(900,0), then you have a 'divide by zero' condition. I'm not sure what the Atmega does under those circumstances, but it might well explain your symptoms.
hmm.. thanks. I've tried the following:
First I tried to eliminate the need for "delay" by calling if statements to play the pip for each second, but of course the pips all merged into one because I wasn't able to call per ms.
Then I tried writing code using the blink without delay example. But I found that the blink without delay example sets a pin to HIGH, whereas I need to tell a function to go to work.
DateTime now = RTC.now();
if (now.second() == 54 && now.minute() == 59)
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you sounded the buzzer
previousMillis = currentMillis;
// if the buzzer is off turn it on and vice-versa:
if (buzzerState == LOW)
buzzerState = HIGH;
else
buzzerState = LOW;
// set the buzzer with the buzzerState of the variable:
playTone(100, 2000);
}
}
To do that you would use the technique demonstrated in 'blink without delay' to detect when it was time to start and end each note, and define a function (for example 'outputTone()') to poll the clock and see whether it was time to change the output. Your existing function 'playTone()' would configure the variable used by outputTone() to tell it what tone and duration it was supposed to be playing. Your loop() function would call outputTone() and then go on to do whatever else you wanted to happen at the same time as playing the tones.
I don't have a buzzer, so I tried the on-board LED as a "speaker" and adapted the cooperative multi-tasking code I referred you to elsethread to keep time in usec instead of msec. Providing my own tone generation code to produce the GTS "pips" looks like:
// 1 kHz tone has cycle every 1 msec or 1000 usec (500 usec up, 500 usec down)
// 1/10 sec = 100 msec = 100,000 usec = 100 cycles short pip
// 1/2 sec = 500 msec = 500,000 usec = 500 cycles long pip
// typedef unsigned long long time_t /* Define the time_t data type */
#define time_t unsigned long long /* Arduino 1.0 can't handle typedef */
// typedef void (*fptr_t)(); /* Define the fptr_t data type */
#define fptr_t(x) void(*x)() /* Arduino 1.0 can't handle typedef */
int aftr(time_t dlay,fptr_t(what));
unsigned long_pip;
unsigned short_pip;
unsigned cycles;
unsigned busy;
void cycle_down(void)
{ digitalWrite(13,LOW);
if (--cycles) aftr(500,cycle_up);
else
{ if (short_pip > 1)
{ --short_pip;
cycles = 100;
aftr(900000,cycle_up);
}
else
{ if (long_pip)
{ long_pip = 0;
cycles = 500;
aftr(900000,cycle_up);
}
else aftr(2000000,unbusy);
}
}
}
void unbusy(void)
{ busy = 0;
}
void cycle_up(void)
{ if (busy)
{ digitalWrite(13,HIGH);
aftr(500,cycle_down);
}
}
void gts(void)
{ while (busy) idle();
busy = 1;
long_pip = 1;
short_pip = 5;
cycles = 100;
cycle_up();
}
void setup(void)
{ pinMode(13,OUTPUT);
busy = 0;
delay(1000);
}
void loop(void)
{ gts();
while (busy) idle();
}
In place of audio tones, my on-board LED does the tones with half-bright (because of the duty cycle) pips - and it's running as I type.
DANE:
Hi, in an effort to do some coding myself, I wrote the following:-
Do you think it'll work? I'm at work so can't test. But I will when I get home...
If you can write it at work then you can test it at work.