Because of the needs of one of our projects, we have to extract data from a CO2 sensor. We got this one, 7722 from AZ Instrument :

7722AZ

This device is a simple CO2 sensor. It gives you a measure result each second. It measures too the temperature and the relative humidity. You can set an alarm (that can activate a relay output) and it has a RS232 port to extract the measures.

This serial port is the reason of this article. You have no info about it in the manufacturer manual. Just that it sends the data each 2 seconds at 9600 bps, 8 bits of data, 1 stop bit and none flow control (classic 8N1). There are an optional cable and software to use it. We didn’t have that cable nor software.

Hardware needs

The RS-232 port in the 7722 AZ is “special”. The physical port is a 3.5mm jack and it doesn’t generate any signal. It just has an optocoupler that switchs (and inverts the signal) with the different pulses associated to a serial communication at 9600 bps. The device only transmits. It has no Rx line. With these particular characteristics, we decide to build our own cable adaptor.

Here we have a simple schema:

As you can see, we need to supply the voltage to get the signal. To make that, we use a pull-up resistor in the signal line, to be switched with GND. The value of the resistor could be changed. If you have problems, you could try to change 5k for 1k ohm. Keep in mind that this simple circuit will not generate a pure RS232 signal (-12V to +12V). This will generate a signal between 0 and Vcc (5V in our case).

Now, we need some kind of adaptor to provide any voltage to Vdd and to convert the signal to a computer. Luckily there are a lot of very cheap USB to TTL serial adaptors that fit like a charm in this case. You can get any of them for a few Euros/Dollars.

In the example model we can check the available lines:

  • DTR. Control line. Unused for us in this porject
  • RXD. Receive line. We’ll conect the TX line of the peer at this line
  • TXD. Transmision line. As our device only transmits, this line is unused for us in this project
  • +5V. This will be our Vcc line
  • GND. Nothing to comment, I guess
  • 3V3. Another alternative Vcc line

So the conections we have to make are clear:

Vcc -> +5V
Rx -> RXD
Gnd -> GND

The application

The application example was made in Python 3. So it’s mandatory to have Python3 installed in our computer.

# ____
# ____ Copyright 2021 BlackDevice @ IPGLOBAL 
# ____ Author: Francisco Dominguez
# ____

import serial 
import time 

SERIAL_PORT='/dev/ttyUSB1' 
PARAM_ERR=-1000 
# parse the result line read from the sensor 
def parse_line(src): 
    tkns = src.split(':') 
    if (len(tkns) < 3): 
        return PARAM_ERR, PARAM_ERR, PARAM_ERR 

    # parse co2 
    if (len(tkns[0]) < 7 and tkns[0] != ord('C')): 
        return PARAM_ERR, PARAM_ERR, PARAM_ERR 

    co2 = int(tkns[0][1:len(tkns[0])-3]) 

    # parse temp 
    if (len(tkns[1]) < 5 and tkns[1] != ord('T')): 
        return co2, PARAM_ERR, PARAM_ERR 

    temp = float(tkns[1][1:len(tkns[1])-1]) 

    # parse RH 
    if (len(tkns[2]) < 5 and tkns[2] != ord('H')): return co2, temp, PARAM_ERR rh = float(tkns[2][1:len(tkns[2])-1]) return co2, temp, rh # read the sensor and returns CO2 (ppm), Temperature (ºC) and Relative Humidity (%) def read_sensor(): # configure the serial connection ser = serial.Serial( port=SERIAL_PORT, baudrate=9600, timeout=1, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS ) ser.isOpen() line = ser.readline() if len(line) > 0 and line[0] == ord('C'): 
        return parse_line(line.decode('utf-8')) 
    else: 
        line = ser.readline() 
        if len(line) > 0 and line[0] == ord('C'): 
            return parse_line(line.decode('utf-8')) 

    return PARAM_ERR, PARAM_ERR, PARAM_ERR 

################################################################## 

while(1): 
    co2, temp, rh = read_sensor() 
    if (co2 == PARAM_ERR or temp == PARAM_ERR or rh == PARAM_ERR): 
        continue 

    print(f"CO2 = {co2} ppm; Temp = {temp} ºC; RH = {rh} %") 
    time.sleep(5)

Before to launch the application is necesary to determine the name of the serial port in our host. This name must be set in the line of the code that begins with SERIALPORT. In Linux it would be something like /dev/ttyUSBX. In Windows would be COMX.

The program makes a serial port read each 5 seconds. In that operation, the program reads the port and parse the content. The device transmit something similar like this each 2 seconds:

$CO2:Air:RH:DP:WBTf9
C1130ppm:T22.2C:H60.2%:d14.1C:w17.0C4a

The interesting part is the second line that is analized in the function def parse_line(src). In that function we read each parameter that are returned to be -in our case as example- printed in the console.

Privacy Preference Center