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
Connection
MQ135 - arduino pro mini 5V
Vcc - Vcc 5V
GND - GND
AO - A1RS485 - arduino pro mini 5V
DI - D9
R0 - D8
DE/RE - D2
GND - GND
Vcc - Vcc 5V
A - A(gateway RS485)
A - A(gateway RS485)CODE
/* 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 http://davidegironi.blogspot.fr/2014/01/cheap-co2-meter-using-mq135-sensor-with.html http://skylink.dl.sourceforge.net/project/davidegironi/avr-lib/avr_lib_mq135_01.zip */ // 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 AIQ_SENSOR_ANALOG_PIN 1 #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) //VARIABLES 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 Serial.println(val); 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))); 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 value. ************************************************************************************/ int MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve) { return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1])); }
SENSOR LOG
16 MCO:BGN:INIT NODE,CP=RSNNA---,REL=255,VER=2.3.1 26 TSM:INIT 27 TSF:WUR:MS=0 28 TSM:INIT:TSP OK 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: 2056 !TSM:FPAR:NO REPLY 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: 4083 !TSM:FPAR:NO REPLY 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: 6111 !TSM:FPAR:NO REPLY 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
GATEWAY LOG
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;0;0;18;2.3.1 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:
!TSM:FPAR:FAIL
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:
NodeID
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
#define AIQ_SENSOR_ANALOG_PIN 1
but should be
#define AIQ_SENSOR_ANALOG_PIN A1
I do not know why with first definition it worked with nano but did not work with mini.