Go Down

Topic: 得到風速計的數據一直是0零 (Read 692 times) previous topic - next topic

AmySakura

Feb 22, 2018, 12:21 pm Last Edit: Feb 22, 2018, 12:30 pm by AmySakura
我在網路上找到氣象站的程式碼
Link: SEN-08942

硬體方面跟網頁裡面一樣,不過電路我只用跳線和電阻,沒有用到其他元件。
明明程式都一樣,但問題是...監控螢幕顯示風速計旋轉次數是「零 0」!
雨量計也是!(見附件圖)
只有風向標的程式可以用。

風速程式碼 1:
Code: [Select]

/*  The SEN-08942 is an anemometer, wind vane and rain gauge set for prototyping an amateur
     weather station.
    
    SEN-08942:
         http://www.sparkfun.com/products/8942
    Spec http://www.sparkfun.com/datasheets/Sensors/Weather/Weather%20Sensor%20Assembly..pdf
         http://www.sparkfun.com/products/8942
         http://www.lextronic.fr/P4452-capteurs-pour-station-meteo.html
         http://home.comcast.net/~saustin98/misc/WeatherStationADC.txt        
    For its complement map SparkFun Weather Shield.
         http://air.imag.fr/index.php/SparkFun_Weather_Shield
*/
/* From http://home.comcast.net/~saustin98/misc/WeatherStationADC.txt */

/* Arduino sketch for Weather device from Sparkfun.
  Uses only the wind direction vane and the anemometer (not the rain gauge).

  Although the inclination for a weather logger is to run it for
  a long time, due to the way Wiring.c implements the millis() function,
  this should be restarted, oh, monthly. The millis() functions overflows
  after about 49 days. We could allow for that here, and handle the
  wraparound, but you've got bigger problems anyway with the delay()
  function at an overflow, so it's best to "reboot".

=========================================================
                  ANEMOMETER
=========================================================
  This is connected to Arduino ground on one side, and pin 2 (for the
  attachInterrupt(0, ...) on the other.
  Pin 2 is pulled up, and the reed switch on the anemometer will send
  that to ground once per revolution, which will trigger the interrupt.
  We count the number of revolutions in 5 seconds, and divide by 5.
   1 Hz (rev/sec) = 1.492 mph = 2.40114125 kph = 2401.1 m/h

=========================================================
                  WIND DIRECTION VANE
=========================================================
  We use a classic voltage divider to measure the resistance in
  the weather vane, which varies by direction.
  Using a 10K resistor, our ADC reading will be:
      1023 * (R/(10000+R))
  where R is the unknown resistance from the vane. We'll scale
  the 1023 down to a 255 range, to match the datasheet docs.

                    +5V
                    |
                    <
                    >     10K
                    <   Resistor
                    <
                    >
                    |
  Analog Pin 5------|
                    |
                    -----------| To weather vane
                               | (mystery resistance)
                    -----------|
                    |
                    |
                  -----
                   ---
                    -
  The ADC values we get for each direction (based on a 255 max)
  follow, assuming that pointing away from the assembly center
  is sector zero. The sector number is just which 45-degree sector
  it is, clockwise from the "away" direction. The direction
  shown is assuming that "away" is West. Depending how
  you orient the system, you'll have to adjust the directions.

      Sector   Reading  Direction
        0        18        W
        1        33        NW
        2        57        N
        7        97        SW
        3       139        NE
        6       183        S
        5       208        SE
        4       232        E
        
  The values in the ADC table below list the midpoints between
  these, so our reading can vary a bit. We'll pick the first value
  that's >= our reading.
=========================================================
                  RAIN GAUGE
=========================================================
  Implemented here.
  It is done the same way as the anemometer, and use
  attachInterrupt(1, ...) on pin 3. Each interrupt represents
  .011 inches of rain (0.2794 mm), according to the docs.
*********************************************************************/

#define PIN_ANEMOMETER  2     // Digital 2 for anemometer (wind speed)

/* How often we want to calculate wind speed or direction
   每隔 5sec = 5000ms 紀錄風速數據 */
#define MSECS_CALC_WIND_SPEED 5000
/*================== Declare Variables ==========================*/
volatile int numRevsAnemometer;  // Incremented in the interrupt
                                 // For interrupt use volatile to avoid failure
unsigned long nextCalcSpeed;     // 下一次計算平均風速的 時間點
unsigned long time;              // Millis() at each start of loop()

/*================== Declare Functions ==========================*/
void countAnemometer();
void calcWindSpeed();
/*================== Initialize =================================*/
void setup() {
   Serial.begin(9600);
   pinMode(PIN_ANEMOMETER, INPUT);
   digitalWrite(PIN_ANEMOMETER, HIGH);
   attachInterrupt(0, countAnemometer, FALLING);// Interrupt 0 在 pin 2 上  
   nextCalcSpeed = millis() + MSECS_CALC_WIND_SPEED;
  
   delay(100);
   Serial.println("setup ready");  
   Serial.println("Please wait for 5sec...\n");
  
   Serial.println("Revolutions\t Wind speed (m/h)");
}

/*================== Main loop ==================================
 * 間隔 MSECS_CALC_WIND_SPEED (5sec) 後,呼叫function: calcWindSpeed() 得到 風速數據
 * 下一次取得 風速數據 的時間點: 再過 5sec 後
=================================================================*/
void loop() {  
   time = millis();
   if (time >= nextCalcSpeed) {
      calcWindSpeed();
      nextCalcSpeed = time + MSECS_CALC_WIND_SPEED;
   }
}

/*=============== countAnemometer() =============================
 * Interrupt handler for anemometer. Called each time the reed
 * switch triggers (one revolution).
=================================================================*/
void countAnemometer() {
   numRevsAnemometer++;
}

/*=============== calcWindSpeed() ===============================
 * Calculate the wind speed, and display it (or log it, whatever).
 * 1 rev/sec = 1.492 mph = 2.40114125 kph = 2401.1 m/h
=================================================================*/
void calcWindSpeed() {
   int x,r, iSpeed; // x = 整數,r = 小數
   // This will produce: m/h * 10
   // (didn't calc right when done as one statement)
   long speed = 24011;
   speed = speed*numRevsAnemometer/MSECS_CALC_WIND_SPEED;
   iSpeed = speed;         // Need this for formatting below
  
   x = iSpeed / 10;
   r = iSpeed % 10;
   Serial.print(numRevsAnemometer); Serial.print("\t\t "); Serial.print(x); Serial.print('.'); Serial.println(r);

   numRevsAnemometer = 0;        // Reset counter
}


雨量計程式碼:
Code: [Select]

#define PIN_RAINGAUGE 3
#define MSECS_CALC_RAIN_FALL  5000         // 5sec
volatile int numDropsRainGauge = 0;
unsigned long nextCalcRain;
unsigned long time;
void setup() {
   Serial.begin(9600);
   attachInterrupt(digitalPinToInterrupt(PIN_RAINGAUGE), countRainGauge, FALLING);
   nextCalcRain = millis() + MSECS_CALC_RAIN_FALL;
   delay(100);
   Serial.println("setup ready");
}

void loop() {
   time = millis();
   if(time >= nextCalcRain) {
    calcRainFall();
    nextCalcRain = time + MSECS_CALC_RAIN_FALL;
   }
}

void countRainGauge(){
  numDropsRainGauge++;
  Serial.println(numDropsRainGauge);
}

void calcRainFall(){
  float Rain = 0.279400;
  Rain = Rain*numDropsRainGauge;
  Rain = Rain/MSECS_CALC_RAIN_FALL*1000; //mm per sec

  Serial.print("Rain fall(mm/sec):\t");Serial.println(Rain);
  numDropsRainGauge = 0;
}


怎麼樣都是 0旋轉次數呀!雨量也是0...
請問大大到底哪裡出錯了?

AmySakura

後來又試著另一個程式碼,也是風速計。
How to Hookup Davis Anemometer to Arduino (Part 2 of 3)

關於ISR function,我有查看它的說明是:不能回傳值,以及不可以使用時間函數,如:time, millis, delay
但是就是不知道應該怎麼改,要怎麼把debounced 判斷拉出來放在新的函數 (就是因為要判斷 debounced 所以才會出現時間函數)。

風速計程式碼2:
Code: [Select]

#include <math.h>

#define WindSensorPin (2) // The pin location of the anemometer sensor

volatile unsigned long Rotations; // cup rotation counter used in interrupt routine
volatile unsigned long ContactBounceTime; // Timer to avoid contact bounce in interrupt routine
float WindSpeed; // speed miles per hour

void setup() {
  Serial.begin(9600);
  pinMode(WindSensorPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(WindSensorPin), isr_rotation, FALLING);
 
  Serial.println("Davis Wind Speed Test");
  Serial.println("Rotations\tMPH");
}

void loop() {
  Rotations = 0;  // Set Rotations count to 0 ready for calculations
  sei();          // Enables interrupts
  delay (3000);   // Wait 3 seconds to average
  cli();          // Disable interrupts
  /* convert to mp/h using the formula V=P(2.25/T)
     V = P(2.25/3) = P * 0.75 */
 
  WindSpeed = Rotations * 0.75; 
  Serial.print(Rotations); Serial.print("\t\t");Serial.println(WindSpeed);
}

// This is the function that the interrupt calls to increment the rotation count
void isr_rotation () {
  if ((millis() - ContactBounceTime) > 15 ) { // debounce the switch contact.
    Rotations++;
    ContactBounceTime = millis();
    }
}

結果呢...還是顯示0

Go Up