I just started programming with arduino few days ago and i'm currently having problems with millis(). So i wanted to measure the time between two button pushes by using millis(), but I'm not getting the exact time. So the code is written something like this:
volatile int i;
unsigned long begin, start, stop, prev;
void setup()
{
attachInterrupt(0, time, RISING);
begin = millis();
}
void time()
{
i++;
start = millis(); //get initial time
if(i >= 2) //start if i = 2
{
stop = start - prev; // time between two pushed buttons
}
prev = start; //save initial time
}
I timed the pushing of buttons with a timer, but the time from the code is delayed. For example timer showed 30s and only 15s from the code. Did i wrote it wrong?
Well I currently don't have arduino ATM but using a simulator (from https://circuits.io/, using micro). I wanted to get a feel of the environment first before buying the actual piece.
Your help and advice is highly appreciated! sorry for the bad english.[/code]
Ok so you have a pull down (that was my question about RISING) and when you press your button D7 goes to 5V
So you modified the attach interrupt to be 4 so that it matches with pin d7, right?
Not sure why you would need begin at all. Might be the simulator not starting millis() or something because you don't have a loop()?
Never used that simulator - is the loop mandatory?
I'm also not sure about adding begin in the loop. I've seen similar codes without it. Yeah, maybe its just the simulator (not sure maybe an emulator). Anyway, thanks for helping!
When you run your sketch on real hardware you will need to use Serial Monitor for output.
volatile int ButtonPressCount;
volatile unsigned long Interval;
volatile boolean DataReady = false;
void setup() {
Serial.begin(19200);
pinMode(7, INPUT); // Not sure this is needed but attachInterrupt() doesn't set the mode.
attachInterrupt(4, ButtonISR, RISING); // int4 = Pin 7 on Arduino Micro
}
void loop() {
noInterrupts(); // Prevent the ISR from changing data while we're using it
if (DataReady) {
unsigned long copy_of_Interval = Interval;
int copy_of_ButtonPressCount = ButtonPressCount;
DataReady = false;
interrupts(); // We have copies of the volatile data so we can allow more interrupts.
Serial.print(F("Interval ending with press "));
Serial.print(copy_of_ButtonPressCount);
Serial.print(F(" is "));
Serial.print(copy_of_Interval);
Serial.println(F(" milliseconds."));
} else
interrupts();
}
void ButtonISR() {
unsigned long m = millis();
static unsigned long prev;
ButtonPressCount++;
if (ButtonPressCount > 1) {
Interval = m - prev; // time between two interrupts
DataReady = true;
}
prev = m; //save as start time for next interval
}
When you run your sketch on real hardware you will need to use Serial Monitor for output.
Yes sir i was using Serial to monitor values. didn't wrote it in the above code though.BTW, thanks for introducing me to noInterrupts() and interrupt().
I also found the culprit for the delayed time intervals.The simulator was running slow, like for 1 sec real time = 3 sec simulator time, probably for my advantage (for beginners). Didn't notice it until i started using millis().
Consider what switch bounce is doing to your interrupt. Per Jack Ganssle in Debouncing Contacts Part 2, "The undebounced switch must connect to a programmed I/O pin, never to an interrupt."