MicroPython Driver for PCT2075 Sensor
Contents
Introduction
This a MicroPython driver written specifically for the BBC micro:bit that will work with both the PCT2075 ambient temperature sensor and its predecessor, the LM75A.
The PCT2075 is a digital temperature only sensor. In addition to returning temperature readings it also has a fairly standard (for this style of sensor) watchdog which provides over-temperature alerting.
The PCT2075 sensor is discussed in some detail here. Additionally, if the watchdog is to be used in a serious manner then the product datasheet should also be carefully consulted.


The Small Outline packaging of this sensor is not particularly breadboard friendly. Fortunately relatively inexpensive breakout boards are available.
Connecting the PCT2075
The PCT2075 communicates via I2C. Hooking it up to the micro:bit is easy:
micro:bit | PCT2075 |
---|---|
3.3V | VCC |
GND | GND |
Pin 20 | SDA |
Pin 19 | SCL |
Any available digital pin (Optional) |
INT |
This utilises the standard I2C pins of the micro:bit.
Connecting the INT pin is only necessary if the temperature watchdog will be used. The driver however does provides the full watchdog functionality if the user's MicroPython program chooses to take advantage of it.
Driver Overview
The PCT2075 chip is a drop-in replacement for the older LM75A chip. It implements all LM75A functionality while adding a couple of nice extras.
Therefore the code starting block for this PCT2075 driver is the micro:bit's LM75A MicroPython driver. The LM75A() base class is extended with the derived class, PCT2075(), which adds the extra PCT2075 methods.
Driver codeThe driver code can be:
- Copied from this webpage onto the clipboard then pasted into the MicroPython editor e.g. the Mu Editor. It should be saved as fc_lm75a_pct2075.py - OR -
- Download as a zip file using the link. Unzip the file and save it as fc_lm75a_pct2075.py into the default directory where the MicroPython editor e.g. Mu Editor saves python code files.
After saving the fc_lm75a_pct2075.py file to the computer it should be copied to the small filesystem on the micro:bit. The examples on this page will not work if this step is omitted. Any MicroPython editor that recognises the micro:bit will have an option to do this.
The Mu Editor is recommended for its simplicity. It provides a Files button on the toolbar for just this purpose.
I2C addressThe PCT2075 chip has three pins; A0, A1, A2 for setting the I2C address. Each pin is connected independently to either VCC, GND or left floating (not attached to anything). This gives a choice of 27 addresses!
The rear of the breakout board exposes these three pins as solderable jumpers for a 'permanent' address assignment.
Additionally, the A0, A1 and A3 leads from the chip are exposed as pins on the breakout board's front face. This allows quick (temporary) address assignment if using a breadboard as part of the project. All three pins by default are left floating which gives an I2C address of 0x37.
There is a table in the product Datasheet that provides all of the 27 address options.
Class constructorThe driver is implemented as a class. The first thing to do is call the constructor. This provides an instance of the class.
Syntax:
instance = PCT2075(Addr = 0x37)
Where:
Addr : The I2C address. There are a total
of 27 different addresses available.
However they are not in one contiguous
range. Refer to Table 5 of the product
Datasheet for available addresses.
Example
from fc_lm75a_pct2075 import *
# Declare a sensor with default address
my_sensor1 = PCT2075()
# Declare a sensor with a different address
# where A0, A1, A2 are all connected to GND.
my_sensor1 = PCT2075(0x48)
This assumes that the file fc_lm75a_pct2075.py has been successfully copied to the micro:bit's filesystem as described above.
Methods and FunctionsThe driver provides methods to:
- Set the frequency of temperature conversions
- Read the temperature
- Set (and get) watchdog parameters
- Set the power mode
Setting Frequency of Temperature Conversions
The frequency at which the PCT2075 performs temperature conversions is user programmable in multiples of 100ms. This is intended as a power saving feature when high frequency temperature measurements are not required.
The CycleTime() method is used to set the conversion frequency.
Syntax:
CycleTime(Multiple = None)
Where:
Multiple : The frequency of temperature
conversions in multiples of 100ms.
For example if Multiple = 3 then
there will be a new temperature
reading available every 300ms.
If Multiple = None then
the method will return the frequency
multiple.
Example:
from fc_lm75a_pct2075 import *
# Declare a sensor with default address
sensor = PCT2075()
# Set temperature conversion for every 300ms
sensor.CycleTime(3)
# Get the frequency of temperature conversions
print('New temperatures available every',
sensor.CycleTime()*100, 'ms')
Output:
New temperatures available every 300 ms
Reading Temperature
Syntax:
Read(Res = 11)
CtoF(C, d = 1)
Purpose:
Read() is a method that returns the most
recent temperature reading in °C.
The default ADC resolution is 11-bits
but this can be configured to 9-bits
to emulate LM75A results.
CtoF() is a function that converts a
centigrade temperature to fahrenheit.
C : Centigrade temperature to convert
to Fahrenheit.
d : Result is rounded to this number of
decimals.
Example:
# Test the PCT2075 MicroPython
# driver for the micro:bit.
from fc_lm75a_pct2075 import *
from microbit import sleep
Sensor = PCT2075()
# Set conversion time frequency to 1000ms.
Sensor.CycleTime(10)
# Take 5 temperature readings, 1 minute apart.
# Convert from C to F, rounded to 2 decimals.
for _ in range(5):
sleep(60000)
C = Sensor.Read()
F = CtoF(C, 2)
print('Centigrade:', C, 'Fahrenheit:', F)
Sample Output:
Centigrade: 28.25 Fahrenheit: 82.85
Centigrade: 28.25 Fahrenheit: 82.85
Centigrade: 29.625 Fahrenheit: 85.32001
Centigrade: 32.875 Fahrenheit: 91.18
Centigrade: 32.125 Fahrenheit: 89.82
In the above example the readings started with a darkened room, then curtains were drawn and the sensor was exposed to direct sunlight. Hence the gradual rise in temperature over the five minutes.
Using the Watchdog
The product datasheet should be read in conjunction with this section. The following methods are provided to allow the user to get the full benefit of the watchdog:
- ResetDefaults() : Resets register to power-on defaults..
- OS() : Set (or get) the TOS temperature.
- Hyst() : Set (or get) the THYST temperature.
- SetConfig() : Set the CmpInt, Polarity and Queue parameters.
- GetConfig() : Returns the Configuration register's byte.
Syntax: ResetDefaults() Where: The Configuration, THYST and TOS registers are reset to power-on defaults.
Syntax: OS(Temp = None) Hyst(Temp = None) Where: Temp : The temperature in °C to set TOS and THYST. The default is None which returns the current value. Refer to the product datasheet for the meaning. of TOS and THYST.
Syntax: SetConfig(Queue = 1, Polarity = 0, CmpInt = 0) Where: Queue : Allowable values are 1, 2, 4, 6 Polarity : 0 = active low 1 = active high CmpInt : 0 = Comparator mode 1 = Interrupt mode Refer to the product datasheet for the meaning. of Queue, Polarity and CmpInt.
Syntax: GetConfig() Where: This method returns the Configuration register's value. Refer to the product datasheet for the meaning of each bit in the Configuration register's byte.
Example: # Tests the watchdog methods. from fc_lm75a_pct2075 import * sensor = PCT2075() # Test setting OS and HYST temperatures # Reset and get default values Sensor.ResetDefaults() print('Test setting OS and HYST temperatures') print('Default OS temperature:', Sensor.OS()) print('Default HYST temperature:', Sensor.Hyst()) # Set new OS temperature Sensor.OS(35) # Set new HYST temperature Sensor.Hyst(30) print('New OS temperature:', Sensor.OS()) print('New HYST temperature:', Sensor.Hyst()) # Test setting watchdog parameters. print('\nTest setting watchdog parameters') # Get Configuration register. CR = Sensor.GetConfig() fCR = "{:08b}".format(CR) print('Configuration register:', fCR) # Set the following: # : Queue faults = 6 # : Polarity = active high # : CmpInt = Interrupt mode print('Queue=6 faults, Active high, Interrupt mode') Sensor.SetConfig(Queue=6, Polarity=1, CmpInt=1) # Get Configuration register. CR = Sensor.GetConfig() fCR = "{:08b}".format(CR) print('Configuration register:', fCR)
Output: Test setting OS and HYST temperatures Default OS temperature: 80 Default HYST temperature: 75 New OS temperature: 35 New HYST temperature: 30 Test setting watchdog parameters Configuration register: 00000000 Queue=6 faults, Active high, Interrupt mode Configuration register: 00011110
Power Modes
The PCT2075 has a Shutdown mode which reduces power supply current significantly. While in this low power mode only the I2C interface is still operational. A stale value will be returned if the Temperature register is read.
Syntax: Off() Where: This method forces the PCT2075 into Shutdown mode.
Syntax: On() Where: This method brings the PCT2075 out of Shutdown mode. Temperature readings resume and the watchdog becomes active.
Example: # Demonstrate Shutdown mode on the PCT2075 # temperature sensor. from fc_lm75a_pct2075 import * from microbit import sleep Sensor = PCT2075() # Get temperature print('Temperature:', Sensor.Read()) # Put sensor into Shutdown mode print('Going into Shutdown mode...') Sensor.Off() # Get temperature print('Temperature:', Sensor.Read()) # Wait 2 minutes print('Wait 2 minutes...') sleep(120000) # Get temperature print('Temperature:', Sensor.Read()) # Wake sensor up. print('Waking up...') Sensor.On() # Get temperature print('Temperature:', Sensor.Read())
Typical Output: Temperature: 28.75 Going into Shutdown mode... Temperature: 28.75 Wait 2 minutes... Temperature: 28.75 Waking up... Temperature: 29.75
In the example above the temperature sensor was placed in Shutdown mode for two minutes. Warm air was lightly blown across the front of the sensor during this time. The increase in temperature (1.0 °C) was not detected till the sensor was woken up.
The temperature reading returned while the sensor was in its low power state was stale and came from the sensor's last conversion before being powered down.
Enjoy!
PCT2075 Driver Code for micro:bit
Download as zip file
'''
LM75A temperature sensor
PCT2075 temperature sensor
MicroPython driver for micro:bit
EXAMPLE USAGE:
LM75A sensor object with default I2C address
lm75a = LM75A()
PCT2075 sensor object with default I2C address
pct2075 = PCT2075()
AUTHOR: fredscave.com
DATE : 2025/04
VERSION : 2.00
'''
from microbit import i2c, sleep
from micropython import const
ADDR_LM75A = const(0x48) # A0, A1, A2 pins all to GND
ADDR_PCT2075 = const(0x37) # A0, A1, A2 pins floating
REG_TEMP = const(0x00)
REG_CONFIG = const(0x01)
REG_HYST = const(0x02)
REG_OS = const(0x03)
REG_TIDLE = const(0x04)
# Power-on default values
DEFAULT_CONFIG = const(0x00)
DEFAULT_THYST_MSB = const(0x4B)
DEFAULT_THYST_LSB = const(0x00)
DEFAULT_OS_MSB = const(0x50)
DEFAULT_OS_LSB = const(0x00)
DEFAULT_TIDLE = const(0x01) # PCT2075 only
# Convert Centigrade to Fahrenheit
CtoF = lambda C, d=1: round((C * 9/5) +32, d)
class LM75A():
def __init__(self, Addr = ADDR_LM75A):
self.Addr = Addr
#--------------------------------------------
# Public Methods
#--------------------------------------------
# Get temperature reading in Centigrade.
# Resolution is 9-bits or 11-bits
def Read(self, Res = 9):
res = Res if (Res in [9, 11]) else 9
i2c.write(self.Addr, bytes([REG_TEMP]))
buf = i2c.read(self.Addr, 2)
return LM75A._Convert(buf, res)
# Resets configuration defaults to power-on values.
def ResetDefaults(self):
i2c.write(self.Addr, bytes([REG_CONFIG,
DEFAULT_CONFIG]))
i2c.write(self.Addr, bytes([REG_HYST,
DEFAULT_THYST_MSB,
DEFAULT_THYST_LSB]))
i2c.write(self.Addr, bytes([REG_OS,
DEFAULT_OS_MSB,
DEFAULT_OS_LSB]))
# Returns the Configuration register value
def GetConfig(self):
i2c.write(self.Addr, bytes([REG_CONFIG]))
return i2c.read(self.Addr, 1)[0]
# Sets the three user settable parameters in
# the Configuration register.
# Read the Datasheet for more details.
def SetConfig(self, Queue = 1, Polarity = 0, CmpInt = 0):
cmpint = CmpInt if (CmpInt in (0, 1)) else 0
polarity = Polarity if (Polarity in (0, 1)) else 0
t = (1, 2, 4, 6)
if Queue in t:
queue = t.index(Queue)
else:
queue = 0
config = self.GetConfig()
config = LM75A._ChangeBit(config, cmpint, 1)
config = LM75A._ChangeBit(config, polarity, 2)
config = LM75A._ChangeBit(config, queue & 0b01, 3)
config = LM75A._ChangeBit(config, queue >> 1, 4)
i2c.write(self.Addr, bytes([REG_CONFIG, config]))
# Place the sensor in shutdown mode.
def Off(self):
i2c.write(self.Addr, bytes([REG_CONFIG]))
config = i2c.read(self.Addr, 1)[0]
config = config | 0x01
i2c.write(self.Addr, bytes([REG_CONFIG, config]))
# Wake the sensor if it is in shutdown mode.
def On(self):
i2c.write(self.Addr, bytes([REG_CONFIG]))
config = i2c.read(self.Addr, 1)[0]
config = config & 0b11111110
i2c.write(self.Addr, bytes([REG_CONFIG, config]))
sleep(300)
# Set or get the Hysteresis Centigrade temperature.
# This is used by the Watchdog. See the Datasheet
# for more details.
def Hyst(self, Temp = None):
if Temp == None:
i2c.write(self.Addr, bytes([REG_HYST]))
binary = i2c.read(self.Addr, 2)[0]
return LM75A._fromComp2(binary, 8)
else:
if isinstance(Temp, int):
temp2comp = LM75A._toComp2(Temp, 8)
buf = bytes([REG_HYST, temp2comp, 0])
i2c.write(self.Addr, buf)
# Set or get the Over-temperature shutdown
# temperature (Centigrade).
# This is used by the Watchdog. See the Datasheet
# for more details.
def OS(self, Temp = None):
if Temp == None:
i2c.write(self.Addr, bytes([REG_OS]))
binary = i2c.read(self.Addr, 2)[0]
return LM75A._fromComp2(binary, 8)
else:
if isinstance(Temp, int):
temp2comp = LM75A._toComp2(Temp, 8)
buf = bytes([REG_OS, temp2comp, 0])
i2c.write(self.Addr, buf)
#--------------------------------------------
# Private Methods
#--------------------------------------------
# Returns binary temperature reading as decimal.
@staticmethod
def _Convert(buf, res):
b = LM75A._fromComp2(buf[0], 8)
dec = buf[1] >> (16 - res)
return b + dec/(2**(res-8))
# Converts Twos Complementary binary
# to decimal equivalent.
@staticmethod
def _fromComp2(binary, bits):
mask = 1 << (bits-1)
if not (binary & mask) >> (bits-1):
return binary
else:
return -((binary ^ 2**bits - 1) + 1)
# Converts signed integer to Twos Complementary.
@staticmethod
def _toComp2(sint, bits):
if sint >= 0:
return sint
else:
return (abs(sint) ^ 2**bits - 1) + 1
# Changes the value of a bit in a given position
# of a byte.
@staticmethod
def _ChangeBit(byte, bit, pos):
if bit == 1:
return byte | (1 << pos)
else:
return byte & ~(1 << pos)
#-----------------------------------------
# Derived class for PCT2075
#
# The PCT2075 sensor is drop in replacement
# for the older LM75A sensor.
#
# The PCT2075 has a few additional features
# that this derived class provides.
#------------------------------------------
class PCT2075(LM75A):
def __init__(self, Addr = ADDR_PCT2075):
self.Addr = Addr
def Read(self, Res = 11):
res = Res if (Res in [9, 11]) else 11
return super().Read(res)
# Resets configuration defaults to power-on values.
def ResetDefaults(self):
i2c.write(self.Addr, bytes([REG_TIDLE,
DEFAULT_TIDLE]))
super().ResetDefaults()
# The temperature conversion cycle time can be
# user set in multiples of 100 ms.
def CycleTime(self, Multiples = None):
if Multiples == None:
i2c.write(self.Addr, bytes([REG_TIDLE]))
buf = i2c.read(self.Addr, 1)
return buf[0]
else:
multiples = Multiples if (Multiples in range(0, 32)) else 1
i2c.write(self.Addr, bytes([REG_TIDLE, multiples]))
Combining LM75A & PCT2075
Since the base class of this module is a driver for the LM75A it is possible to use this module to control both an LM75A and PCT2075 at the same time on the same I2C bus. This example shows how simple it is to do this.
Requirements- micro:bit
- LM75A breakout board
- PCT2075 breakout board
- Breadboard, jumper wires
- Driver: fc_lm75a_pct2075.py
- LM75A and PCT2075 GND pins ⇒ micro:bit GND pin
- LM75A and PCT2075 VCC pins ⇒ micro:bit 3.3V
- LM75A and PCT2075 SCL pins ⇒ micro:bit Pin 19
- LM75A and PCT2075 SDA pins ⇒ micro:bit Pin 20
Ensure that the driver file fc_lm75a_pct2075.py has been copied t0 the micro:bit's file system.
The code:
# Test the PCT2075 driver by reading
# temperatures simultaneously from
# an LM75A sensor and a PCT2075 sensor.
from fc_lm75a_pct2075 import *
from microbit import sleep
lm75a = LM75A()
pct2075 = PCT2075()
# Print headings
print('LM75A PCT2075')
# Take 5 readings at two minute
# intervals from each sensor.
for x in range(5):
print(lm75a.Read(), ' ', pct2075.Read())
if x != 4:
sleep(120000)
Output:
LM75A PCT2075
27.0 29.0
27.5 29.125
27.5 29.0
27.0 28.875
27.0 28.75

Interestingly the PCT2075 consistently read about 2°C higher than the LM75A.