Go Down

Topic: Frequency/Pulse Measurement (Read 7425 times) previous topic - next topic

Nick Gammon

Interrupts won't trouble an analog read. That's a hardware function.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

robtillaart

Code: [Select]
The idea is that, every hour (or half hour),
That might be a long time, why not measure continuously and write an average every timeslot. That way you could detect peaks esp. in the windspeed.

Or is the Arduino running on batteries?  [why not on windenergy ?]
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Heimdallofasgard

I'm hoping to run it off batteries eventually. But anyway, here's some of the code I have at the moment:

Code: [Select]
const byte LED = 13;
const byte BUTTON = 2;

// Interrupt Service Routine (ISR)
void pinChange ()
{
Serial.println(millis());
  if (digitalRead (BUTTON) == HIGH)
    digitalWrite (LED, HIGH);
  else
    digitalWrite (LED, LOW);
}  // end of pinChange

void setup ()
{
  Serial.begin(9600);
  pinMode (LED, OUTPUT);  // so we can update the LED
  digitalWrite (BUTTON, HIGH);  // internal pull-up resistor
  attachInterrupt (0, pinChange, CHANGE);  // attach interrupt handler

}  // end of setup

void loop ()
{
//Start Temperature Measurement: 
  int therm0 = analogRead(A0);                  //1. input on Analog pin 0
  float volt0 = therm0 * (5 / 1023.0);            //2. conversion to Voltage
  float temp0 = ((volt0 + 10.281)/0.0458)-273.15; //3. temperature calc 0
    int therm1 = analogRead(A1);                  //1. input on Analog pin 1
  float volt1 = therm1 * (5 / 1023.0);            //2. conversion to Voltage
  float temp1 = ((volt1 + 10.281)/0.0458)-273.15; //3. temperature calc 1
   Serial.println(temp1);
//End Temperature Measurement
}


Both the temperature measurement and the pin interrupt run okay by themselves, but when I try the above sketch with both of them in the same sketch. The void.Loop() runs continuously until the interrupt, after the interrupt it stops reporting the temperature to the serial out.

PaulS

Quote
The void.Loop() runs continuously until the interrupt, after the interrupt it stops reporting the temperature to the serial out.

Likely because you are trying to do serial output in the interrupt handler. Serial output uses interrupts, which are disabled during your interrupt service routine. The buffer is full, so Serial.print() blocks until there is room. Since interrupts are disabled, no data ever gets shifted out, so no room is ever made available, so Serial.print() keeps waiting.

Heimdallofasgard

Okay nice... I took the serial print out of the interrupt and the two pieces of code seem to be working alongside each other fine now. Would a millis() function in the interrupt cause the program to stop working? like... with an overuse of timers or something?!

- Heim

Nick Gammon

Yes, they will melt down and explode.  NOT.

You can call millis() inside an ISR however it will not increment.

You can call micros() and it will increment, however don't do that for more than 1 mS.

Your ISR routines should be short.

http://www.gammon.com.au/interrupts
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Heimdallofasgard


Yes, they will melt down and explode.  NOT.

You can call millis() inside an ISR however it will not increment.

You can call micros() and it will increment, however don't do that for more than 1 mS.

Your ISR routines should be short.

http://www.gammon.com.au/interrupts



Okay good to know!

I'm going to have to think of some way to record the time it takes between interrupts no so I can record the anemometer wind speed :S

Nick Gammon

There is no objection to using millis() or micros() inside an interrupt to record the current time. And then in the next interrupt do it again and work out the interval.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Heimdallofasgard

Okay I got the anemometer working with the two thermistors! thanks for all your help, Here's my final code:

Code: [Select]
const byte BUTTON = 2;
float elapsed, diff, start;
float windspeed;

void setup ()
{
 Serial.begin(9600);
 digitalWrite (BUTTON, HIGH);  // internal pull-up resistor
 attachInterrupt (0, pinChange, RISING);  // attach interrupt handler
 start = millis();
 Serial.println("Therm 1 / Therm 2 / WindSpd");
}  // end of setup

// Interrupt Process
void pinChange ()
{
 elapsed=millis()-start;         //gets the full period (in ms) of rotation
 windspeed=2.5/(elapsed/1000);   //gets freq from ms then * by 2.5 to get mph (according to hardware spec)
 start=millis();                 //resets the counter

}  // end of Interrupt Loop

void loop ()
{
 //Start Temperature Measurement:  
 int therm0 = analogRead(A0);                  //1. input on Analog pin 0
 float volt0 = therm0 * (5 / 1023.0);            //2. conversion to Voltage
 float temp0 = ((volt0 + 10.281)/0.0458)-273.15; //3. temperature calc 0
 int therm1 = analogRead(A1);                  //1. input on Analog pin 1
 float volt1 = therm1 * (5 / 1023.0);            //2. conversion to Voltage
 float temp1 = ((volt1 + 10.281)/0.0458)-273.15; //3. temperature calc 1
 Serial.print(temp0);
 Serial.print("DegC");
 Serial.print(" ");
 Serial.print(temp1);
 Serial.print("DegC");
 Serial.print(" ");
 Serial.print(windspeed);
 Serial.print(" ");
 Serial.println("mph");
 delay(1000);
 //End Temperature Measurement
}




Now I just need to work out the strain gauges... Data logging... and low power standby

Feel free to PM me with any questions you might have

Heimdallofasgard

Hi Guys!

It's a little later on in this project now and I went back to look at the anemometer readings I was getting and there are some one off readings where the wind speed suddenly just reads 0.00 mph then carries on reading the wind speed as usual.

Is it possible to modify the below code to get a rolling average of anemometer readings from the previous 10 readings?

Code: [Select]
const byte BUTTON = 2;
float elapsed, diff, start;
float windspeed;

// Begin Setup-----------------------------------------------------------------
void setup ()
{
  Serial.begin(9600);
  digitalWrite (BUTTON, HIGH);                   // internal pull-up resistor
  attachInterrupt (0, pinChange, RISING);        // attach interrupt handler
  start = millis();
  Serial.println("WindSpd");
}

// Interrupt Process for Windspeed Measurement---------------------------------
void pinChange ()
{
  elapsed=millis()-start;         //gets the full period (in ms) of rotation
  windspeed=2.5/(elapsed/1000);   //gets freq from ms then * by 2.5 to get mph
  start=millis();                 //resets the counter

// end of Interrupt Process----------------------------------------------------

// Main Loop-------------------------------------------------------------------
void loop ()

//Begin Serial Printing
  Serial.print(windspeed);
  Serial.print(" ");
  Serial.println("mph");

//End Serial Printing

  delay(200);
}

robtillaart

Quote
Is it possible to modify the below code to get a rolling average of anemometer readings from the previous 10 readings?

try this one - http://playground.arduino.cc/Main/RunningAverage -
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up