You have two problems right now that are separate from each other.
1) Button bounce
2) Improper button wiring
First, you need to introduce a delay into your interrupt function so that it won't keep registering each rise and fall of the bounce as a separate button press. Use "delayMicroseconds()" because apparently you can't use regular "delay()" inside interrupts. Id suggest a 20,000 microsecond delay.
Second, you need to put a pull down resistor onto the digital pin that you are sampling.
The problem you are having is that the pin is in input mode and thus at high impedance (very high resistance) and thus has a tenancy to "float". If you put a voltage to it, it charges up like a capacitor and since the pin itself has very high resistance to ground, it takes a while for the charge to dissipate to the point where the Arduino will register a LOW again. A 10k resistor from the pin to ground will force the "capacitor" to discharge quickly after current from the button has stopped flowing.
Finally, the Arduino is pretty quick at it's read/write operations (I'm a mechanical engineer, ALL electronics happen "quickly" in comparison to mechanical systems, so it's relative I guess). Here's a link to some test results.
TL;DR verson:
What these values tell me, is that we can do about:
10 analog 10-bit readings per millisecond with analogRead()
128 pwm settings per millisecond with analogWrite()
220 pin reads per millisecond with digitalRead()
224 pin writes per millisecond with digitalWrite()
1056 pin reads per millisecond with direct port reads
1059 pin writes per millisecond with direct port writes
Try clearing INTEDG bit of OPTION_REG register. From the datasheet page 30(32):
INTEDG: Interrupt Edge Select bit
1 = Interrupt on rising edge of INT pin
0 = Interrupt on falling edge of INT pin
When PORTD is high, does the LED turn ON or OFF?
Also check out switch contact bounce. Here is a link on it and how to debounce. To check it is the contact bounce causing the thing that is seen as a "problem", add a delay of 500msec or 1 sec after PORTD=0xff;
in the interrupt routine. If the port is high, your problem is contact bounce if the above suggested solution doesn't solve your problem -that is clearing INTEDG bit.
You don't need that GIE=1;
in the last line of the interrupt block.
I have no experience with Hi-Tech C compiler. Chances are low but try doing INTE=1;
before GIE=1;
in the main function.
Edit
Try changing void intMain()
to void interrupt intMain()
. According to
HI-TECH C® for PIC10/12/16 User’s Guide 3.8 INTERRUPT HANDLING IN C (Page 86) Link
Edit After Second Question
According to the same manual mentioned above page(299):
To produce an infinite loop, use for(;;).
You are trying to assign an 'integer' value to a 'character' variable as I quoted below. Define variable i as unsigned char. Compiler should take care of this, but it is worth trying.
...
int i,k;
...
PORTD=i;
...
Best Answer
@ LoneTech: I figured this site was to help people. Not put them down for lack of information, but to provide it for them if the need is there. Also, Interrupts can be used to interrupt other code without hurting the speed of your main loop. If your button is supposed to change a process and your main loop is controlling a wave or something. INT0 could be used. You also don't know what other operations this individual plans on using it for.
@ Michael: This code took me a while to track down and understand as well. I have written code for AVRs for 5+ years now and for PC 13+ years. Its amazing how little documentation is there at your fingertips. I ran across a nice tutorial and finally it clicked.