Thanks for the replies everyone!
PaulS:
I use tone() to generate the waveforms for test
There was some discussion a while back (on the old forum, I think) that, if I remember correctly, came to the conclusion that the way tone is written it can not generate accurate output below 31 Hz. Perhaps this is the root of your problem.
If this is true - then this would be a major problem, and this limitation should be added to the documentation at http://www.arduino.cc/en/Reference/Tone. Do you know how I can read the code for tone()?
I have also tested this with both un-debounced and hardware debounced switches however, and the results are way off unless the presses are extremely short. This is why I was doing the testing with the waveform.
I had been using the tone() hack to test this in order to avoid having to use a waveform generator or an O scope, as I have neither. I guess at some point I'll have to make some investments..
Graynomad:
duration is an int?
duration is a globally declared unsigned long.
The comments are correct, but what we think something is and what they actually are can be quite different things. That's why you need to have someone else look at all the code.
Rob
As to the first comment, I'm fairly sure that unsigned long is the way to go. This is a quote from the documentation for pulsein():
"Returns the length of the pulse (in microseconds) or 0 if no pulse started before the timeout (unsigned long)"
Since an unsigned long is an integer data type, this makes sense. As for the second point, here is the rest of the code. I tried unsigned int and int as well, as you will see in the comments:
/*
designed to run on the "duemilanove" prototype board equipped with an ATmega328 microprocessor
*/
// global constants
// set pin numbers:
const int buttonPin = 7; // the number of the pushbutton pin (I tried an alternate pin to make sure it wasn't a faulty input problem)
const int wavePin = 4; // the number of the test waveform pin
// global variables
int buttonState = 0; // variable for reading the pushbutton status
int controlTone = 0; // used to control the tone call for waveform testing
unsigned long duration; // shouldn't be the problem b/c this data type ranges from 0 to 4,294,967,295 (2^32 - 1).
//unsigned int duration; //
//int duration; //
//======================================================================
//======================================================================
void setup() {
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
// initialize a pin for outputting a waveform to test the input
pinMode(wavePin, OUTPUT);
// -----------------------------------
Serial.begin(9600); // Start serial communication at 9600 bps
// -----------------------------------
}
//======================================================================
//======================================================================
// the program main loop initializes the testing tone generator
// and then listens for a pulse on pin 7 (buttonPin)
//
void loop(){
// this if statement is used to turn on the tone generator.
// this is used only to generate a test waveform
if (controlTone == 0) { // here, we're making sure it gets turned on only once
Serial.println("about to turn on the tone generator");
controlTone = 1;
//tone(wavePin, 1000); // pin, frequency in hertz, duration in ms (optional) - leaving it running
//tone(wavePin, 100); // pin, frequency in hertz, duration in ms (optional) - leaving it running
//tone(wavePin, 10); // pin, frequency in hertz, duration in ms (optional) - leaving it running
//tone(wavePin, 50); // pin, frequency in hertz, duration in ms (optional) - leaving it running
//tone(wavePin, 40); // pin, frequency in hertz, duration in ms (optional) - leaving it running
tone(wavePin, 30); // pin, frequency in hertz, duration in ms (optional) - leaving it running
//tone(wavePin, 35); // pin, frequency in hertz, duration in ms (optional) - leaving it running
//tone(wavePin, 34); //
//tone(wavePin, 33); //
//tone(wavePin, 32); //
//tone(wavePin, 31); //
Serial.println("tone generator should be running on pin 4 at this point");
//Serial.println("1000 hertz 50% duty cycle"); // -- works -- reads as 493 or 486 (~0.5 miliseconds)
//Serial.println("100 hertz 50% duty cycle"); // -- works -- reads as 4954 or 4960 (~5.0 miliseconds)
//Serial.println("10 hertz 50% duty cycle"); // -- fails -- reads as 818 (.818 miliseconds - should be 50)
//Serial.println("50 hertz 50% duty cycle"); // -- works -- reads as 9922 (9.92 miliseconds)
//Serial.println("40 hertz 50% duty cycle"); // -- works -- reads as 12398, '396 or '400 (12.4 miliseconds)
Serial.println("30 hertz 50% duty cycle"); // -- fails -- reads as 246 or 249 (~0.20 miliseconds)
//Serial.println("35 hertz 50% duty cycle"); // -- works -- reads as 14178 or ' 9 (14.2 miliseconds)
//Serial.println("34 hertz 50% duty cycle"); // -- works -- reads as 14557 or '6 (14.6 miliseconds)
//Serial.println("33 hertz 50% duty cycle"); // -- works -- reads as 15010 or '12 (15.0 miliseconds)
//Serial.println("32 hertz 50% duty cycle"); // -- works -- reads as 15516 or '7 (15.5 miliseconds)
//Serial.println("31 hertz 50% duty cycle"); // -- works -- reads as 16022, 29 or 27 (16.0 miliseconds)
}
//----------------------------------------------------------- //
//------------ This is the main program loop --------------- //
duration = pulseIn(buttonPin, LOW); // gives pulsewidth in microseconds
if (duration != 0) { printout(); }
//------------ This is the main program loop --------------- //
//----------------------------------------------------------- //
}
//======================================================================
//======================================================================
// the printout subroutine prints ascii to the serial line
void printout(){
// here we report the raw data, which is in microseconds:
Serial.println(" ");
Serial.println(duration, DEC);
Serial.println("------");
return;
}
// END OF PROGRAM
//======================================================================
//======================================================================