-
Notifications
You must be signed in to change notification settings - Fork 0
/
CO2-concentration.ino
96 lines (84 loc) · 4.13 KB
/
CO2-concentration.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#define MG_PIN (0) //define which analog input channel you are going to use
#define BOOL_PIN (2) //Arduino D2-CO2 sensor digital pinout, labled with "D" on PCB
#define DC_GAIN (8.5) //define the DC gain of amplifier
/***********************Software Related Macros************************************/
#define READ_SAMPLE_TIMES (10) //define how many samples you are going to take in normal operation
#define READ_SAMPLE_INTERVAL (50) //define the time interval(in milisecond) between each samples in
//normal operation
/**********************Application Related Macros**********************************/
//These values differ from sensor to sensor. User should derermine this value.
#define ZERO_POINT_X (2.602) //lg400=2.602, the start point_on X_axis of the curve
#define ZERO_POINT_VOLTAGE (0.324) //define the output of the sensor in volts when the concentration of CO2 is 400PPM
#define MAX_POINT_VOLTAGE (0.265) //define the output of the sensor in volts when the concentration of CO2 is 10,000PPM
#define REACTION_VOLTGAE (0.059) //define the voltage drop of the sensor when move the sensor from air into 1000ppm CO2
/*****************************Globals***********************************************/
float CO2Curve[3] = {ZERO_POINT_X, ZERO_POINT_VOLTAGE, (REACTION_VOLTGAE / (2.602 - 4))};
//Two points are taken from the curve.With these two points, a line is formed which is
//"approximately equivalent" to the original curve. You could use other methods to get more accurate slope
//CO2 Curve format:{ x, y, slope};point1: (lg400=2.602, 0.324), point2: (lg10000=4, 0.265)
//slope = (y1-y2)(i.e.reaction voltage)/ x1-x2 = (0.324-0.265)/(log400 - log10000)
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( "SEN0159:" );
Serial.print(volts);
Serial.print( "V " );
percentage = MGGetPercentage(volts, CO2Curve);
Serial.print("CO2:");
if (percentage == -1) {
Serial.print("Under heating/beyond range(400~10,000)");
} 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(1000);
}
/***************************** 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) {
volts = volts / DC_GAIN;
if (volts > ZERO_POINT_VOLTAGE || volts < MAX_POINT_VOLTAGE ) {
return -1;
} else {
return pow(10, (volts - pcurve[1]) / pcurve[2] + pcurve[0]);
volts = 0;
}
}