1
+ /* 1.0.0 VERSION */
2
+
3
+ #include " ddmq4.h"
4
+
5
+ DDMQ4::DDMQ4 (int pin)
6
+ {
7
+ this ->_analogPin = pin;
8
+ }
9
+
10
+ DDMQ4Val DDMQ4::getValue ()
11
+ {
12
+
13
+ float sensor_volt; // Define variable for sensor voltage
14
+ float RS_gas; // Define variable for sensor resistance
15
+ float ratio; // Define variable for ratio
16
+
17
+ float sensorValue = analogRead (this ->_analogPin );
18
+
19
+ sensor_volt = sensorValue * (3.3 / 1023.0 ); // Convert analog values to voltage
20
+ RS_gas = ((3.3 * 10.0 ) / sensor_volt) - 10.0 ; // Get value of RS in a gas
21
+ ratio = RS_gas / this ->_R0 ; // Get ratio RS_gas/RS_air
22
+
23
+ double ppm_log = (log10 (ratio) - this ->_b ) / this ->_m ; // Get ppm value in linear scale according to the the ratio value
24
+ double ppm = pow (10 , ppm_log); // Convert ppm value to log scale
25
+ double percentage = ppm / 10000 ; // Convert to percentage
26
+
27
+ float realValue = 0.0 ;
28
+
29
+ if (sensorValue > this ->_valorecentrale )
30
+ {
31
+ realValue = this ->fscale (this ->_valorecentrale , 1023 , 1000 , 10000 , sensorValue, 10 );
32
+ }
33
+ else
34
+ {
35
+ realValue = this ->fscale (0 , this ->_valorecentrale , 200 , 1000 , sensorValue, 10 );
36
+ }
37
+
38
+ DDMQ4Val ret;
39
+ ret.realValue = realValue;
40
+ ret.ppm = ppm;
41
+ ret.sensorValue = sensorValue;
42
+ ret.percentage = percentage;
43
+ ret.success = true ;
44
+
45
+ return ret;
46
+ }
47
+
48
+ float DDMQ4::fscale (float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve)
49
+ {
50
+
51
+ float OriginalRange = 0 ;
52
+ float NewRange = 0 ;
53
+ float zeroRefCurVal = 0 ;
54
+ float normalizedCurVal = 0 ;
55
+ float rangedValue = 0 ;
56
+ boolean invFlag = 0 ;
57
+
58
+ // condition curve parameter
59
+ // limit range
60
+
61
+ if (curve > 10 )
62
+ curve = 10 ;
63
+ if (curve < -10 )
64
+ curve = -10 ;
65
+
66
+ curve = (curve * -.1 ); // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
67
+ curve = pow (10 , curve); // convert linear scale into lograthimic exponent for other pow function
68
+
69
+ /*
70
+ Serial.println(curve * 100, DEC); // multply by 100 to preserve resolution
71
+ Serial.println();
72
+ */
73
+
74
+ // Check for out of range inputValues
75
+ if (inputValue < originalMin)
76
+ {
77
+ inputValue = originalMin;
78
+ }
79
+ if (inputValue > originalMax)
80
+ {
81
+ inputValue = originalMax;
82
+ }
83
+
84
+ // Zero Refference the values
85
+ OriginalRange = originalMax - originalMin;
86
+
87
+ if (newEnd > newBegin)
88
+ {
89
+ NewRange = newEnd - newBegin;
90
+ }
91
+ else
92
+ {
93
+ NewRange = newBegin - newEnd;
94
+ invFlag = 1 ;
95
+ }
96
+
97
+ zeroRefCurVal = inputValue - originalMin;
98
+ normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float
99
+
100
+ /*
101
+ Serial.print(OriginalRange, DEC);
102
+ Serial.print(" ");
103
+ Serial.print(NewRange, DEC);
104
+ Serial.print(" ");
105
+ Serial.println(zeroRefCurVal, DEC);
106
+ Serial.println();
107
+ */
108
+
109
+ // Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine
110
+ if (originalMin > originalMax)
111
+ {
112
+ return 0 ;
113
+ }
114
+
115
+ if (invFlag == 0 )
116
+ {
117
+ rangedValue = (pow (normalizedCurVal, curve) * NewRange) + newBegin;
118
+ }
119
+ else // invert the ranges
120
+ {
121
+ rangedValue = newBegin - (pow (normalizedCurVal, curve) * NewRange);
122
+ }
123
+
124
+ return rangedValue;
125
+ }
0 commit comments