Hello!!
I'm a bit new to arduino and don't know allot of things here.
So, I've been working on a project and im having some problems.
the problem is that i have to get rid of the delay command cuz its messing my code.
The code is a bit long but ill show you the main problem.
Is there any way to make the sei(); and cli(); without any delay?
I mean I need 5 sec or even more to average the rpm but this delay pauses the whole program
#include <math.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8, 7, 6, 5, 4);
#define RotationPin (18)
volatile unsigned long Rpm;
volatile unsigned long ContactBounceTime1;
void setup() {
pinMode(RotationPin, INPUT); //Hall sensor pin
attachInterrupt(digitalPinToInterrupt(RotationPin), isr_hall, RISING);
lcd.begin(20, 4);
lcd.clear();
}
void loop() {
lcd.setCursor(0,1);
lcd.print("Rotor RPM: RPM" );
lcd.setCursor(13,1);
lcd.print(Rpm*6); //rpm times 6 cuz of the average of 5 sec
Rpm=0; //Set RPM count to 0
sei(); // Enables interrupts
delay (5000); // Wait 5 seconds to average
cli(); // Disable interrupts
}
void isr_hall ()
{
if ((millis() - ContactBounceTime1) > 15 ) // debounce the switch contact.
{
Rpm++;
ContactBounceTime1 = millis();
}
}
Thank you!!
if the whole code is needed pls tell me!
You should not use cli() and sei() the way you do.. In fact, they do not really do anything for you because you set them almost right after you clear them. Instead of a delay you should use millis for timing:
#define RPM_MILLIS 5000
unsigned long rpmStart;
void setup()
{
//Other code here
rpmStart = millis();
}
void loop()
{
if (millis() - rpmStart >= RPM_MILLIS)
{
cli(); //Stop interrupts / enter "critical section"
//Calculate average
//Restart interrupts and timing
sei();
rpmStart = millis();
}
}
I did read on that thread but didnt help me with the problem i have..
Main problem is that Im new to this.I need to learn a bit more on how interrupts works.
Right now, i'm trying to figure out the code Danois90 sent
Interrupts will interrupt execution of the main code (eg. the loop() method) in order to do something "more important" and when done, execution of the main code will resume from the point it was interrupted. That is also why code in interrupt handlers should be as little as possible to prevent the main code from being blocked for too long since this may cause timing to "glitch". When you call "cli()" in the main code you prevent any interrupts from interferring with the main code until "sei()" is called. This approach is usually referred to as a "critical section" (even if it is not) and will allow the main code to access "volatile" variables used in the interrupt handlers without any interference from the interrupt handlers. Do not think of the interrupts in arduino's / MCU's as multi-threading in PC's since it is not. Good luck!
Right now, i'm trying to figure out the code Danois90 sent
In summary, you only need to disable the interrupts whilst doing calculations with multi byte variables.
Use millis() to time the period over which readings are to be taken, then disable interrupts, do the calculation and then enable interrupts ready for the next timing period
It doesn't look like anyone above has stated this - but if you have interrupts disabled for more than a couple of milliseconds (two overflows of timer0), all time keeping will stop, so a delay() will last forever, and millis() will stop increasing as long as interrupts are disabled. Also serial output will stop and if more than one character is received over serial, those will be lost too. Interrupts should be disabled only when absolutely necessary, and for as short a time as possible.
Cant figure how to make it work..
I know from the main code I uploaded is that it count the pulses for 5 secs, which I then multiply it by 6 60sec(1min)/5(time to avg)=12. 12/2=6 cuz it sees 2 pulses every time the magnet passes by.
Cant figure how to make these 5 secs without using delay
inside between sei(); and cli();
Did you read post #2? It seems everything you want to do happens every 5 seconds, so move your code into a timing loop, see post #1.
What RPM are we talking about? How fast is the interrupt firing? Too much you have not shared to get much more of an answer based on anything but your code snippet. If you're simply trying to display a smoothed RPM reading, there are several methods available. If you try explaining what it is you want to accomplish, you might get some useful answers.
What exactly are you measuring and how accurate does it need to be? You are saying you can't figure out how to make it work. We can't either if we don't know what "working" is. It's possible you are going about this all in a very complicated manner without the need for it. We need more information.
The RPM is for a wind turbine im working on
I use this code i posted to measure the RPM of the rotor and the windspeed.
I can post the whole code but its a mess
Doesn't have to be accurate.
The part I cant figure it out is between cli and sei, I dont know what calculations i have to put. Do I keep the original code and try to find a way to calculate the RPM between cli and sei?
I understand how the code I posted worked, doesn't have any calculation.. Its just averaging the pulses it collects in 5secs
Hello and sorry for the delay, had some work to do off topic.
I would like to thank you all for helping me on this problem I had.
After reading it today I made it work thanks to your help!!
Didn't know why I could not understand How simple it was.