My issue is simple: I am trying to dim or brighten a LED using a PWM, and using interrupts to change the time of the duty cycle. But with my best efforts it is not working. I want to confirm if it is a hardware or software issue. Here is my code:
// 5000 Microseconds = 5 Milisecondes = 200Hz
// 5 Miliseconds is the total time of the PWM
volatile int PWMup = 5000;
void setup() {
pinMode(8,OUTPUT);
pinMode(4,INPUT);
pinMode(2,INPUT);
attachInterrupt(digitalPinToInterrupt(4),LowerIntensity,RISING);
attachInterrupt(digitalPinToInterrupt(2),HigherIntensity,RISING);
}
void loop() {
digitalWrite(8,HIGH);
delayMicroseconds(PWMup);
digitalWrite(8,LOW);
delayMicroseconds(5000-PWMup); // Max - Up = Down
}
void LowerIntensity(){
if (PWMup > 0) {
PWMup = PWMup - 500;
}
return;
}
void HigherIntensity(){
if (PWMup < 5000) {
PWMup = PWMup + 500;
}
return;
}
Yes, this is a simple code for a simple problem.
I'm trying to avoid to use the integrated timers, but if you think it is far better this way then I will use them.
PaulS:
The Uno doesn't have an external interrupt on pin 4.
Yes I am using the UNO and thanks for that information, but changed PIN recently, so that isn't the biggest problem, I will just switch it again.
The problem is, at the moment: the luminosity doesn't change at all when I press the buttons i use for the interrupt.
For exemple,
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(8,HIGH);
delay(PWMup);
digitalWrite(8,LOW);
delay(10000-PWMup); // Max - Up = Down
}
When I change the loop this way and press my interrupts, it doesn't change the time of the flickering (5 seconds here).
Your interrupt pins are floating when not attached to the 5v.
The preferred method is to declare the input pins as INPUT_PULLUP which connects them internally through a 20K-50K resistor to 5v. The pin will read HIGH. You then want the button to connect between the input pin and ground which will take the inputs LOW when pressed.
For most common 4 leg buttons, you want to connect diagonally across them to ensure connection to legs which are switched instead of permanently connected.
IT WORKS !!
That was so stupid of me....
Now I have the problem of multiple inputs at the same press, but I will try to solve this myself. There is plenty of tutorials on how to fix this.
Thanks a lot !!
I will think of this next time I need buttons intterupt !
Now I have the problem of multiple inputs at the same press, but I will try to solve this myself. There is plenty of tutorials on how to fix this.
Thanks a lot !!
I will think of this next time I need buttons intterupt !
There is no need to use interrupts for reading buttons pressed by humans. The arduino processor is very fast, and button presses are slow events to a 16MHz chip.
You need to write code which does not use delay, loops rapidly, and is always responsive to external inputs without interrupts. Debounce is easier without interrupts.
cattledog:
There is no need to use interrupts for reading buttons pressed by humans. The arduino processor is very fast, and button presses are slow events to a 16MHz chip.
You need to write code which does not use delay, loops rapidly, and is always responsive to external inputs without interrupts. Debounce is easier without interrupts.
Not using delays and interrupts means using the internal timers. I do not know them but I will try to learn them.
As for the bounce back, if I keep using my method, a simple capacitor should do the trick.
Not using delays and interrupts means using the internal timers.
Yes, but you can use Arduino functions like analogWrite() to provide timer based pwm without getting into the details of timer code.
You can also use "Blink Without Delay" methods which use millis() to time events without delay.
Here's an example. You could use button input or Serial input from the monitor to change the values
const byte ledPin = LED_BUILTIN;// the number of the LED pin
byte ledState = LOW;
unsigned long previousMillis = 0;
unsigned long intervalOn = 100;
unsigned long intervalOff= 400;
unsigned long interval = intervalOff;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
interval = intervalOn;
} else {
ledState = LOW;
interval = intervalOff;
}
digitalWrite(ledPin, ledState);
}
}