AC_Hacker |
03-25-14 11:15 AM |
Project Improvement...
Although the fan-control part of the program worked just fine, I had a persistent problem with the display of the CO2 values, in that values below 999 ppm were all showing properly, but once the displayed values exceeded 999 ppm, and went into 4-digits (EX: 1032 ppm) and then dropped below a 4-digit value, the last digit would hang, and a value like 984 ppm would read out something like 9842 ppm, with the last digit being a persistent artifact from the last 4-digit value that had been displayed.
The fix was to flush the ppm value part of the display with 4 blank spaces before printing the ppm value. Fix code is at lines 239 through 247.
Below, is the revised code.
By the way, I've been watching my monitor-controller which senses CO2, temperature and humidity for a bit over a year now, and I am amazed at how accurate the temperature-humidity chip (SHT15) has been. In fact, it has become my reference monitor!
Best,
-AC
Code:
/*
* Example code for SHT1x or SHT7x sensors demonstrating blocking calls
* for temperature and humidity measurement in the setup routine and
* non-blocking calls in the main loop. The pin 13 LED is flashed as a
* background task while temperature and humidity measurements are made.
* In addition, the sensor may be placed in low resolution mode by
* uncommenting the status register write call in setup().
*/
/*
The circuit:
* LCD RS pin to digital pin 12 => Teensy 5
* LCD Enable pin to digital pin 11 => Teensy 4
* LCD D4 pin to digital pin 5 => Teensy 23
* LCD D5 pin to digital pin 4 => Teensy 22
* LCD D6 pin to digital pin 3 => Teensy 21
* LCD D7 pin to digital pin 2 => Teensy 20
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
*/
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
return 1.8 * celsius + 32;
}
//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
return celsius + 273.15;
}
// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm
double dewPoint(double celsius, double humidity)
{
double A0= 373.15/(273.15 + celsius);
double SUM = -7.90298 * (A0-1);
SUM += 5.02808 * log10(A0);
SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
SUM += log10(1013.246);
double VP = pow(10, SUM-3) * humidity;
double T = log(VP/0.61078); // temp var
return (241.88 * T) / (17.558-T);
}
// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
double a = 17.271;
double b = 237.7;
double temp = (a * celsius) / (b + celsius) + log(humidity/100);
double Td = (b * temp) / (a - temp);
return Td;
}
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(5, 4, 23, 22, 21, 20);
// Define pins for CO2 Sensor
int CO2_ReadPin = 38; // initialize pin 38 for analog voltage in
int PWM_WritePin = 14; // initialize pin 14 for PWM
int CO2_Value;
int PWM_Value;
int DutyCycle;
int ppm;
#include <Sensirion.h>
const uint8_t dataPin = 10; // SHT serial data (Teensy)
const uint8_t sclkPin = 11; // SHT serial clock (Teensy)
const uint8_t ledPin = 6; // Arduino built-in LED (Teensy)
const uint32_t TRHSTEP = 3000UL; // Sensor query period
const uint32_t BLINKSTEP = 250UL; // LED blink period
Sensirion sht = Sensirion(dataPin, sclkPin);
uint16_t rawData;
float temperature;
float humidity;
float dewpoint;
byte shtState = 0;
byte ledState = 0;
unsigned long curMillis; // Time interval tracking
unsigned long trhMillis = 0;
unsigned long blinkMillis = 0;
void setup(){
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
//lcd.print("ACHacker");
// Setup for CO2 Sensor
pinMode(PWM_WritePin, OUTPUT); // Make PWM_pin (AKA: pin 14) an output pin
int CO2_Value = 0; // variable set to zero
int PWM_Value = 0; // variable set to zero
int DutyCycle = 0; // variable set to zero
int ppm = 0; // variable set to zero
//Serial.begin(9600);
pinMode(ledPin, OUTPUT);
delay(15); // Wait at least 11 ms before first cmd
// sht.writeSR(LOW_RES); // Set sensor to low resolution
sht.measTemp(&rawData); // Maps to: sht.meas(TEMP, &rawData, BLOCK)
temperature = sht.calcTemp(rawData);
sht.measHumi(&rawData); // Maps to: sht.meas(HUMI, &rawData, BLOCK)
humidity = sht.calcHumi(rawData, temperature);
dewpoint = sht.calcDewpoint(humidity, temperature);
logData();
}
void loop()
{
curMillis = millis();
if (curMillis - blinkMillis >= BLINKSTEP) { // Time to toggle the LED state?
ledState ^= 1;
digitalWrite(ledPin, ledState);
blinkMillis = curMillis;
}
switch (shtState) {
case 0:
if (curMillis - trhMillis >= TRHSTEP) { // Start new temp/humi measurement?
sht.meas(TEMP, &rawData, NONBLOCK);
shtState++;
trhMillis = curMillis;
}
break;
case 1:
if (sht.measRdy()) { // Process temperature measurement?
temperature = sht.calcTemp(rawData);
sht.meas(HUMI, &rawData, NONBLOCK);
shtState++;
}
break;
case 2:
if (sht.measRdy()) { // Process humidity measurement?
humidity = sht.calcHumi(rawData, temperature);
dewpoint = sht.calcDewpoint(humidity, temperature);
shtState = 0;
logData();
}
break;
default:
Serial.println("How did I get here?");
break;
}
}
void logData() {
//Serial.print("Temperature = "); Serial.print(temperature);
//Serial.print(" C, Humidity = "); Serial.print(humidity);
//Serial.print(" %, Dewpoint = "); Serial.print(dewpoint);
//Serial.println(" C");
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// Loop for CO2 Sensor
CO2_Value = analogRead(CO2_ReadPin); // read Teensy input pin 38
unsigned int ppm = ((unsigned long)analogRead(CO2_ReadPin) * 2500)/1024; // calc ppm
//Serial.print("CO2 level = "); // Write ppm to serial monitor
//Serial.print(ppm);
//Serial.println(" ppm");
PWM_Value = CO2_Value/4; // Scale CO2_Value (range = 1024) to PWM_Value (range = 256)
analogWrite(PWM_WritePin, (PWM_Value + 54)); // Write PWM_Value to PWM_WritePin
//Serial.print("PWM_Value is = "); // Write val to serial monitor
//Serial.println(PWM_Value + 54);
DutyCycle = (100 * (PWM_Value + 54) / 256); // Calculate DutyCycle
//Serial.print("PWM DutyCycle = "); // Write DutyCycle to serial monitor
//Serial.print(DutyCycle);
//Serial.println("%");
//PRINTING TEMPERATURE
// set the cursor to column 0, line 0
// (note: line 0 is the first row, since counting begins with 0): %column, row%
lcd.setCursor(0, 0);
// print the Temperature title
lcd.print("Temp");
// set the cursor to column 5, line 0
// (note: line 0 is the first row, since counting begins with 0):
lcd.setCursor(5, 0);
// print the Temperature valie
//****lcd.print(Fahrenheit(DHT11.temperature), 0);
lcd.print(Fahrenheit(temperature), 0);
// set the cursor to column 7, line 0
// (note: line 0 is the first row, since counting begins with 0): %column, row%
lcd.setCursor(7, 0);
// print the Temperature 'F'
lcd.print("F");
//PRINTING RELATIVE HUMIDITY
// set the cursor to column 10, line 0
// (note: line 0 is the first row, since counting begins with 0):
lcd.setCursor(10, 0);
// print the Relative Humidity title
lcd.print("RH");
// set the cursor to column 13, line 0
// (note: line 0 is the first row, since counting begins with 0):
lcd.setCursor(13, 0);
// print the Relative Humidity value
//*****lcd.print((float)DHT11.humidity, 0);
lcd.print(humidity, 0);
// set the cursor to column 15, line 0
// (note: line 0 is the first row, since counting begins with 0): %column, row%
lcd.setCursor(15, 0);
// print the Relative Humidity percent sign
lcd.print("%");
//PRINTING CO2 READINGS
// set the cursor to column 0, line 1
// (note: line 0 is the first row, since counting begins with 0):
lcd.setCursor(2, 1);
// print the CO2 title
lcd.print("CO2 ");
// set the cursor to column 6, line 1
// (note: line 0 is the first row, since counting begins with 0):
lcd.setCursor(6, 1);
// print 'purge' characters to eliminate persistent last digit
lcd.print(" ");
// reposition the cursor to column 6, line 1
lcd.setCursor(6, 1);
// print the CO2 value
lcd.print(ppm);
// set the cursor to column 11, line 1
// (note: line 0 is the first row, since counting begins with 0): %column, row%
lcd.setCursor(11, 1);
// print the CO2 'ppm'
lcd.print("ppm");
delay(2000);
}
|