Using CircuitPython with XIAO nRF52840 for Temperature and Humidity Monitoring


In this tutorial, we will be using a very small but powerful development board called XIAO. We will use XIAO nRF52850 development board to monitor environmental conditions. This can be useful in agriculture applications where climate monitoring is important.

This project aims to use a temperature and humidity sensor with the XIAO board. Data collected from the sensor will be compared to the threshold temperature and humidity. If the recorded temperature and/or humidity reaches the set threshold, the system will alarm the user by lighting up LEDs and beeping the buzzer. Simultaneously, an LCD screen will display the real-time temperature and humidity.


Hardware Used:

  • Xiao Seeed nrf52840


  • DHT11
  • 16x2 LCD module
  • LED
  • Buzzer
  • 220-ohm resistor
  • Breadboard
  • Jumper wire (male-male, male-female, female-female)
  • USB C connector
  • Software Used:


    Programming Language:


    Application Discussion:


    Seeed Studio XIAO nRF52840 is equipped with a powerful Nordic nRF52840 MCU which integrates Bluetooth 5.0 connectivity. Meanwhile, it has a small and exquisite form-factor which can be used for wearable devices and Internet of Things projects. The single-sided surface-mountable design and the onboard Bluetooth antenna can greatly facilitate the rapid deployment of IoT projects.

    DHT11 is a basic, ultra low-cost digital temperature and humidity sensor. It uses a capacitive humidity sensor and a thermistor to measure the surrounding air and spits out a digital signal on the data pin (no analog input pins needed). It's fairly simple to use but requires careful timing to grab data.

    The buzzer uses the piezoelectric effect of the piezoelectric ceramics and uses the pulse current to drive the vibration of the metal plate to generate sound. Piezoelectric buzzer is mainly composed of multi-resonator, piezoelectric plate, impedance matcher, resonance box, housing, etc. Some of the piezoelectric buzzers are also equipped with light-emitting diodes.

    An LCD (Liquid Crystal Display) screen is an electronic display module and has a wide range of applications. It can display 16 characters per line and there are 2 such lines. In this LCD each character is displayed in 5x7 pixel matrix. The 16 x 2 intelligent alphanumeric dot matrix display is capable of displaying 224 different characters and symbols. This LCD has two registers, namely, Command and Data.

    Hardware Setup:


    For reference, this is the hardware pinouts of the Seeed XIAO nRF52840:

    The LCD and the DHT11 sensors needs to be connected to the power source of the XIAO board. Connect both on the power rail of the breadboard. Likewise, connect the sensor, LEDs, buzzer, and LCD to the ground via the ground rail of the breadboard and connect it to the ground pin of the XIAO board.

    Connect the following pins to the respective XIAO board pins

    • Red LED to XIAO Pin D8
    • Green LED to XIAO Pin D7
    • Buzzer Pin to XIAO Pin D6
    • DHT11 output Pin to XIAO Pin D10
    • LCD SDA Pin to XIAO Pin D4
    • LCD SCL Pin to XIAO Pin D5


    Software Setup: 

    Setting Up the Seeed XIAO nRF52840 and CircuitPython

    You may follow the set-up and installation shown below:


     MU Editor Set-up

    First, download the MU editor in their official websites. After downloading the editor, open the editor and click "Mode" as shown below

    Then, choose CircuitPython as the mode as shown below. You may now enter your program code.


    Program Code: 

    #Temperature and Humidity Alarm with CircuitPython with Xiao Seeed nrf52840
    #the objective of this project is to create a weather/environment alarm that will use a DHT sensor to collect environmental temperature and humidity
    #if the sensor detected an alarming temperature and humidity values, the system will alarm the user by lighting up LED and beeping a buzzer
    #Several libraries were used in this project. See blog post to download them.
    #if the does not run, eject the hardware and replug to your computer
    #import necessary libraries
    import board
    import busio
    import time
    import digitalio
    import adafruit_dht
    #import LCD libraries
    from lcd.lcd import LCD
    from lcd.i2c_pcf8574_interface import I2CPCF8574Interface
    from lcd.lcd import CursorMode
    # Talk to the LCD at I2C address 0x27.
    # The number of rows and columns defaults to 4x20, so those
    # arguments could be omitted in this case.
    lcd = LCD(I2CPCF8574Interface(board.I2C(), 0x27), num_rows=4, num_cols=20)
    #initialize the led
    led1 = digitalio.DigitalInOut(board.D8)
    led1.direction = digitalio.Direction.OUTPUT
    led2 = digitalio.DigitalInOut(board.D7)
    led2.direction = digitalio.Direction.OUTPUT
    #initialize the buzzer
    buzzer = digitalio.DigitalInOut(board.D6)
    buzzer.direction = digitalio.Direction.OUTPUT
    # Initial the dht device, with data pin connected to:
    dhtDevice = adafruit_dht.DHT11(board.D10)
    #set the threshold values for both temperature and humidity
    tempLimit = 28.0
    humLimit = 60.0
    #The while True here is needed to keep the program inside the whole loop running over time
    while True:
            # Print the values to the serial port
            #keep getting the temperature and humidity from the sensor, this is getting real-time data
            temperature_c = dhtDevice.temperature
            #You may convert the temperature in Celsiul to Farenheit
            temperature_f = temperature_c * (9 / 5) + 32
            humidity = dhtDevice.humidity
                "Temp: {:.1f} F / {:.1f} C    Humidity: {}% ".format(
                    temperature_f, temperature_c, humidity
            #clear the contents of the LCD display every loop
            #print the temperature and humidity to the LCD
            #the LCD lib has a set_cursor_pos function that allows u to print characters in a specific position in the LCD matrix
            #However, it seems like it doesn't work on this case. Both values must be printed in a single print call like shown below.
            #variables or non-string parameters must be converted to stings to successfully display them to the LCD
            lcd.print("Temperature:" + str(temperature_c) + "C\nHumidity:" +str(humidity) + "%")
            if temperature_c > tempLimit and humidity > humLimit: #if both the temp and humidity reach the threshold, lit up both led and beep the buzzer
                led1.value = True
                led2.value = True
                buzzer.value = True
            elif temperature_c > tempLimit and humidity < humLimit: #if the temperature reach the threshold but the humidity did not, lit up the first led and beep the buzzer
                led1.value = True
                led2.value = False
                buzzer.value = True
            elif temperature_c < tempLimit and humidity > humLimit: #if the humidity reach the threshold but the temperature did not, lit up the second led and beep the buzzer
                led1.value = False
                led2.value = True
                buzzer.value = True
            else: #if neither sensors reach the threshold values, turn off the led and the buzzer
                led1.value = False
                led2.value = False
                buzzer.value = False
        except RuntimeError as error:
            # Errors happen fairly often, DHT's are hard to read, just keep going
        except Exception as error:
            raise error
        #Give the system time to process data in real-time to avoid buffering of the LCD displays

    Code Breakdown:

    It is necessary to have a basic to intermediate knowledge of the Python language and its syntax to understand the program code of this project. Specifically, a knowledge at calling libraries, conditional statements, looping, methods and functions, and prompting errors. The following are detailed breakdown of the code above:

    Code block before while True

    • In this block, the program must import the necessary libraries, both built-in and libraries from external sources, such as board and dht11 libraries.
    • This is also where the program initialize the LEDs and the buzzer and designated them as output hardware. The dhtDevice is initialize as input of the program.
    • In this block, the temperature and humidity threshold are set. 

    While True: block

    • The while True: is used in this block to keep the content inside the loop running forever unless the XIAO board is ejected from the computer.
    • This contains the try, except block where the program keeps on retrieving real-time temperature and humidity data from the dht11 sensor.
    • The time.sleep() line is necessary to give XIAO ample time to process the program.

    Try block

    • In this block, temperature_c and humidity are assigned to contain the real-time temperature and humidity data from the dht11 sensor. The program also converts the temperature in Celsius to Fahrenheit, and print the data to the Serial. 
    • The lcd.print() line displays the real-time temperature, in Celsius, and humidity to the LCD screen.
    • The code block also contains the if-elif-else statements, which decides which output must be activated and deactivated.

    Except block

    • In this block, the program prompt an error if dht11 is not detected or no data is received from the said sensor.


    Output and Testing:

    Testing the project by varying temperature and humidity thresholds:

    Testing the project using real-time temperature and humidity data:  


    Common Problems and Possible Solutions:

    1. DHT11 cannot receive data. If you encounter this, make sure that your sensor is functional. Before starting a project, test each component using the MU editor’s Serial port. 
    2. does not run when saving the updated code. If the code does not automatically run, eject and replug the XIAO board. Your code is now expected to run automatically. If there is still a problem, give the disk ample time to process the code.
    3. LCD module library does not work. Not all libraries related to the module you used can use the libraries available online. Make sure you use updated libraries and test them on the MU editor’s Serial before using them in your project.
    4. The code does not work. Make sure that your code is free from errors. Python is indent-sensitive, so make sure to check your indentations. You can view possible errors on the Serial of the MU editor. Also, check your wiring and pinouts if they are correct.



    This tutorial has successfully demonstrated how to create an environment monitoring system using the XIAO nRF52840 development board, and temperature and humidity sensor, with alarm feature for the user when the system reaches the set thresholds. This monitoring system could be advanced further by testing it up on an agricultural field or a garden to gather temperature and humidity data.

    A suggested next step to this project is to use XIAO's Bluetooth Low Energy (BLE) to transmit sensor data to mobile phone and visualize it via mobile app. A GSM module could also be integrated to add SMS or call capabilities. 

    In terms of the difficulty of using the XIAO nRF52840, it depends on how knowledgeable the user is in Python programming language. It is relatively easy to create projects using CircuitPython when you master the syntax of the said language and are familiar with the libraries you will be using.



    CircuitpythonDht11HumidityI2c lcdTemperatureXiaoXiao seeedXiao seeed nrf52840

    Leave a comment

    All comments are moderated before being published