DFRobot O2 sensor not responding via UART

userHead Paul.Holloway 2023-08-04 11:04:56 687 Views3 Replies

Hi,

I'm new here, and after some help. I'm having an issue with my raspberry pi pico communicating with my DFRobot Gravity O2 sensor via UART. I can get the O2 values from the sensor in the default ‘initiative’ mode where it sends data every 1 sec and the values seem fine. However when I send FF 01 78 04 00 00 00 00 83 to sent to question/answer mode, I do not get the confirmation of mode being set (78 01 00 00 00 00 00 87) and the sensor continues to read every second giving a signal that start ‘ FF 88’ suggesting it is still in default mode (I should be getting a response starting FF 86 as per these instructions ).

Does anyone have any suggestions? Could it be a hardware issue or is it my code?

 

My micropython code is: 

 

from machine import UART, Pin
from time import sleep

uart0 = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1), timeout=500)#the UART pins are actually backward on the sensor
uart0.init(9600, bits=8, stop=1)#maybe comment out
uart0.flush()
sleep(1)

while True:

   sleep(1)
   uart0.flush()
   #request question/answer mode, expected response 'xff x78 x01 x00 x00 x00 x00 x00 x87 
   sequence_to_send =b'\xff\x01\x78\x04\x00\x00\x00\x00\83'
   uart0.write(sequence_to_send)
   if uart0.any():
       O2uart = uart0.read()
    
       print("{}".format(O2uart))
   else:
       print("O2 Sensor Error")
   #actual response "b'\xff\x88\x00\xc9\x05\x01\x01\xe4\xa8\"
   uart0.flush()
   sleep(1)
   #request read, expected response starts '\xff\x86'
   sequence_to_send =b'\xff\x01\x86\x04\x00\x00\x00\x00\79'
   uart0.write(sequence_to_send) 
   if uart0.any():
       O2uart = uart0.read()
      
       print("{}".format(O2uart))
   else:
       print("O2 Sensor Error")
   #actual response starts 'xff\x88'
 

The working code for measureing O2 from the default initiative mode is:

from machine import UART, Pin
from time import sleep

uart0 = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1), timeout=500)#the UART pins are actually backward on the sensor
uart0.init(9600, bits=8, stop=1)#maybe comment out
uart0.flush()
sleep(1)
   
while True:
   uart0.flush()

   sleep(1)
           
   if uart0.any():
       O2uart = uart0.read()
       O2high = O2uart[2]
       O2low = O2uart[3]
       O2 = (O2high * 256 + O2low)*0.1

       
       print("{}%".format(O2))
   else:
       print("O2 Sensor Error")
 

2023-08-16 01:25:59

Hi!

 

Please try to use the I2C mode and scan through the I2C address code to see if the address can be scanned.

https://www.digikey.com/en/maker/projects/raspberry-pi-pico-rp2040-i2c-example-with-micropython-and-cc/47d0c922b79342779cdbd4b37b7eb7e2

userHeadPic jenna
Paul.Holloway wrote:

Thanks @jenna! I'll give this a go to see if I get a response. I've never tried I2C before, so the resource is very useful. I'll let you know how I get on.

2023-09-08 08:43:06
Paul.Holloway wrote:

I finally got round to getting it to work on I2C. Still no luck with UART. But I2C works nicely. The code that works on RP pico using micropython is below in case anyone needs it:

 

from machine import Pin, I2Cimport timeI2C_interface=(0)sdapin= Pin(0)sclpin= Pin(1)

i2c = I2C(I2C_interface, scl=sclpin, sda=sdapin,freq=100000) OXYGEN_I2C_ADDRESS = 0x74sendbuf = bytearray(9)  recvbuf = bytearray(9)O2Reading = 0.0

def clear_buffer(buf,length): for i in range(0,length):   buf[i]=0

#check O2 Sensor connectiontry:   i2c.readfrom(OXYGEN_I2C_ADDRESS, 1)   print("I2C O2 connect success!")except OSError:   print("I2C O2 device error!")

 

def fuc_check_sum(i,ln): tempq=0 for j in range(1,ln-1):   tempq+=i[j] tempq=(((~tempq)&0xff)**) return tempq

# 0x04 is used to set O2 sensor to passive mode. Then check if recvbuf[2]=1 to see if mode change is completeO2mode_Passive = bytearray([0xFF, 0x01, 0x78, 0x04, 0x00, 0x00, 0x00, 0x00, fuc_check_sum(sendbuf,8)])i2c.writeto(0x74, O2mode_Passive)time.sleep(0.1)i2c.readfrom_into(0x74, recvbuf)if(recvbuf[2]==1):   print ("O2 mode changed to passive")else:   print ("Failed to change O2 to passive")

def O2Read():   global recvbuf   clear_buffer(recvbuf,9)   CheckO2 = bytearray([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, fuc_check_sum(sendbuf,8)])   i2c.writeto(0x74, CheckO2)   time.sleep(0.1)   recvbuf = bytearray(9)   i2c.readfrom_into(0x74, recvbuf)   if(fuc_check_sum(recvbuf,8) == recvbuf[8]):     O2Reading = ((recvbuf[2]<<8)+recvbuf[3])*1.0     decimal_digits = recvbuf[5]     if decimal_digits == 1:       O2Reading = O2Reading * 0.1       return O2Reading      elif decimal_digits == 2:       O2Reading = O2Reading * 0.01       return O2Reading    else: # Read failure. Readings of 100 concidered failure     O2Reading = 100     return O2Reading

while True:   O2 = O2Read()   print (O2)   time.sleep(1) 

 

2023-11-04 08:35:05
2 Replies