Here is the code and schematic. The code also includes a lot of weather calculations and I am displaying temperature and relative air density as well as the flow pressure.
#include "U8glib.h" //LCD 128x64 ST7920 Display Library
#include "SparkFunBME280.h" // BME280 Library
#include "Wire.h" // I2C Library For Sensor
// Flow Meter Set Integers Start
//int rawValue; // A/D readings
int offset = 46; // zero flow pressure adjust (~30-72)
int fullScale = 819; // max pressure adjust (~798-840)
float flowpressure; // final pressure in mmHg
int battery;
int pressurezero;
uint32_t rawValue; // new average code
int rawAccumulator; // new average code
int filteredValue; // new average code
// Flow Meter Set Integers End
// Weather Integers Start
BME280 Sensor;
float kelvin = 0;
float dewptk = 0;
float dewptc = 0;
float dewptf = 0;
float baromb; //pressure millibar
float baropascal; //pressure in Pascals
float gconstdry = 287.058; //gas constant for dry air
float gconstwaterv = 461.495; //gas constant, water vapor
double psatmb; //pressure saturated millibar
double psatnum; //pressure saturated numerator
double psatden; //pressure saturated denominator
double psatfract; //pressure saturated fraction
double psatexpo; //exponent for pressure saturated
double pvapwater; //pressure, water vapor component
double pdryair; //pressure, dry air
double psatpascals; //pressure saturated in Pascals
double phumidA; //part A of equation
double phumidB; //part B of equation
double rho; //variable for air density in Kg/m3
int analogPin = 2; //
int val = 0; //initialize value to 0
float pottopress; //from (pot*0.0017578)+29.92
float pressalt; //from (SLP -Baro) *994
float degc;
float degf;
float pressure;
float h;
float inhg;
double rad; // relative air density(rad) = 100 * (current air density) / (reference air density) standard automotive reference 1.1568 kg/m3
// Weather Integers End
// constructor call for display
U8GLIB_ST7920_128X64 u8g(13, 11, 10, U8G_PIN_NONE); // SPI Com: SCK = en = 13, MOSI = rw = 11, CS = di = 0
void draw(void)
{
// graphic commands to redraw the complete screen should be placed here
}
void setup(void)
{
u8g.setRot180(); // flip screen / rotated for current display
// set SPI backup if required / not required with current display
//u8g.setHardwareBackup(u8g_backup_avr_spi);
//***Set up sensor******************************//
//commInterface I2C_MODE
Sensor.settings.commInterface = I2C_MODE;
Sensor.settings.I2CAddress = 0x76;
Sensor.settings.runMode = 3; // 3, Normal mode
Sensor.settings.tStandby = 0; // 0, 0.5ms
Sensor.settings.filter = 0; // 0, filter off
//tempOverSample can be:
// 0, skipped
// 1 through 5, oversampling *1, *2, *4, *8, *16 respectively
Sensor.settings.tempOverSample = 1;
//pressOverSample can be:
// 0, skipped
// 1 through 5, oversampling *1, *2, *4, *8, *16 respectively
Sensor.settings.pressOverSample = 1;
//humidOverSample can be:
// 0, skipped
// 1 through 5, oversampling *1, *2, *4, *8, *16 respectively
Sensor.settings.humidOverSample = 1;
//***Initialize Sensor**************************//
Serial.begin(57600);
Serial.print("Program Started\n");
Serial.println("Starting BME280... result of .begin():");
delay(10); //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
//Calling .begin() causes the settings to be loaded
Serial.print("Sensor: 0x");
Serial.println(Sensor.begin(), HEX);
}
void loop(void)
{
//pressurezero = analogRead(A2) / 8;
rawValue = analogRead(A0);
flowpressure = (filteredValue - offset) * 650.0 / (fullScale - offset); // offset or pressurezero for trimmer pot Replaced rawValue with filteredValue. 650.0 for calibrated pressure conversion
battery = analogRead(A1) / 8.9; // Display battery percentage at max 100%
if (flowpressure < 0) // If pressure is below zero have display show zero
{
flowpressure = 0;
}
if (battery > 100) // If battery tries to display over 100% have display show 100%
{
battery = 100;
}
// New code for averaging - On each pass, it subtracts 1/8 of the total rawAccumulator value, then adds in the current rawValue.
// So over time, the rawAccumulator value will converge on 8x the average raw value.
// Then it takes 1/8 of the rawAccumulator value as the filteredValue.
rawAccumulator -= (rawAccumulator >> 3); // new average code. Can change 3 to 2 for less or 3 to 4 for more averaging.
rawAccumulator += rawValue; // new average code
filteredValue = rawAccumulator >> 3; // new average code. Can change 3 to 2 for less or 3 to 4 for more averaging.
val = analogRead(analogPin);
pottopress = (val * 0.0017578) + 29.92; //"Kollsman Window" value calculation
//Start with temperature, as that data is needed for accurate compensation.
//Reading the temperature updates the compensators of the other functions
//in the background.
Serial.print("***************** DIRECTLY FROM SENSOR START *********************");
Serial.println("");
Serial.print("Temperature: ");
Serial.print(Sensor.readTempC(), 2);
Serial.print(", ");
Serial.println("");
Serial.print("Temperature: ");
Serial.print(Sensor.readTempF(), 2);
Serial.print(", ");
Serial.println("");
Serial.print("Pressure: ");
Serial.print(Sensor.readFloatPressure(), 2);
Serial.print(", ");
Serial.println("");
Serial.print("Altitude: ");
Serial.print(Sensor.readFloatAltitudeMeters(), 2);
Serial.print(", ");
Serial.println("");
Serial.print("Altitude: ");
Serial.print(Sensor.readFloatAltitudeFeet(), 2);
Serial.print(", ");
Serial.println("");
Serial.print("%RH: ");
Serial.print(Sensor.readFloatHumidity(), 2);
Serial.print(", ");
Serial.println();
Serial.print("***************** DIRECTLY FROM SENSOR END *********************");
Serial.println("");
//read and calibrate TempF from TempC
float degc = Sensor.readTempC() - 1.0; // read and calibrate temp c
float degf = Sensor.readTempF() - 2.5; // read and calibrate temp f
//degf = (degc * 1.8) + 32-1; // was calculated off of Celcius, but to much variation with Faranheit after calculation.
float h = Sensor.readFloatHumidity() - 2; // read and calibrate humidity
float pressure = Sensor.readFloatPressure();
inhg = pressure / 3386;
baromb = inhg * 33.86;
baropascal = inhg * 3386;
kelvin = degc + 273.15;
dewptk = kelvin - ((100 - h) / 5);
dewptc = dewptk - 273.15;
dewptf = ((dewptc * 1.8) + 32);
pressalt = (pottopress - inhg) * 994; //calculate feet
psatnum = 7.5 * degc; //calculate the numerator of the psat exponent
psatfract = psatnum / psatden; //calculate the psat exponent fraction
psatden = degc + 237.3; //calculate the denominator of the psat exponent psatfract = psatnum / psatden; //calculate the psat exponent fraction
psatexpo = pow(10, psatfract); //calculate exponent for psat
psatmb = 6.1087 * psatexpo; //calculate psat in millibars
psatpascals = psatmb * 100; //convert psat millibars (hectopascals) to pascals
pvapwater = (h / 100 * psatmb) * 100; //calculate water vapor pressure component
pdryair = baropascal - pvapwater; //calculate partial pressure dry air component
phumidB = pdryair / (gconstdry * kelvin); //part B of the pressure humid air calculation
phumidA = pvapwater / (gconstwaterv * kelvin); //part A of humid air pressure
rho = phumidA + phumidB; //calculate RHO in Kg/m3!
rad = (rho / 1.225) * 100;
// picture loop
u8g.firstPage();
do
{
draw();
{
u8g.setFont(u8g_font_unifontr); //Set font
u8g.drawStr( 0, 10, "FLOW");
u8g.drawStr( 80, 10, "TEMP'C");
u8g.setPrintPos(85, 22);
u8g.print(degc, 1);
//u8g.drawStr( 100, 22, "'F");
u8g.drawStr( 80, 37, "RAD %");
u8g.setPrintPos(85, 50);
u8g.print(rad, 1);
//u8g.drawStr( 105, 50, "%");
u8g.setFont(u8g_font_fub30r); //Set font
u8g.setPrintPos(0, 48);
u8g.print(flowpressure, 0);
u8g.setFont(u8g_font_unifontr); //Set font
u8g.drawStr( 18, 64, "BATTERY %");
u8g.setPrintPos(89, 64);
u8g.print(battery);
}
else
{
u8g.setFont(u8g_font_unifontr); //Set font
u8g.drawStr( 7, 38, "CHARGE BATTERY");
}
}
while ( u8g.nextPage() );
// rebuild the picture after some delay
delay(200);
}
[/code]
