newbie with no clue

Iv been suck ino the middle of a project to measure wind speed an direction i initially started with reed effect devices but found the bounce to be too erratic for the accuracy i require. I know the calibration of my device to be 1.43 pulses a second for one mph. The code I have got is an altered example of code from this forum and tried to ammend it i am getting a constant read out of 0mph with spikes if added or removed this i expected. I have replaced the hall effect as im aware they can be tempremental bastards when being connected and diconnected from the supply. I beleive my error may be within my maths function but cant see it for looking if there are any pointers I would be greatly appreciative the code is as follows.

// read MPH
int half_revolutions = 0;
int mph = 0;
unsigned long lastmillis = 0;

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, mph_windspeed, FALLING);

}

void loop() {
  if (millis() - lastmillis == 1000) {       //update every one second this is equivelent to readin frequency
    detachInterrupt(0);                            //disable intterupt when calculating
    mph = half_revolutions*60/(1.43*60);    //convert to rpm(hlf rev*60) mph/(constant*mins in hour)
    Serial.print ("MPH =\t");                        //print the word MPH 
    Serial.println (mph);                             //print the mph value
    Serial.print ("\t Hz=\t");                        //print freq (HZ)
    Serial.println(half_revolutions);
    half_revolutions = 0;                            //restart the counter
    lastmillis = millis(); //update last millis
    attachInterrupt(0, mph_windspeed, FALLING);    //enabl interrrupt
  }

}
//this code will be executed everytime teh interrupt 0 (pin2) gets low
void mph_windspeed(){
  half_revolutions++;
}

moderator: added code tags

interrupt variables must be declared volatile, so they are not optimized by the compiler. making a counter unsigned doubles it actual ranges and prevents negative values making it long makes it ... well lasting longer ;)

volatile unsigned long half_revolutions = 0;

and just do not detach/attach the interrupt as you will miss pulses.

write your code in a way that it handles an ever increasing counter (just subtract the last known value.

try this version

// read MPH
volatile unsigned long half_revolutions = 0;
unsigned long previousCounter = 0;
float mph = 0;
unsigned long lastmillis = 0;

void setup() 
{
  Serial.begin(9600);
  attachInterrupt(0, mph_windspeed, FALLING);
}

void loop() 
{
  unsigned long currentTime = millis();
  if (currentTime - lastmillis >= 1000) 
  {
    int duration = currentTime - lastmillis;
    lastmillis = currentTime;    
    
    noInterrupts();     //disable intterupt when copy the volatile counter
    unsigned int pulses = half_revolutions - previousCounter;
    previousCounter = half_revolutions;
    interrupts();  

    mph = (pulses * 1000.0) / (1.43 * duration); // use float, correct for exact duration
    
    Serial.print ("MPH =\t");
    Serial.println (mph, 1);    // print float with one decimal
    Serial.print ("\t Hz=\t");
    Serial.println(pulses * 2);  // ?????
  }
}

//this code will be executed everytime teh interrupt 0 (pin2) gets low
void mph_windspeed(){
  half_revolutions++;
}

Try this.

I am not sufficiently familar with the use of floats to know if the calculation
mph = intervalHalfRevs *60 / (1.43 *60 );
will work correctly. It certainly would not work is mph is an int

Note that I do not use detachInterrupt(), and nor do I reset the half_revolutions variable

// read MPH
volatile unsigned long half_revolutions = 0;
unsigned long prevHalfRevs = 0;
unsigned long latestHalfRevs = 0;
float mph = 0.0;
unsigned long lastmillis = 0;

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, mph_windspeed, FALLING);

}

void loop() {
  if (millis() - lastmillis >= 1000) {       //update every one second this is equivelent to readin frequency
    prevHalfRev = latestHalfRev;
    noInterrupts();                            //disable intterupt when calculating
       latestHalfRev = half_revolutions;    // save the latest value
    interrupts();                       // re enable interrupts
    intervalHalfRevs =  latestHalfRev - prevHalfRev;
    mph = intervalHalfRevs *60 / (1.43 *60 );    //convert to rpm(hlf rev*60) mph/(constant*mins in hour)
    Serial.print ("MPH =\t");                        //print the word MPH
    Serial.println (mph);                             //print the mph value
    Serial.print ("\t Hz=\t");                        //print freq (HZ)
    Serial.println(half_revolutions);                          //restart the counter
    lastmillis += 1000; //update last millis - this is more accurate
 
  }

}
//this code will be executed everytime teh interrupt 0 (pin2) gets low
void mph_windspeed(){
  half_revolutions++;
}

Also not that I used the code button </>

…R

Why would you use interrupts for this?

here are TWO clues for you !

http://forum.arduino.cc/index.php/topic,148850.0.html

read #6 and #7

you have been made aware of #7, not sure you understand. and #6 needs your action desperately.

Thank you for the replies i shall look into them as soon as i finish work this evening. And thank you for the link as i am completely new to arduino with only a very basic education in plc as far as coding is concerned.

please note this is also a dangerous statement (solved in reply #1)

if (millis() - lastmillis == 1000) {

There is a chance that millis() would be forwarded 2 or 3 between two calls ...

Thanks Rob. I missed that. I have updated the code in Reply #2.

Did you add your code after I posted Reply #2 ?
I don’t recall seeing it when I was posting.

…R

Different time zones, sort of simultaneous posting, and yes I took quite some time to type it. In the end a forum is also just a multi threading system with all its quirks :)

robtillaart: just a multi threading system with all its quirks :)

No problem. I just wanted to check whether senility had caught up with me. :)

...R

Thank you all for the help and replies and i shall definitely make clearer headings in future as well as using the code functions and appreciate any tips or hints in general.

amamcgill1980: Thank you all for the help and replies and i shall definitely make clearer headings in future as well as using the code functions and appreciate any tips or hints in general.

you can edit your first post and change the subject line. look at the bottom right of your first post to edit it.