Ich habe mich diese Woche mit dem TGS4161 beschäftigt und wollte es mit
euch Teilen.
Die max mV Ausgabe pegelt sich nach ein paar Tagen Laufzeit auf einen
Wert ein.
Das Delta_mV (ist max mV - aktuell mV) ist von Sensor zu Sensor
unterschiedlich, deswegen muss man 2 Werte auslesen.
Am besten wert 1 bei 350ppm, sind bei mir deltamV = 0 mV und wert 2 bei
3000ppm sind das deltamV = 64 mV. Das dann einfach in den Code einsetzen
und fertig.
Schaltplan, Formel Herleitung und AVR/Arduino Code sind in der PDF.
Ich dividiere den ADC Volt wert durch 7.8 weil das mein
Verstärkungsfaktor ist.
Hier der Komplette Arduino Code:
1 | #include <math.h>
|
2 |
|
3 | #define x1 350
|
4 | #define y1 0
|
5 | #define x2 3000
|
6 | #define y2 64
|
7 |
|
8 | double mv2ppm(double delta_mv) {
|
9 | double a = (y1 - (((y2 * log(x1)) - (y1 * log(x2))) / (log(x1) - log(x2)))) / log(x1);
|
10 | double b = (((y2 * log(x1)) - (y1 * log(x2))) / (log(x1) - log(x2)));
|
11 | return exp((delta_mv - b) / a);
|
12 | }
|
13 |
|
14 |
|
15 | void setup() {
|
16 | Serial.begin(9600);
|
17 | Serial.println("Start CO2");
|
18 | pinMode(A0, INPUT);
|
19 | digitalWrite(A0, HIGH);
|
20 | }
|
21 |
|
22 | void loop() {
|
23 | uint16_t calVal = 0;
|
24 | uint16_t sensorVal = getAverage(A0, 100, 5);
|
25 |
|
26 | if (calVal < sensorVal)
|
27 | calVal = sensorVal;
|
28 | double volt = computeVolts(sensorVal);
|
29 | double sensorVolt = (volt / 7.8) * 1000;
|
30 | double calVolt = (computeVolts(calVal) / 7.8) * 1000;
|
31 | double EMF = calVolt - sensorVolt;
|
32 | double ppm = mv2ppm(EMF);
|
33 | Serial.print("ADC: ");
|
34 | Serial.print(sensorVal);
|
35 | Serial.print(" / ");
|
36 | Serial.print(volt);
|
37 | Serial.println("V");
|
38 | Serial.print("Sensor: ");
|
39 | Serial.print(sensorVolt);
|
40 | Serial.println("mV");
|
41 | Serial.print("Calibration: ");
|
42 | Serial.print(calVolt);
|
43 | Serial.println("mV");
|
44 | Serial.print("EMF:");
|
45 | Serial.print(EMF);
|
46 | Serial.println("mV");
|
47 | Serial.print("CO2: ");
|
48 | Serial.print(int(ppm));
|
49 | Serial.println("ppm");
|
50 |
|
51 | if (ppm < 500)
|
52 | Serial.println("Green");
|
53 | if (ppm >= 500 && ppm < 1000)
|
54 | Serial.println("Yellow");
|
55 | if (ppm >= 1000)
|
56 | Serial.println("Red");
|
57 |
|
58 | Serial.println();
|
59 |
|
60 | delay(5000);
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 | double computeVolts(int rawADC) {
|
66 | return ((rawADC * 4.95) / 1023.0);
|
67 | }
|
68 |
|
69 | uint16_t getAverage(byte sensorPin, int avgNum, int del) {
|
70 | int i = 0;
|
71 | long sum = 0;
|
72 | unsigned int value = 0;
|
73 | unsigned int result = 0;
|
74 |
|
75 | for (i = 0 ; i < avgNum ; i++)
|
76 | {
|
77 | value = analogRead(sensorPin);
|
78 | sum = sum + value;
|
79 | delayMicroseconds(del);
|
80 | }
|
81 | result = sum / avgNum;
|
82 | return (result);
|
83 | }
|