Interfacing MH-Z16 CO2 sensor with PBP?
Hello.
I have this sensor and I want to read CO2 reading from it using PBP.
According to manual, it can be done either via PWM or serial interface.
PWM works, I checked it with scope and pulse width changes according to CO2 value.
I tried to capture it with PULSIN statement, and sometimes it works a bit, sometimes - not.
first, reading loop looks like this:
32768
actual value
32768
actual value
32768
actual value
and so on
I would "filter" out 32768 quite easily, but sometimes, strange values being measured - like say, average reading is around 6000 at the moment, but there might be some measurements that are below 500 or above 40000 - for 1-2 loop iterations.
These are not sensor issues, since I checked with scope and everything works properly, there are no out of spec pulses.
I'm using PIC18F45K80 @64 mhz and here's the code:
Code:
#config
CONFIG RETEN = OFF
CONFIG INTOSCSEL = HIGH
CONFIG SOSCSEL = DIG
CONFIG XINST = OFF ;Enabled
CONFIG FOSC = INTIO1
CONFIG PLLCFG = OFF
CONFIG FCMEN = OFF ;Disabled
CONFIG PWRTEN = OFF ;Disabled
CONFIG BOREN = OFF ;Disabled in hardware, SBOREN disabled
CONFIG WDTEN = OFF ;WDT disabled in hardware; SWDTEN bit disabled
CONFIG CANMX = PORTB
CONFIG MCLRE = OFF
#endconfig
OSCTUNE.6 = 1 ; Enable 4x PLL
OSCCON = %01110000
ANCON1=0 'DISABLE ADC D3-D2-D1-D0-
ANCON0=0
ADCON0=0
TRISC=%10100001 'set PORTC
TRISD=%00000000 'set PORTD
TRISB=%00000000 'set PORTB
TRISA=%01000100 'set PORTA
TRISE=%0000000 'set PORTE
define OSC 64
DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 3
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 850
DEFINE LCD_DATAUS 30
'PORTS
PWIN VAR PORTC.0 'PWM INPUT
'VARIABLES
X VAR word 'TEMP VARIABLE 1
co2check:
PULSIN PWIN,1, X
LCDOUT $FE,$2,"CO2=", DEC X
PAUSE 100
GOTO CO2CHECK
This device also supports serial TX/RX, I tried to read serial data from it, but it does not responds to the serial statement - there are no pulses coming back from the sensor. I'm using this to query the sensor, according to the sensor manual:
https://www.winsen-sensor.com/d/files/MH-Z16.pdf
serout2 PORTA.7, 84,[$FF,$01,$86,0,0,0,0,0,$79]
Of course, I'd prefer serial output to be used, but I'm ok with PULSIN, if there's no other solutions available, but why it behaves so weirdly? connecting wires are short, and sensor outputs clean signal, but PBP detects it wrongly. Maybe this is because PWM is being read irregularly? but how can I change that?, ok, in that code I'll reduce PAUSE to say 1. But in actual code, I have other things to do...
Re: Interfacing MH-Z16 CO2 sensor with PBP?
The PULSIN command is not too reliable. I have tried something similar to the PWM measurements that you are trying to do with 2 resistors in series and a 100 nF capacitor using ADC in the PIC. Connect 2 resistors in series to ground from the PWM output from the sensor. You can try 100 kOhms both. Connect the ADC input of the PIC to the junction between the two resistors. Conn0ect a 100pF cap to ground from the ADC input port. Get a reading. Try different values for the resistors. It works. Wait like small pause fefore the ADC reading. Something like 20 uSeconds.
Re: Interfacing MH-Z16 CO2 sensor with PBP?
The PWM period of the sensor output signal is a whopping 1004ms!
At 64MHz the longest time you can measure with PULSIN is ~41ms. You'll only be able to measure at the very low end of the sensor range with that method.
There seems to be an analog output as well, perhaps you can use that if you're not able to get the serial working. Or lowpass filter the PWM signal as mentioned.
Your settings and command string does seem correct. The datasheet says "Users must use TTL level. If RS232 level, it must be converted." which to me means you should send data non-inverted (which you are). You could try sending it inverted as well, mode 16468 I believe. I'd be surprised if that's it but it's easy to try.
Sometimes the terms RXD/TXD gets mixed up. In this case the datasheet is pretty clear that RXD is the input of the device (as apposed to mean "connect to RXD on the uC). Do you have it wired correctly? Have you tried switching RXD/TXD?
Re: Interfacing MH-Z16 CO2 sensor with PBP?
Thanks!
So since pulse duration is so long, instead of pulsin I can use something like
WHILE PIN=1 A=A+1 and then count number of A's ?
For the analog output, my particular sensor does not have it, I talked to manufacturer (I bought sensor directly from them), they said this is optional feature and had to be noted when ordering the sensor.
Arduino library for the sensor is available, I'll try to connect to it later and check that way.
Re: Interfacing MH-Z16 CO2 sensor with PBP?
I just tried this, but it always returns 0...
puka:
IF PWIN=1 THEN
X=X+1
ELSE
LCDOUT $FE, $C0, DEC x, " "
PAUSE 100
x=0
ENDIF
GOTO PUKA
Re: Interfacing MH-Z16 CO2 sensor with PBP?
More than one issue with that piece of code. For one, you're running at 64MHz so it's probably going to wrap around X variable quite quickly giving you weird results. I'd try something like this:
Code:
Th VAR WORD
Tl VAR WORD
PWIN VAR PORTB.0
Main:
GOSUB Measure
LCDOUT $FE, $01, "High: ", DEC Th
LCDOUT $FE, $C0, "Low: ", DEC Tl
GOTO Main
Measure:
Th = 0
Tl = 0
WHILE !PWIN : WEND ' Wait for rising edge
WHILE PWIN ' Measure high pulse width
Th = Th + 1
PAUSEUS 999
WEND
WHILE !PWIN ' Measure low pulse width
Tl = Tl + 1
PAUSEUS 999
WEND
RETURN
Once you have that working, displaying pulsewidth values matching what you see on the scope you can A) increase resolution (if needed) and/or B) calculate PPMs or percentage or whatever you want to display. Small steps...
Re: Interfacing MH-Z16 CO2 sensor with PBP?
Thanks a lot!
Will check it tomorrow.
Re: Interfacing MH-Z16 CO2 sensor with PBP?
Just tried this code, it works fine, "High" displays readings consistent with actual CO2 concentrations, LOW displays some fixed numbers which only slightly change.