[SOLVED] UART and MH-Z16 CO2 sensor



  • Hello there! :)

    I am having some trouble communicating with this CO2 sensor.
    This it's wiki with sample code, and this is the datasheet.

    Okay so I think my issue is related to byte conversion but not sure.

    from machine import UART
    uart = UART(1, 9600) 
    uart.write(b'\xFF\x01\x86\x00\x00\x00\x00\x00\x79') # This is what should trigger the measure 
    uart.read(9) #b'\xff\x86\x01\xecF\x00\x00\x00G' #This is the answer
    

    I am not sure how to process the read value.. The first 2 number is always ff and 86 the next is always small, then the 4th is something weird.. then always 2 zero, and zero with a letter in the and.
    So do you have any idea how can I get proper measurment out of it? Thank you!



  • @robert-hh Thank you! :)
    I got it now. It's work like it's should.
    Maybe I should to open the window :D


  • Global Moderator

    @tttadam Using struct.unpack, you can also use:

    from machine import UART
    from struct import unpack
    uart = UART(1, 9600) 
    uart.write(b'\xFF\x01\x86\x00\x00\x00\x00\x00\x79') # This is what should trigger the measure 
    response = uart.read(9)
    cmd, concentration, check = unpack(">xBh4xB", response)
    checksum = (256 - sum(response[1:-1])) % 256
    print(concentration, checksum == check)
    

  • Global Moderator

    @tttadam The checksum is just to be used to verify, that the data was received correctly. The calculated value should be identical to response[8]. Note that I changed the code, such that the checksum is always positive.



  • @robert-hh Thank you. The code is working, but the values seems to be off, and I am not sure how should I understood the checksum. Should I calibrate the sensor somehow?
    response: 586
    checksum: -29

    response: 590
    checksum: -33

    response: 667
    checksum: -112


  • Global Moderator

    @tttadam Look at the struct module. It allows to unpack a bytearray into individual data elements. You can also make it simpler,. just following the manual:

    from machine import UART
    uart = UART(1, 9600) 
    uart.write(b'\xFF\x01\x86\x00\x00\x00\x00\x00\x79') # This is what should trigger the measure 
    response = bytearray(uart.read(9)) #
    concentration = response[2] * 256 + response[3]
    checksum = (256 - sum(response[1:-1])) % 256
    print(concentration)
    

    The last byte is the checksum. It looks as if the sample C code in the data sheet is wrong. The variable checksum is not initialized to 0.
    Edit: Checksum simplified



Pycom on Twitter