It's a simple question. I want to use buttons simultaneously and if it is a blocking function my inputs wouldn't register... Right?
This is not the right question.
The attachInterrupt() function just connects a function with an interrupt - it does not do anything that could be considered "blocking".
There is no need to use interrupts to detect buttons that humans press. An Arduino is perfectly fast enough to give the appearance of an instantaneous response just by polling the pins connected to the buttons.
...R
Seems like the OP might be using interrupts to fix some code they have elsewhere that they have been told is "blocking".
Sounds like a classic X-Y problem to me...
daisy_merollin:
It's a simple question. I want to use buttons simultaneously and if it is a blocking function my inputs wouldn't register... Right?
do you think it blocks until an interrupt occurs? it doesn't
Robin2:
This is not the right question.The attachInterrupt() function just connects a function with an interrupt - it does not do anything that could be considered "blocking".
There is no need to use interrupts to detect buttons that humans press. An Arduino is perfectly fast enough to give the appearance of an instantaneous response just by polling the pins connected to the buttons.
...R
I want to use buttons while reading inputs from hall effect sensors. I'm using millis in my code everywhere so I can't use delay (or sth like that) whatsoever because they are blocking functions (I'm told.) And I read in the Arduino's reference website thing and it says millis doesn't work in attachInterrupt function. So I was just wondering if I can still press my buttons while the code is inside the interrupt.
And I read in the Arduino's reference website thing and it says millis doesn't work in attachInterrupt function.
You misread it.
millis may not work in the attached interrupt function (when called), but nothing at all to do with attachInterrupt
daisy_merollin:
And I read in the Arduino's reference website thing and it says millis doesn't work in attachInterrupt function.
You need to explain why you want to use an interrupt and what you want your interrupt function to do.
Like I said in Reply #1, the attachInterrupt() function only makes a link between an interrupt and a function. The attachInterrupt() call probably only takes a few microsecs and usually you only call it once from setup()
...R
daisy_merollin:
I want to use buttons while reading inputs from hall effect sensors.
How many hall effect sensors you have? In which DPins they are connected. Are you acquiring signals from these sensors using interrupt or by polling? (Polling means checking again and again that the sensors are ready with data.)
How many buttons that you have connected with UNO? In which DPins they are connected. Are you acquiring signals from these buttons using interrupt or by polling?
Please, post your codes with code tags (</>).
Robin2:
You need to explain why you want to use an interrupt and what you want your interrupt function to do.Like I said in Reply #1, the attachInterrupt() function only makes a link between an interrupt and a function. The attachInterrupt() call probably only takes a few microsecs and usually you only call it once from setup()
...R
I'm gonna make a speedometer with hall effect sensors and whenever a magnet passes by I want to get the time between each pass and divide it by the perimeter of the driveshaft (I'm basically building a DIY kind of car/atv) so I get my speed. It's just gonna be some math problems inside the interrupt function and display the speed on the 7-Segments. But at the same I want to be able to press other buttons. For example I have a LCD mounted and there are several pages which I'm using buttons to cycle through them and they are not controlled by interrupts, only state change detectors.
To sum up, when I press a button at the same time the magnet goes near the hall effect sensor, I'm afraid that the button wouldn't work because the interrupt function would be called and the state detector in the loop function stops working. I hope you can understand me...
daisy_merollin:
To sum up, when I press a button at the same time the magnet goes near the hall effect sensor, I'm afraid that the button wouldn't work because the interrupt function would be called and the state detector in the loop function stops working. I hope you can understand me...
That can normally not happen. An interrupt service routine should never run for any more than a few microseconds. A finger pressing a button only moves a few thousandths of a millimeter in that period of time. There is plenty of time to poll it.
Perhaps you are contemplating performing complicated processing in your service routine, which is something that you should never do, and don't need to do, since you can pass that kind of task off to the main program, which only retrieves raw data (such as the time of a Hall effect transition) from the service routine.
An interrupt routine should be as short and quick as possible. Don't do calculations there. If you're keen to use interrupts, just trigger on rising edges in the interrupt routine when the Hall sensor sees a magnet. Do the speed calc periodically in loop.
Frankly, you can dispense with interrupts and just poll the Hall, unless you're doing something intense elsewhere or using delay.
As to missing buttons, a human will never notice that it took a microsecond or so to pick up a press.
Ditto what the last two guys. Also, remember variables shared between ISR and non-ISR code need to be declared volatile. And, protect accesses in non-ISR code with critical sections if they are non-atomic.
The usual advice is not to use interrupts unless you know what you're doing. But, that's kind of a Catch 22, you'll never learn to use them unless you're burned a couple of times attempting to do so.
daisy_merollin:
I'm gonna make a speedometer with hall effect sensors and whenever a magnet passes by I want to get the time between each pass and divide it by the perimeter of the driveshaft (I'm basically building a DIY kind of car/atv) so I get my speed. It's just gonna be some math problems inside the interrupt function and display the speed on the 7-Segments.
Don't do any maths inside the ISR - just record the time and set a flag so the main part of your program knows there has been an interrupt.
The code in this link is derived from a program I used to control the speed of a small DC motor. I was using an optical sensor but I'm sure the code would work just as well with a hall-effect sensor.
How many pulses per revolution have you in mind? And how many revolutions per minute?
My project just had one pulse per revolution and it was working fine up to 16,000 RPM
...R
Hopefully you are using the input capture from timer 1 on the ICP1 pin. If not, you should be.
Using an interrupt and millis() to time intervals between interrupts is not the way to do accurate speed detection.
The timer 1 capture is far more accurate. You can get down to intervals of 125ns at 8MHz, or 63ns at 16MHz, if necessary.
pcbbc:
Hopefully you are using the input capture from timer 1 on the ICP1 pin. If not, you should be.
Using an interrupt and millis() to time intervals between interrupts is not the way to do accurate speed detection.
The timer 1 capture is far more accurate. You can get down to intervals of 125ns at 8MHz, or 63ns at 16MHz, if necessary.
At 16,000 RPM and 1 pulse per rev there are about 3700 µsecs between pulses. I don't see that the extra accuracy of using input capture would be worth the trouble.
...R
Robin2:
Don't do any maths inside the ISR - just record the time and set a flag so the main part of your program knows there has been an interrupt.The code in this link is derived from a program I used to control the speed of a small DC motor. I was using an optical sensor but I'm sure the code would work just as well with a hall-effect sensor.
How many pulses per revolution have you in mind? And how many revolutions per minute?
My project just had one pulse per revolution and it was working fine up to 16,000 RPM
...R
void updateMotorSpeed() {
pwmVal = potVal >> 2;
digitalWrite(revPin,LOW);
analogWrite(fwdPin, pwmVal);
}
What does the " >> " operator mean here? I couldn't understand it. Btw the code looks perfect for my project. Can I use it?
What does the " >> " operator mean here?
Right shift.
Here used as an integer divide by four.
(The author could have used "/ 4" instead to make the code clearer, and the compiler would've generated ">> 2" anyway)
shifts content of the variable to the right; similarly << shifts it to the left. As were talking bits, the number of shifts (in your case 2) means divide by 22 equals 4; << would indicate multiply by 4.
TheMemberFormerlyKnownAsAWOL:
(The author could have used "/ 4" instead to make the code clearer, and the compiler would've generated ">> 2" anyway)
I'm pretty sure I checked that at some time and discovered that the compiler does not substitute a right shift for a divide. The right shift a great deal faster than a divide.
...R
Same code**, at least for signed/unsigned int type...
unsigned_n >>= 2;
7c2: 80 91 50 01 lds r24, 0x0150 ; 0x800150 <unsigned_n>
7c6: 90 91 51 01 lds r25, 0x0151 ; 0x800151 <unsigned_n+0x1>
7ca: 96 95 lsr r25
7cc: 87 95 ror r24
7ce: 96 95 lsr r25
7d0: 87 95 ror r24
7d2: 90 93 51 01 sts 0x0151, r25 ; 0x800151 <unsigned_n+0x1>
7d6: 80 93 50 01 sts 0x0150, r24 ; 0x800150 <unsigned_n>
unsigned_n /= 4;
7da: 80 91 50 01 lds r24, 0x0150 ; 0x800150 <unsigned_n>
7de: 90 91 51 01 lds r25, 0x0151 ; 0x800151 <unsigned_n+0x1>
7e2: 96 95 lsr r25
7e4: 87 95 ror r24
7e6: 96 95 lsr r25
7e8: 87 95 ror r24
7ea: 90 93 51 01 sts 0x0151, r25 ; 0x800151 <unsigned_n+0x1>
7ee: 80 93 50 01 sts 0x0150, r24 ; 0x800150 <unsigned_n>
signed_n >>= 2;
7f2: 80 91 4e 01 lds r24, 0x014E ; 0x80014e <__data_end>
7f6: 90 91 4f 01 lds r25, 0x014F ; 0x80014f <__data_end+0x1>
7fa: 95 95 asr r25
7fc: 87 95 ror r24
7fe: 95 95 asr r25
800: 87 95 ror r24
802: 90 93 4f 01 sts 0x014F, r25 ; 0x80014f <__data_end+0x1>
806: 80 93 4e 01 sts 0x014E, r24 ; 0x80014e <__data_end>
signed_n /= 4;
80a: 80 91 4e 01 lds r24, 0x014E ; 0x80014e <__data_end>
80e: 90 91 4f 01 lds r25, 0x014F ; 0x80014f <__data_end+0x1>
812: 97 fd sbrc r25, 7 **
814: 03 96 adiw r24, 0x03 ; 3 **
816: 95 95 asr r25
818: 87 95 ror r24
81a: 95 95 asr r25
81c: 87 95 ror r24
81e: 90 93 4f 01 sts 0x014F, r25 ; 0x80014f <__data_end+0x1>
822: 80 93 4e 01 sts 0x014E, r24 ; 0x80014e <__data_end>
** Note signed int requires a small adjustment to produce the correct division result for negative numbers.