Hi guys...I am currently using Figaro TGS series gas sensors (2600, 2602 and 2620) to sense breath from
human. I already obtain the voltage output when sensed with gas samples. Would like to know is there any
way to convert the output voltage obtained to the gas concentration? Because these sensors can sense
more than one gas type so I cannot really see the gas concentration b just referring to the output voltage.
/****************Hardware Related Macros***********/
#include "MegunoLink.h"
#define TGS2602_SENSOR (0) //define analog pin to be connected in kilo ohms
#define RO_2602CLEAN_AIR_FACTOR (1) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
//which is derived from the chart in datasheet
#define TGS2600_SENSOR (1)
#define RO_2600CLEAN_AIR_FACTOR (1)
#define TGS2620_SENSOR (2)
#define RO_2620CLEAN_AIR_FACTOR (20)
#define RL_2602 (12)
#define RL_2600 (0.560)
#define RL_2620 (0.560)
/***************Software Related Macros************/
#define CALIBRATION_SAMPLE_TIMES (50) //define how many samples going to take for calibration
#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interal (in ms) for calibration
#define READ_SAMPLE_INTERVAL (50) //define no. of samples take for normal measure
#define READ_SAMPLE_TIMES (5) //define the time interal for normal measure
/**************Application Related Macros**********/
#define GAS_C7H8 (0)
#define GAS_H2S (1)
#define GAS_C2H5OH (2)
#define GAS_NH3 (3)
/**************Globals***************/
float C7H8_Curve[2] = {0.1319857248, -1.69516241}; //TGS2602 (0.3;1)( 0.08;10) (0.04;30)
float H2S_Curve[2] = {0.05566582614,-2.954075758}; //TGS2602 (0.8,0.1) (0.4,1) (0.25,3)
float C2H5OH_quarCurve[2] = {0.5409499131,-2.312489623};//TGS2602 (0.75,1) (0.3,10) (0.17,30)
float NH3_Curve[2] = {0.585030495, -3.448654502 }; //TGS2602 (0.8,1) (0.5,10) (0.3,30)
float Ro;
float Ro_2600;
float Ro_2602;
float Ro_2620;
float sensor_volt;
float Rs_cleanair;
float Ro_cleanair;
float ave_voltage=0;
float RS_sampling2602;
float RS_sampling2600;
float RS_sampling2620;
float v_out2602;
float v_out2600;
float v_out2620;
TimePlot MyPlot;
void setup() {
Serial.begin(9600);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
digitalWrite(3,HIGH);
warmingup();
Serial.println("Calibrating...\n");
Ro_2602=TGSCalibration(TGS2602_SENSOR, RO_2602CLEAN_AIR_FACTOR, RL_2602);
//Serial.println("Calibration is done...\n");
Serial.print("TGS2602:\n");
Serial.print("Ro_2602 = ");
Serial.print(Ro_2602);
Serial.print("kohm\n\n");
//Serial.print("\n");
delay(5000);
Ro_2600=TGSCalibration(TGS2600_SENSOR, RO_2600CLEAN_AIR_FACTOR, RL_2600);
Serial.print("TGS2600:\n");
Serial.print("Ro_2600 = ");
Serial.print(Ro_2600);
Serial.print("kohm\n\n");
// Serial.print("\n");
delay(5000);
Ro_2620=TGSCalibration(TGS2620_SENSOR, RO_2620CLEAN_AIR_FACTOR, RL_2620);
Serial.print("TGS2620:\n");
Serial.print("Ro_2620 = ");
Serial.print(Ro_2620);
Serial.print("kohm\n\n");
// Serial.print("\n");
delay(5000);
}
void loop() {
Serial.println(" ");
Serial.println("SAMPLING...");
Serial.print("TGS2602:");
v_out2602 = TGSGetVout(TGS2602_SENSOR);
Serial.print(" ");
Serial.print("Vout:");
Serial.print(v_out2602);
Serial.print("V");
Serial.print(" ");
RS_sampling2602=(TGSGetRs1(TGS2602_SENSOR, RL_2602));
Serial.print("Rs:");
Serial.print(RS_sampling2602);
Serial.print("kohm");
Serial.print(" ");
Serial.print("Ratio =");
Serial.print(RS_sampling2602/Ro_2602);
MyPlot.SendData("TGS2602", v_out2602);
Serial.print("\n\n");
// Serial.print("\n");
Serial.print("TGS2600:");
v_out2600 = TGSGetVout(TGS2600_SENSOR);
Serial.print(" ");
Serial.print("Vout:");
Serial.print(v_out2600);
Serial.print("V");
Serial.print(" ");
RS_sampling2600=(TGSGetRs2(TGS2600_SENSOR, RL_2600));
Serial.print("Rs:");
Serial.print(RS_sampling2600);
Serial.print("kohm");
Serial.print(" ");
Serial.print("Ratio =");
Serial.print(RS_sampling2600/Ro_2600);
MyPlot.SendData("TGS2600", v_out2600);
Serial.print("\n\n");
Serial.print("TGS2620:");
v_out2620 = TGSGetVout(TGS2620_SENSOR);
Serial.print(" ");
Serial.print("Vout:");
Serial.print(v_out2620);
Serial.print("V");
Serial.print(" ");
RS_sampling2620=(TGSGetRs3(TGS2620_SENSOR, RL_2620));
Serial.print("Rs:");
Serial.print(RS_sampling2620);
Serial.print("kohm");
Serial.print(" ");
Serial.print("Ratio =");
Serial.print(RS_sampling2620/Ro_2620);
MyPlot.SendData("TGS2620", v_out2620);
Serial.print("\n\n");
delay(2000);
}
/****************** MQResistanceCalculation ****************************************
Input: raw_adc - raw value read from adc, which represents the voltage
Output: the calculated sensor resistance
Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
across the load resistor and its resistance, the resistance of the sensor
could be derived.
************************************************************************************/
float TGSResistanceCalculation(float raw_adc, float Rl_value)
{
raw_adc= raw_adc*5.0/1023; //convert to voltage
return ( ((float)Rl_value*(5.0-raw_adc)/raw_adc)); //(vin-vout)/vout x Rl
}
/***************************** MQCalibration ****************************************
Input: mq_pin - analog channel
Output: Ro of the sensor
Remarks: This function assumes that the sensor is in clean air. It use
MQResistanceCalculation to calculates the sensor resistance in clean air
and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
10, which differs slightly between different sensors.
************************************************************************************/
float TGSCalibration(int sensor_pin, int cleanairfactor, float rl_value)
{
int i;
float val=0;
for (i=0;i<CALIBRATION_SAMPLE_TIMES;i++) { //take multiple samples
val += TGSResistanceCalculation(analogRead(sensor_pin), rl_value);
delay(CALIBRATION_SAMPLE_INTERVAL);
}
val = val/CALIBRATION_SAMPLE_TIMES; //calculate the average sensor resistance Rs in clean air
val = val/cleanairfactor; //divided by RO_CLEAN_AIR_FACTOR yields the Ro in clean air
//according to the chart in the datasheet
return val;
}
/***************************** MQRead *********************************************
Input: mq_pin - analog channel
Output: Rs of the sensor
Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
The Rs changes as the sensor is in the different consentration of the target
gas. The sample times and the time interval between samples could be configured
by changing the definition of the macros.
************************************************************************************/
float TGSGetVout(int sensor_pin)
{
int i;
float sensorValue;
float sensor_volt;
for (i=0;i<READ_SAMPLE_TIMES;i++){
sensorValue = sensorValue + analogRead(sensor_pin);
delay(READ_SAMPLE_INTERVAL);
}
sensorValue = (float)sensorValue/READ_SAMPLE_TIMES;
sensor_volt = sensorValue*5.00000/1023.00000;
return sensor_volt;
}
float TGSGetRs1(int sensor_pin, float rl_value)
{
float Rs_sampling1;
Rs_sampling1 = rl_value*(5.0-v_out2602)/v_out2602;
return Rs_sampling1;
}
float TGSGetRs2(int sensor_pin, float rL_value)
{
float Rs_sampling2;
Rs_sampling2 = rL_value*(5.0-v_out2600)/v_out2600;
return Rs_sampling2;
}
float TGSGetRs3(int sensor_pin, float RL_value)
{
float Rs_sampling3;
Rs_sampling3 = RL_value*(5.0-v_out2620)/v_out2620;
return Rs_sampling3;
}
void warmingup()
{
int i;
Serial.print(" ");
Serial.println("WARMING UP");
//digitalWrite(ledpin,HIGH); //high up yellow led when warming up
for(i=0; i<181; i++)
{
digitalWrite(4,HIGH);
delay(500);
digitalWrite(4,LOW);
delay(500);
Serial.print(i);
Serial.print(" ");
}
if (i = 180)
{
digitalWrite(4,HIGH);
Serial.println("warming complete");
}
}