GravityTroubleshooting

How to read SEN0465 Oxygen Sensor with Micro:bit on MakeCode Python

userHead Marco Antonio PG 2026-06-15 01:23:18 7 Views0 Replies

Tutorial: How to read DFRobot Oxygen Sensor (SEN0465) with Micro:bit in MakeCode Python

 

The Problem

When trying to connect the SEN0465 oxygen sensor (on the DFRobot Gas Sensor V1.1 base) to a Micro:bit using MakeCode, you might run into a hurdle: there are no official blocks, and sending a standard I2C read command only returns null values (0x00 or 0xFF).

 

This happens because the module does not act like standard I2C memory. To wake up and transmit the oxygen concentration, it requires a strict 9-byte data frame, which includes a start header (0xFF), the master command (0x88), and a Checksum (0x77) at the end.

 

If the MakeCode compiler does not send the memory buffer in this exact format, the sensor completely ignores the request.

 

Hardware Setup & Physical Connections

1. DIP Switches

For the module to communicate via the I2C bus and use memory address 0x74 (the one used in our code), the small switches on the V1.1 base must be set to the 0 (OFF) position:

-SEL: 0 (Enables I2C mode)

-A1: 0

-A0: 0

 

2. Wiring to the Micro:bit

Connect the sensor directly to your Micro:bit expansion board using the nomenclature printed on the base's silkscreen:

-(+) -> 3.3V (or 3V)

-(-) -> GND

-(C/R) -> Pin SCL 19

-(D/T) -> Pin SDA 20

 

The Solution: Validated Code for MakeCode Python

The MakeCode compiler is very strict with memory management. To avoid overflow errors, we must instantiate a 9-byte buffer, populate it sequentially, and include an anti-noise validation filter that checks for the correct response header (0xFF) before calculating the percentage.

Copy and paste the following code into the Python tab of MakeCode:

Python

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


# 1. Global Variables (Default address for DFRobot base)
I2C_ADDR = 0x74

# 2. Strict 9-byte master frame
CMD_O2 = bytearray(9)
CMD_O2[0] = 0xFF # Header
CMD_O2[1] = 0x01
CMD_O2[2] = 0x88 # "Read all data" command
CMD_O2[3] = 0x00
CMD_O2[4] = 0x00
CMD_O2[5] = 0x00
CMD_O2[6] = 0x00
CMD_O2[7] = 0x00
CMD_O2[8] = 0x77 # Checksum

# 3. Robust reading function
def read_oxygen():
   # Write the command to the bus
   pins.i2c_write_buffer(I2C_ADDR, CMD_O2, False)
   basic.pause(100) # Sensor processing time
   
   # Read the 9-byte response
   resp = pins.i2c_read_buffer(I2C_ADDR, 9, False)
   
   # 4. Validation: Check the packet header (Anti-noise filter)
   if resp[0] == 0xFF:
       # Valid packet, extract High and Low concentration bytes
       b_high = resp[2]
       b_low = resp[3]
       
       # Bitshift and calculation
       raw_concentration = (b_high << 8) | b_low
       return raw_concentration / 10
   else:
       # Invalid packet (returns error to prevent false alarms)
       return -1

# --- Main Loop ---
def on_forever():
   percentage = read_oxygen()
   
   # Check if the reading was successful (20.9% is normal in open air)
   if percentage != -1:
       serial.write_line("O2: " + str(percentage) + " %")
   else:
       serial.write_line("Read error: Check I2C connection")
       
   basic.pause(1000)

basic.forever(on_forever)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Quick Test:

Open your device's serial console. To confirm the sensor is actually measuring gas displacement, you can place a glass over the probe and light a lighter inside to consume the trapped oxygen. You will see the console readings drop quickly from 20.9% down to deficiency levels (around 18%), confirming your code works perfectly.