MQ135 with RS485

  • Hello,

    I try to get working my MQ135 on RS485 but I cannot manage to make it working.

    I use UNO as Gateway + 2 separate sensors (DHT on UNO and MQ135 on pro mini 5V)
    DHT works correctly but MQ135 does not work.

    For testing purpose I disconnected DHT.

    I wanted to be sure that MQ135 is connected correctly so I uploaded another code and everything works correctly, But with code below I cannot send data to gateway. I used as a source of code following MySensor forum code


    MQ135 - arduino pro mini 5V
    Vcc - Vcc 5V
    GND - GND
    AO - A1

    RS485 - arduino pro mini 5V
    DI - D9
    R0 - D8
    DE/RE - D2
    GND - GND
    Vcc - Vcc 5V
    A - A(gateway RS485)
    A - A(gateway RS485)


      Arduino MQ135
      connect the sensor as follows :
      A H A   >>> 5V
      B       >>> A0
      H       >>> GND
      B       >>> 10K ohm >>> GND
      Contribution: epierre
      Based on David Gironi
    // Enable debug prints
    #define MY_DEBUG
    // Enable RS485 transport layer
    #define MY_RS485
    // Define this to enables DE-pin management on defined pin
    #define MY_RS485_DE_PIN 2
    // Set RS485 baud rate to use
    #define MY_RS485_BAUD_RATE 9600
    // Enable this if RS485 is connected to a hardware serial port
    //#define MY_RS485_HWSERIAL Serial1
    // #include <SPI.h>    
    //#include <MySensor.h>
    #include <MySensors.h>
    #include <Wire.h> 
    #define CHILD_ID_AIQ 0
    #define MQ135_DEFAULTPPM 399 //default ppm of CO2 for calibration
    #define MQ135_DEFAULTRO 68550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
    #define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
    #define MQ135_EXPONENT -2.769034857 //CO2 gas value
    #define MQ135_MAXRSRO 2.428 //for CO2
    #define MQ135_MINRSRO 0.358 //for CO2
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in seconds)
    float mq135_ro = 10000.0;    // this has to be tuned 10K Ohm
    int val = 0;                 // variable to store the value coming from the sensor
    float valAIQ =0.0;
    float lastAIQ =0.0;
    // MySensor gw;
    MyMessage msg(CHILD_ID_AIQ, V_LEVEL);
    void setup()  
    //  gw.begin();
      // Send the sketch version information to the gateway and Controller
     // gw.sendSketchInfo("AIQ Sensor MQ135", "1.0");
      // Register all sensors to gateway (they will be created as child devices)
    //  gw.present(CHILD_ID_AIQ, S_AIR_QUALITY);  
    void presentation()
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("AIQ Sensor MQ135", "1.0");
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_AIQ, S_AIR_QUALITY);  
     * get the calibrated ro based upon read resistance, and a know ppm
    long mq135_getro(long resvalue, double ppm) {
    return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
     * get the ppm concentration
    double mq135_getppm(long resvalue, long ro) {
    double ret = 0;
    double validinterval = 0;
    validinterval = resvalue/(double)ro;
    if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
    ret = (double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT);
    return ret;
    void loop()      
      uint16_t valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
      uint16_t val =  ((float)22000*(1023-valr)/valr); 
      //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
      mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
      //convert to ppm (using default ro)
      valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
      Serial.print ( "Val / Ro / value:");
      Serial.print ( val);
      Serial.print ( " / ");
      Serial.print ( mq135_ro);
      Serial.print ( " / ");
      Serial.print ( valAIQ);
      if (valAIQ != lastAIQ) {
        //  gw.send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
          lastAIQ = ceil(valAIQ);
      // Power down the radio.  Note that the radio will get powered back up
      // on the next write() call.
      //gw.sleep(SLEEP_TIME); //sleep for: sleepTime
      sleep(SLEEP_TIME); //sleep for: sleepTime
    /*****************************  MQGetPercentage **********************************
    Input:   rs_ro_ratio - Rs divided by Ro
             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(rs_ro_ratio) is provided. As it is a 
             logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
    int  MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve)
      return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1]));


    16 MCO:BGN:INIT NODE,CP=RSNNA---,REL=255,VER=2.3.1
    26 TSM:INIT
    27 TSF:WUR:MS=0
    30 TSM:FPAR
    49 TSF:MSG:SEND,255-255-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    2058 TSM:FPAR
    2075 TSF:MSG:SEND,255-255-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    4085 TSM:FPAR
    4103 TSF:MSG:SEND,255-255-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    6113 TSM:FPAR
    6130 TSF:MSG:SEND,255-255-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    8138 !TSM:FPAR:FAIL
    8139 TSM:FAIL:CNT=1
    8141 TSM:FAIL:DIS
    8143 TSF:TDI:TSL


    0;255;3;0;9;0 MCO:BGN:INIT GW,CP=RSNGA---,REL=255,VER=2.3.1
    0;255;3;0;9;5 TSM:INIT
    0;255;3;0;9;7 TSF:WUR:MS=0
    0;255;3;0;9;9 TSM:INIT:TSP OK
    0;255;3;0;9;12 TSM:INIT:GW MODE
    0;255;3;0;9;15 TSM:READY:ID=0,PAR=0,DIS=0
    0;255;3;0;9;18 MCO:REG:NOT NEEDED
    0;255;3;0;14;Gateway startup complete.
    0;255;3;0;9;23 MCO:BGN:STP
    0;255;3;0;9;29 MCO:BGN:INIT OK,TSP=1
    0;255;3;0;9;32 TSM:READY:NWD REQ
    0;255;3;0;9;52 TSF:MSG:SEND,0-0-255-255,s=255,c=3,t=20,pt=0,l=0,sg=0,ft=0,st=OK:

    Thank you very much for any help!!!

  • Now I replaced mini pro and used nano instead. Data were send successfully.

    Do you have any idea what can be wrong with mini pro?

  • @qobouky said in MQ135 with RS485:


    This basically means there's no communication between the node and GW.
    Note: at RS485 transport layer, automatic NodeID assigning methods for the nodes will not work, so you have to do it manually.
    Just saw this even isn't mentionned in the RS485 motion sketch example.☹

  • @rejoe2 said in MQ135 with RS485:


    Hmm, I tried to define sensor as 30 but still the same result. In log of sensor I can see

    114875 !TSM:FPAR:NO REPLY
    114877 TSM:FPAR
    114895 TSF:MSG:SEND,30-30-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:

    I think that it is not a case. As I told everything works with arduino nano.

    How I can check if data from sensor are reading?
    It seems that code does not continue if sensor is not connected to gateway.

  • I found an root cause.

    In pin definition was


    but should be


    I do not know why with first definition it worked with nano but did not work with mini.

Log in to reply

Suggested Topics

  • 3
  • 50
  • 5
  • 6
  • 8
  • 2
  • 2
  • 9