SEN0159 CO2 sensor spark core code


I’ve some issues hooking up a SEN0159 CO2 sensor. The following code works on a arduino, but does not work using a spark core when reading through the serial monitor. The result is never bigger than 400 ppm, which is impossible. When logging the different parts of the script i found out the issues is probably in the lower part of the script, where the MGGetPercentage calculation is happening. Can someone tell why?

#include "math.h";

/************************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.324) //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
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) 

int co2 = 0;
  //  int percentage;
  //  float volts;

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");                

 //   Spark.variable("CO2", &co2, int);
//    Spark.variable("percentage", &percentage, int);
//    Spark.variable("volts", &volts, float);

void loop()
     int sensorValue = analogRead(A1);
    int percentage;
    float volts;
//    Spark.variable("CO2", &co2, int);
//    Spark.variable("percentage", &percentage, int);
//    Spark.variable("volts", &volts, float);
    volts = MGRead(MG_PIN);
    Serial.print( "SEN0159:" );
    Serial.print( "V           " );
    percentage = MGGetPercentage(volts,CO2Curve);
 //   Serial.println(CO2Curve);
  //  Serial.println(MGRead);
    if (percentage == -1) {
        Serial.print( "<400" );
    } else {
    Serial.print( "ppm" );  
    Serial.print( "       Time point:" );
    if (digitalRead(BOOL_PIN) ){
        Serial.print( "=====BOOL is HIGH======" );
    } else {
        Serial.print( "=====BOOL is LOW======" );
/*****************************  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);
    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 
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]);

Have you taken into account that the Core works on 3.3V and the ADC returns a value in the range of 0…4095 (12bit) rather than 0…1024 (10bit)?

So if you power your sensor via 5V you may even damage the ADC pin, if your reading would exceed 3.3V (66% of max output)

1 Like