//////////////////////////////////////////////////////////////////////
/*Author: Tiequan Shao: tiequan.shao@sandboxelectronics.com
Peng Wei: peng.wei@sandboxelectronics.com
Lisence: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
Note: This piece of source code is supposed to be used as a demostration ONLY. More
sophisticated calibration is required for industrial field application.
Sandbox Electronics 2012-05-31
************************************************************************************/
/************************Hardware Related Macros************************************/
#define MG_PIN (0) //define which analog input channel you are going to use
#define BOOL_PIN (2)
#define DC_GAIN (8.5) //define the DC gain of amplifier
/***********************Software Related Macros************************************/
#define READ_SAMPLE_INTERVAL (50) //define how many samples you are going to take in normal operation
#define READ_SAMPLE_TIMES (5) //define the time interval(in milisecond) between each samples in
//normal operation
/**********************Application Related Macros**********************************/
//These two values differ from sensor to sensor. user should derermine this value.
#define ZERO_POINT_VOLTAGE (0.220) //define the output of the sensor in volts when the concentration of CO2 is 400PPM
#define REACTION_VOLTGAE (0.020) //define the voltage drop of the sensor when move the sensor from air into 1000ppm CO2
/*****************************Globals***********************************************/
float CO2Curve[3] = {2.602,ZERO_POINT_VOLTAGE,(REACTION_VOLTGAE/(2.602-3))};
//two points are taken from the curve.
//with these two points, a line is formed which is
//"approximately equivalent" to the original curve.
//data format:{ x, y, slope}; point1: (lg400, 0.324), point2: (lg4000, 0.280)
//slope = ( reaction voltage ) / (log400 –log1000)
void setup()
{
Serial.begin(9600); //UART setup, baudrate = 9600bps
pinMode(BOOL_PIN, INPUT); //set pin to input
digitalWrite(BOOL_PIN, HIGH); //turn on pullup resistors
Serial.print("MG-811 Demostration\n");
}
void loop()
{
int percentage;
float volts;
volts = MGRead(MG_PIN);
Serial.print( "SEN-00007:" );
Serial.print(volts);
Serial.print( "V " );
percentage = MGGetPercentage(volts,CO2Curve);
Serial.print("CO2:");
if (percentage == -1) {
Serial.print( "<400" );
} else {
Serial.print(percentage);
}
Serial.print( "ppm" );
Serial.print( " Time point:" );
Serial.print(millis());
Serial.print("\n");
if (digitalRead(BOOL_PIN) ){
Serial.print( "=====BOOL is HIGH======" );
} else {
Serial.print( "=====BOOL is LOW======" );
}
Serial.print("\n");
delay(200);
}
/***************************** MGRead *********************************************
Input: mg_pin - analog channel
Output: output of SEN-000007
Remarks: This function reads the output of SEN-000007
************************************************************************************/
float MGRead(int mg_pin)
{
int i;
float v=0;
for (i=0;i<READ_SAMPLE_TIMES;i++) {
v += analogRead(mg_pin);
delay(READ_SAMPLE_INTERVAL);
}
v = (v/READ_SAMPLE_TIMES) *5/1024 ;
return v;
}
/***************************** MQGetPercentage **********************************
Input: volts - SEN-000007 output measured in volts
pcurve - pointer to the curve of the target gas
Output: ppm of the target gas
Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
of the line could be derived if y(MG-811 output) is provided. As it is a
logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
value.
************************************************************************************/
int MGGetPercentage(float volts, float *pcurve)
{
if ((volts/DC_GAIN )>=ZERO_POINT_VOLTAGE) {
return -1;
} else {
return pow(10, ((volts/DC_GAIN)-pcurve[1])/pcurve[2]+pcurve[0]);
}
}
///////////////////////////////////////////////////////////////////////////
Few things to remember about this sensor is that it has an on-board potentiometer that is adjusted using a plus-tipped Philips screwdriver. The technique used for this test is to turn the potentiometer clockwise at the edge of lighting up. Exposure to the CO2 source indicate that the sensor does detect CO2. Tinkering with the potentiometer to get the desired sensitivity is recommended because it is very reliant on a good calibration for its detection. Another important point is that the change in resistance in the sensor board happens through a chemical reaction happening on the MG811 CO2 sensor, which explains the delayed reaction from the sensor's output.
In official sensor tests, the sensors were subjected to extreme temperatures and pressure. On the former, the sensor was put in a less than 40 degrees Celsius environment. The ozone sensor gave out and the carbon dioxide mysteriously stopped functioning. In investigation of what might have went wrong, datasheets about the CO2 sensor indicate that it does not read CO2 levels below 400ppm. This officially disqualifies this sensor from the experiment because we were expecting significantly less CO2 at the 20-30 km altitude.
Here are some recommendations for future projects, high-altitude balloons and whatnot:
- Spend more time on the documentation and previous project articles about this sensor as its code has a lot of information that could be vexing to anyone uninformed.
- Try to look for videos with experimentation regarding the sensor. This is where I got the CO2 source idea
- Have better packaging for the delivery of the sensor. Transit damages is a big pain because transit usually takes weeks.
- Check datasheets and check if it meets project's goal
Here are some links pertinent to this report:
Trello: https://trello.com/c/3DYC0UZo/15-sainsmart-mg811-gas-co2-carbon-dioxide-sensor
Sainsmart Site: http://www.sainsmart.com/sainsmart-mg811-gas-co2-carbon-dioxide-sensor-module-sensor-module.html
Spencerpages: http://www.spencerpages.com/wiki/index.php?title=MG811_Carbon_Dioxide_(CO2)_Sensor
No comments:
Post a Comment