Modern Device Wind Sensor Rev P

Hi All,
I have done my due diligence with Google University and have not reached an resolution. I am using the Modern Device Wind Sensor Rev P in a remediation system I am constructing. The flow measurements appear to be within a believable range, but I run in to an issue with the temp readings. Background of the setup: I have these sensors installed upstream of the 12v blower, and the Arduino is on the same battery source as the blower, with grounds tied together. The velocity and mass flow measurements are spot on, but run in to an issue with the temp. When the blower is off, the temp is spot on, but once the fan turns on, I have a major temp drop. Ambient is around 65F, which the sensor (MCP9701) reads without a problem, but when the fan turns on, the temp reading drops to around 16-18F. I assume I need to set up an equation to account for the wind speed, but have not found any documentation around this issue. Less a full scale wind tunnel test and regression, any ideas?

In case my coding is inducing this issue, it is below. Note, the addressing to the LCD screen has two lines with one commented out, I have 2 different addresses that are used, depends on the remediation system, I have to change the address based on the system being programed.

#include <LiquidCrystal_I2C.h>

#include <Wire.h>

int WellNumber = 7;

//LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x3F, 20, 4);
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);


/*
  Hardware hookup for sensor
  Sensor     Arduino Pin
  Ground     Ground
  +10-12V      Vin
  Out          A0
  TMP          A2
*/

/*
  Hardware hookup for LCD
  Ground    Ground
  Vcc       5V
  SDA       A4
  SCL       A5
*/

const int VelocityPin = A0;
const int NumVelocityReadings = 10;

int VelocityReadings[NumVelocityReadings];
int VelocityIndex = 0;
int VelocityTotal = 0;
int VelocityAverage = 0;


const int TempPin = A2;
const int NumTempReadings = 10;

int TempReadings[NumTempReadings];
int TempIndex = 0;
int TempTotal = 0;
int TempAverage = 0;

static char VelocityStr[5];
static char FlowStr[5];
static char TempStr[5];

float Dia = 2.0;
const float Pi = 3.14159;



void setup() {

  ////////////////////////////// Serial Setup //////////////////////////////

  Serial.begin(9600);

  ////////////////////////////// Initialize Velocity and Temp Arrays to Zero //////////////////////////////

  for (int ThisVelocityReading = 0; ThisVelocityReading < NumVelocityReadings; ThisVelocityReading++) {
    TempReadings[ThisVelocityReading] = 0;
  }

  for (int ThisTempReading = 0; ThisTempReading < NumTempReadings; ThisTempReading++) {
    TempReadings[ThisTempReading] = 0;
  }


  ////////////////////////////// Initialize LCD Screen and Run Screen Test //////////////////////////////

  lcd.init();
  lcd.backlight();

  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print("Display Test");
  delay(1000);

  lcd.setCursor(0, 1);
  lcd.print("Please Wait - 3");
  delay(1000);

  lcd.setCursor(0, 1);
  lcd.print("Please Wait - 2");
  delay(1000);

  lcd.setCursor(0, 1);
  lcd.print("Please Wait - 1");
  delay(1000);

  lcd.clear();

  lcd.setCursor(1, 0);
  lcd.print("Monitoring Well ");
  lcd.setCursor(17, 0);
  if (WellNumber < 10) {
    lcd.print("0");
    lcd.print(WellNumber);
  } else {
    lcd.print(WellNumber);
  }

  lcd.setCursor(0, 1);
  lcd.print("Velocity: ");

  lcd.setCursor(17, 1);
  lcd.print("FPM");

  lcd.setCursor(2, 2);
  lcd.print("Flow: ");

  lcd.setCursor(15, 2);
  lcd.print("CFM");

  lcd.setCursor(2, 3);
  lcd.print("Temp: ");

  lcd.setCursor(15, 3);
  lcd.print((char)223);
  lcd.setCursor(16, 3);
  lcd.print("F");
}

void loop() {

  ////////////////////////////// Raw Readings //////////////////////////////

  int VelocityRAW = analogRead(VelocityPin);  // read velocity

  int TempRAW = analogRead(TempPin);  //read temp

  ////////////////////////////// Velocity Averageing Calculations //////////////////////////////

  VelocityTotal = VelocityTotal - VelocityReadings[VelocityIndex];
  VelocityReadings[VelocityIndex] = analogRead(VelocityPin);
  VelocityTotal = VelocityTotal + VelocityReadings[VelocityIndex];
  VelocityIndex = VelocityIndex + 1;

  if (VelocityIndex >= NumVelocityReadings) {
    VelocityIndex = 0;
  }

  VelocityAverage = VelocityTotal / NumVelocityReadings;

  ////////////////////////////// Temperature Averaging Calculations //////////////////////////////

  TempTotal = TempTotal - TempReadings[TempIndex];
  TempReadings[TempIndex] = analogRead(TempPin);
  TempTotal = TempTotal + TempReadings[TempIndex];
  TempIndex = TempIndex + 1;

  if (TempIndex >= NumTempReadings) {
    TempIndex = 0;
  }

  TempAverage = TempTotal / NumTempReadings;


  ////////////////////////////// Velocity and Flow Rate Calculations //////////////////////////////

  float VelocityMPH = pow((((float)VelocityAverage - 264.0) / 85.6814), 3.36814);  // velocity formula derived from a wind tunnel data, annemometer and some fancy Excel regressions. formula provided by manufacturer and in miles per hour.
  float VelocityFPM = VelocityMPH * 88.0;                                          //convert from miles per hour to feet per minute
  if (isnan(VelocityFPM)) {
    lcd.setCursor(10, 1);
    lcd.print("      ");
    lcd.setCursor(10, 1);
    lcd.print("OFF");
  } else {
    if(VelocityFPM >= 1000){
    dtostrf(VelocityFPM, 6, 1, VelocityStr);}
    else{
    dtostrf(VelocityFPM, 6, 2, VelocityStr);
    }
    lcd.setCursor(10, 1);
    lcd.print("      ");
    lcd.setCursor(10, 1);
    lcd.print(VelocityStr);
  }

  float AreaSqIn = Pi * pow(((float)Dia / 2.0), 2);  //calcuate cross sectional area of pipe in square inches
  float AreaSqFt = AreaSqIn / 144;                   //convert from square inches to square feet

  float FlowCFM = VelocityFPM * AreaSqFt;
  if (isnan(FlowCFM)) {
    lcd.setCursor(8, 2);
    lcd.print("      ");
    lcd.setCursor(8, 2);
    lcd.print("OFF");
  } else {
    dtostrf(FlowCFM, 6, 2, FlowStr);
    lcd.setCursor(8, 2);
    lcd.print("      ");
    lcd.setCursor(8, 2);
    lcd.print(FlowStr);
  }


  ////////////////////////////// Temperature Calculations //////////////////////////////

  float TempC = ((((float)TempAverage * 5.0) / 1024.0) - 0.400) / .0195;  // convert to volts then use formula from datatsheet.    Vout = ( TempC * .0195 ) + .400    tempC = (Vout - V0c) / TC   see the MCP9701 datasheet for V0c and TC
  float TempF = (TempC * (9.0 / 5.0)) + 32.0;
  if (isnan(TempC)) {
    lcd.setCursor(8, 3);
    lcd.print("      ");
    lcd.setCursor(8, 3);
    lcd.print("OFF");
  } else {
    dtostrf(TempF, 6, 2, TempStr);
    lcd.setCursor(8, 3);
    lcd.print("      ");
    lcd.setCursor(8, 3);
    lcd.print(TempStr);
  }
  delay(750);
}

The MCP9701 temperature sensor is not ratiometric, so your problem may be that when the blower turns on, the Arduino's ADC reference voltage droops and borks the ADC reading.

One way to check that hypothesis is to use a multimeter to measure the voltage at the AREF pin with the blower off and with the blower on. If it changes, then you can use those numbers to estimate the effects on analogRead and the calculated temperature.

If that is the problem, then one solution is to ditch the MCP9701 and get a digital temperature sensor such as the DS18B20.

Another possible solution would be to use the internal reference voltage (which is stable relative to the Arduino supply voltage). This will only work if the MCP9701 output is equal to or less than the internal reference voltage in the temp range of interest. And some calibration would be needed, since tho' the internal ref is stable, it is not accurate.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.