Skip to content

Commit 04987f3

Browse files
Silicon Labs CircuitPython Applications v1.1.0
1 parent cf3cedf commit 04987f3

21 files changed

+696
-5
lines changed

README.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
# Silicon Labs CircuitPython Applications #
1515

16-
[![Version Badge](https://img.shields.io/badge/-v1.0.1-green)](https://github.com/SiliconLabs/circuitpython_applications/releases)
16+
[![Version Badge](https://img.shields.io/badge/-v1.1.0-green)](https://github.com/SiliconLabs/circuitpython_applications/releases)
1717
[![CircuitPython](https://img.shields.io/badge/CircuitPython-v8.2.0+-green)](https://circuitpython.org/downloads?q=silabs)
1818
![License badge](https://img.shields.io/badge/License-Zlib-green)
1919

@@ -26,10 +26,11 @@ All examples in this repository are considered to be EXPERIMENTAL QUALITY, which
2626
|:--:|:-------------|:---------------:|
2727
| 1 | CircuitPython - Bluetooth - Distance Monitor (VL53L1X) | [Click Here](./cp_bluetooth_distance_monitor)|
2828
| 2 | CircuitPython - Bluetooth - Environmental Sensing (CCS811/BME280) | [Click Here](./cp_bluetooth_environmental_sensing) |
29-
| 3 | CircuitPython - Non-Wireless Display Demo (IS31FL3741) | [Click Here](./cp_non_wireless_display_demo) |
30-
| 4 | CircuitPython - RGB Display Drawing (ILI9341) | [Click Here](./cp_rgb_display_drawing_ili9341) |
31-
| 5 | CircuitPython - Temperature and Humidity Monitor with LED Matrix Display (SI2071/IS31FL3741) | [Click Here](./cp_temperature_and_humidty_monitor) |
32-
| 6 | CircuitPython - xG24 Dev Kit Sensors (ILI9341) | [Click Here](./cp_xg24_dev_kit_sensors) |
29+
| 3 | CircuitPython - Bluetooth - Neopixel Humidity Gauge (SHTC3) | [Click Here](./cp_bluetooth_neopixel_humidity_gauge) |
30+
| 4 | CircuitPython - Non-Wireless Display Demo (IS31FL3741) | [Click Here](./cp_non_wireless_display_demo) |
31+
| 5 | CircuitPython - RGB Display Drawing (ILI9341) | [Click Here](./cp_rgb_display_drawing_ili9341) |
32+
| 6 | CircuitPython - Temperature and Humidity Monitor with LED Matrix Display (SI2071/IS31FL3741) | [Click Here](./cp_temperature_and_humidty_monitor) |
33+
| 7 | CircuitPython - xG24 Dev Kit Sensors (ILI9341) | [Click Here](./cp_xg24_dev_kit_sensors) |
3334

3435

3536
## Get CircuitPython firmware ##
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# CircuitPython - Bluetooth - Neopixel humidity gauge (SHTC3) #
2+
3+
## Overview ##
4+
5+
This project aims to implement a wireless humidity gauge sensing system using Sparkfun Thing Plus for Matter - MGM240 development kits and external sensors integrated with the BLE wireless stack and CircuitPython.
6+
The block diagram of this application is shown in the image below:
7+
8+
![overview](docs/overview.PNG)
9+
10+
### Sensor Device ###
11+
12+
The sensor device is a Sparkfun Thing Plus Matter - MGM240P kit connected to a SparkFun Humidity Sensor Breakout - SHTC3 (Qwiic) board. This device periodically provides the humidity level.
13+
14+
The sensor device implements a GATT Server and provides the measured values via BLE Characteristics. The client device can connect to the sensor and gather the provided environmental data by reading the BLE Characteristics.
15+
16+
### Client Device ###
17+
18+
The client device is a Sparkfun Thing Plus Matter - MGM240P kit connected to a NeoPixel Ring - 12 x 5050 RGB LED with Integrated Drivers display. The client device connects to the sensor device via BLE and reads the provided environmental data via BLE characteristics.
19+
20+
The gathered humidity data is displayed on the connected NeoPixel Ring.
21+
22+
## Hardware Required ##
23+
24+
### Silabs Development Kits ###
25+
26+
- [SparkFun Thing Plus Matter - MGM240P](https://www.sparkfun.com/products/20270)
27+
28+
### External Hardware ###
29+
30+
- [SparkFun Humidity Sensor Breakout - SHTC3 (Qwiic)](https://www.sparkfun.com/products/16467)
31+
- [NeoPixel Ring - 12 x 5050 RGB LED with Integrated Drivers](https://www.adafruit.com/product/1643)
32+
33+
### Prerequisites ###
34+
35+
- Getting started with [CircuitPython on EFR32 boards](../doc/running_circuitpython.md).
36+
37+
## Setup ##
38+
39+
To run the example you need to install **Thonny** editor and then follow the steps below:
40+
41+
1. Flash the corresponding CircuitPython binary for your board. You can visit [circuitpython.org/downloads](https://circuitpython.org/downloads?q=silabs) to download the binary.
42+
43+
>**_NOTE:_** The examples in this repository require CircuitPython v8.2.0 or higher.
44+
45+
2. Install the necessary libraries from Adafruit CircuitPython bundle. You can download the bundle from [here](https://circuitpython.org/libraries). The libraries that used in this project and their version are list in this table below.
46+
- Sensor device
47+
48+
| Library | Version |
49+
|:----------------- |:------------------|
50+
| adafruit_shtc3 | 1.9.15 |
51+
52+
- Client device
53+
54+
| Library | Version |
55+
|:----------------- |:------------------|
56+
| neopixel_spi | 1.6.1 |
57+
58+
3. Upload all the libraries and files of the lib folder to the CircuitPython device. The files in binary folder should not be uploaded to lib folder in the device, they should have the same hierarchy as the **code.py** file.
59+
60+
4. Copy the content of the **code.py** and paste it to the **code.py** file on the CircuitPython device.
61+
62+
- Sensor device: [code.py](sensor/src/code.py)
63+
64+
- Client device: [code.py](client/src/code.py)
65+
66+
5. Run the scripts on the board.
67+
68+
## How it Works ##
69+
70+
### Sensor ###
71+
72+
- **Initialization process**
73+
![sensor_init](docs/sensor_inits.PNG)
74+
75+
- **Runtime**
76+
The sensor device periodically measures the environmental data with a time period of 10 seconds.
77+
![sensor_runtime](docs/runtime.PNG)
78+
79+
- **BLE**
80+
81+
***Read Characteristics***
82+
![ble_char](docs/ble_char.PNG)
83+
84+
- **GATT Database:**
85+
- Device name: "CP_HUM_SENSOR"
86+
- [Service] Humidity Sensing
87+
- [Char] Humidity
88+
[R, N] Get humidity value (e.g.: 25.5 % => 255)
89+
90+
### Client ###
91+
92+
- **Initialization process**
93+
![client_init](docs/client_inits.PNG)
94+
95+
- **Runtime operation**
96+
![client_runtime](docs/client_runtime.PNG)
97+
98+
### Output Display ###
99+
100+
Measured values should be displayed on the connected Neopixel Ring display.
101+
After startup, if client app is scanning sensor app via BLE, Neopixel will blink. After the connection is established, the client app will receive the humidity data and display it via Neopixel. The Neopixel ring has 12 RGB LEDs. The measured humidity value is in the 0-100% range and 8% => 1 LED.
102+
103+
The NeoPixel ring is made up of 12 individual RGB LEDs, which means that each LED can display any color in the RGB color space. In this example, the colors displayed are based on the humidity level measured by the SHTC3 sensor.
104+
105+
The SHTC3 sensor measures relative humidity as a percentage. In this example, the range of humidity values is divided into 12 equal parts, with each part corresponding to one LED on the NeoPixel ring. When the humidity is at 0%, only the first LED lights up with a blue color, which indicates a low humidity level. As the humidity level increases, more LEDs light up on the ring, and the colors become warmer.
106+
107+
For example, if the humidity level is at 10%, then the first two LEDs light up with a warmer color than blue. At 20% humidity, the first three LEDs light up with a warmer color, and so on. At 100% humidity, all 12 LEDs light up with the warmest color, indicating that the humidity level is very high.
108+
109+
Run the **code.py** file on both sensor and client device and monitor the NeoPixel you will see the result like below.
110+
111+
**Sensor Shell**
112+
![sensor_result](docs/sensor_result.PNG)
113+
114+
**Client Shell**
115+
![client_result](docs/client_result.PNG)
116+
117+
**Hardware**
118+
![hw_result](docs/result.JPG)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"""
2+
*****************************************************************************
3+
Copyright 2023 Silicon Laboratories Inc. www.silabs.com
4+
*****************************************************************************
5+
SPDX-License-Identifier: Zlib
6+
7+
The licensor of this software is Silicon Laboratories Inc.
8+
9+
This software is provided \'as-is\', without any express or implied
10+
warranty. In no event will the authors be held liable for any damages
11+
arising from the use of this software.
12+
13+
Permission is granted to anyone to use this software for any purpose,
14+
including commercial applications, and to alter it and redistribute it
15+
freely, subject to the following restrictions:
16+
17+
1. The origin of this software must not be misrepresented; you must not
18+
claim that you wrote the original software. If you use this software
19+
in a product, an acknowledgment in the product documentation would be
20+
appreciated but is not required.
21+
2. Altered source versions must be plainly marked as such, and must not be
22+
misrepresented as being the original software.
23+
3. This notice may not be removed or altered from any source distribution.
24+
25+
*****************************************************************************
26+
# EXPERIMENTAL QUALITY
27+
This code has not been formally tested and is provided as-is. It is not
28+
suitable for production environments. In addition, this code will not be
29+
maintained and there may be no bug maintenance planned for these resources.
30+
Silicon Labs may update projects from time to time.
31+
******************************************************************************
32+
"""
33+
import board
34+
from time import monotonic
35+
from adafruit_ble import BLERadio
36+
from SleepTimer import SleepTimer
37+
from NeoPixelDisplay import NeoPixel_Display
38+
from EnvSensingService import EnvironmentalSensingService
39+
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
40+
41+
42+
class ClientApp():
43+
def __init__(self) -> None:
44+
45+
self.service = None
46+
self.connection = None
47+
self.ble = BLERadio()
48+
self.current_tick = 0
49+
self.appNeoPixel = NeoPixel_Display()
50+
self.ble_read_humidity = 0.0
51+
self.neopixel_trigger_blink = True
52+
SleepTimer.setup_timer(self.neopixel_control, 0.5)
53+
54+
def neopixel_control(self, *args, **kwargs):
55+
if not self.ble.connected:
56+
if self.neopixel_trigger_blink:
57+
self.neopixel_trigger_blink = False
58+
self.appNeoPixel.fill_full_color()
59+
else:
60+
self.neopixel_trigger_blink = True
61+
self.appNeoPixel.clear()
62+
else:
63+
self.appNeoPixel.humidity_display(self.ble_read_humidity)
64+
65+
66+
def main_function(self):
67+
68+
SleepTimer.main_function()
69+
tick = monotonic()
70+
71+
if (tick - self.current_tick) >= 1:
72+
73+
self.current_tick = tick
74+
if not self.ble.connected:
75+
print('>>> Scanning sensor device...\r')
76+
77+
for adv in self.ble.start_scan(ProvideServicesAdvertisement):
78+
if EnvironmentalSensingService in adv.services:
79+
print('>>> Found sensor device !!!\r')
80+
print('>>> Stop scanning sensor device\r')
81+
self.ble.stop_scan()
82+
self.connection = self.ble.connect(adv)
83+
break
84+
85+
if self.ble.connected:
86+
self.service = self.connection[EnvironmentalSensingService]
87+
self.ble_read_humidity = self.service.humidity / 100.0
88+
print(f"BLE read humidity = {self.ble_read_humidity}")
89+
90+
91+
92+
93+
94+
95+
96+
97+
98+
99+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""
2+
*****************************************************************************
3+
Copyright 2023 Silicon Laboratories Inc. www.silabs.com
4+
*****************************************************************************
5+
SPDX-License-Identifier: Zlib
6+
7+
The licensor of this software is Silicon Laboratories Inc.
8+
9+
This software is provided \'as-is\', without any express or implied
10+
warranty. In no event will the authors be held liable for any damages
11+
arising from the use of this software.
12+
13+
Permission is granted to anyone to use this software for any purpose,
14+
including commercial applications, and to alter it and redistribute it
15+
freely, subject to the following restrictions:
16+
17+
1. The origin of this software must not be misrepresented; you must not
18+
claim that you wrote the original software. If you use this software
19+
in a product, an acknowledgment in the product documentation would be
20+
appreciated but is not required.
21+
2. Altered source versions must be plainly marked as such, and must not be
22+
misrepresented as being the original software.
23+
3. This notice may not be removed or altered from any source distribution.
24+
25+
*****************************************************************************
26+
# EXPERIMENTAL QUALITY
27+
This code has not been formally tested and is provided as-is. It is not
28+
suitable for production environments. In addition, this code will not be
29+
maintained and there may be no bug maintenance planned for these resources.
30+
Silicon Labs may update projects from time to time.
31+
******************************************************************************
32+
"""
33+
from adafruit_ble.characteristics import Characteristic
34+
from adafruit_ble.attributes import Attribute
35+
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
36+
from adafruit_ble.services import Service
37+
from adafruit_ble.uuid import StandardUUID, VendorUUID
38+
from adafruit_ble.characteristics.int import Int16Characteristic
39+
from adafruit_ble.characteristics.string import StringCharacteristic
40+
41+
42+
class EnvironmentalSensingService(Service):
43+
uuid = StandardUUID(0x181A)
44+
45+
humidity = Int16Characteristic(
46+
uuid = StandardUUID(0x2A6F),
47+
properties = (Characteristic.READ | Characteristic.NOTIFY),
48+
write_perm = Attribute.NO_ACCESS,
49+
)
50+
51+
52+
def __init__(self, service=None):
53+
super().__init__(service=service)
54+
self.connectable = True
55+
56+
57+
58+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
"""
2+
*****************************************************************************
3+
Copyright 2023 Silicon Laboratories Inc. www.silabs.com
4+
*****************************************************************************
5+
SPDX-License-Identifier: Zlib
6+
7+
The licensor of this software is Silicon Laboratories Inc.
8+
9+
This software is provided \'as-is\', without any express or implied
10+
warranty. In no event will the authors be held liable for any damages
11+
arising from the use of this software.
12+
13+
Permission is granted to anyone to use this software for any purpose,
14+
including commercial applications, and to alter it and redistribute it
15+
freely, subject to the following restrictions:
16+
17+
1. The origin of this software must not be misrepresented; you must not
18+
claim that you wrote the original software. If you use this software
19+
in a product, an acknowledgment in the product documentation would be
20+
appreciated but is not required.
21+
2. Altered source versions must be plainly marked as such, and must not be
22+
misrepresented as being the original software.
23+
3. This notice may not be removed or altered from any source distribution.
24+
25+
*****************************************************************************
26+
# EXPERIMENTAL QUALITY
27+
This code has not been formally tested and is provided as-is. It is not
28+
suitable for production environments. In addition, this code will not be
29+
maintained and there may be no bug maintenance planned for these resources.
30+
Silicon Labs may update projects from time to time.
31+
******************************************************************************
32+
"""
33+
import board
34+
import busio
35+
import neopixel_spi as neopixel
36+
37+
38+
# Update this to match the number of LEDs.
39+
NUMPIXELS_DEFAULT = 12
40+
41+
# A number between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
42+
BRIGHTNESS_DEFAULT = 0.1
43+
44+
# This is the data out pin NeoPixel connect to host
45+
DATA_PIN = board.PD0
46+
47+
# Set the pixel color channel order
48+
ORDER = neopixel.GRB
49+
50+
COLORS_PALETTE = (0x00eaff, 0x00e5e4, 0x00dfc2, 0x00d79c, 0x40cd72, 0x67c145,
51+
0x85b400, 0xa1a300, 0xbc8f00, 0xd67600, 0xed5300, 0xff0000 )
52+
53+
class NeoPixel_Display():
54+
55+
def __init__(self) -> None:
56+
57+
_spi = busio.SPI(clock = board.SCK, MOSI = DATA_PIN, MISO = board.MISO)
58+
59+
self.pixels = neopixel.NeoPixel_SPI(
60+
spi = _spi,
61+
n = NUMPIXELS_DEFAULT,
62+
brightness = BRIGHTNESS_DEFAULT,
63+
auto_write = False,
64+
pixel_order = ORDER
65+
)
66+
67+
def fill_full_color(self):
68+
for i in range (0, len(COLORS_PALETTE)):
69+
self.pixels[i] = COLORS_PALETTE[i]
70+
71+
self.pixels.show()
72+
73+
def clear(self):
74+
self.pixels.fill(0)
75+
self.pixels.show()
76+
77+
def humidity_display(self, humidity):
78+
79+
index_display = humidity / 8;
80+
if humidity % 8 != 0:
81+
index_display += 1
82+
83+
if index_display > (len(COLORS_PALETTE) - 1):
84+
index_display = len(COLORS_PALETTE) - 1
85+
86+
self.pixels.fill(0)
87+
for i in range(0, int(index_display)):
88+
self.pixels[i] = COLORS_PALETTE[i]
89+
90+
self.pixels.show()
91+
92+

0 commit comments

Comments
 (0)