Pages: 1 [2]   Go Down
Author Topic: Frequency/Pulse Measurement  (Read 6738 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 502
Posts: 19080
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Interrupts won't trouble an analog read. That's a hardware function.
Logged


Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 223
Posts: 13896
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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 ?]
Logged

Rob Tillaart

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

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 50331
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 502
Posts: 19080
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 502
Posts: 19080
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
}
Logged

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 223
Posts: 13896
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 -
Logged

Rob Tillaart

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

Pages: 1 [2]   Go Up
Jump to: