In this tutorial we will create an I2C scanner for the Raspberry Pi PIco.
Sometimes you get a sensor and are not sure the I2C address or you may have a sensor library that does not work for some reason and this may be because the sensor supports multiple I2C addresses and the default one in the library may be different from your hardware.
I have seen this with a few sensors and in particular OLED displays – the library may be 0x3C and the display is set to 0x3D
We have a couple of citcuitpython sensor examples on this site where we have to set the I2C address
Parts Required
Just a Raspberry Pi Pico required for this one
Name | Link |
Pico | Raspberry Pi Pico Development Board |
Code Examples
We have examples here for Micropython, Circuitpython and the Arduino IDE
Micropython
[codesyntax lang=”python”]
import machine sda=machine.Pin(0) scl=machine.Pin(1) i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000) print('Scan i2c bus...') devices = i2c.scan() if len(devices) == 0: print("No i2c device !") else: print('i2c devices found:',len(devices)) for device in devices: print("Decimal address: ",device," | Hexa address: ",hex(device))
[/codesyntax]
CircuitPython
[codesyntax lang=”python”]
import board import busio i2c = busio.I2C(scl=board.GP1, sda=board.GP0) count = 0 # Wait for I2C lock while not i2c.try_lock(): pass # Scan for devices on the I2C bus print("Scanning I2C bus") for x in i2c.scan(): print(hex(x)) count += 1 print("%d device(s) found on I2C bus" % count) # Release the I2C bus i2c.unlock()
[/codesyntax]
Arduino
If you have arduino support installed for the Raspberry Pi Pico then this all you need. We will do a write up of Arduino support in another article. I’m using the one from https://github.com/earlephilhower/arduino-pico
[codesyntax lang=”cpp”]
#include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for next scan }
[/codesyntax]