Building a Multi-Functional LED Matrix Display with Sensors, GPS, and OLED Screen
Introduction
In this project, we’re going to take a deep dive into a Python-based solution running on a microcontroller (like Raspberry Pi Pico), designed to display messages and real-time sensor data using an LED matrix, an OLED screen, and a temperature sensor. Additionally, we integrate a GPS module to display location and time data, which makes this project a versatile tool for various applications, including fitness tracking, information kiosks, or even for fun visual displays.
This article walks through the code and explains how it can be used to create an interactive display system.
Hardware Components
Here’s a quick overview of the hardware used in this project:
- NeoPixel LED Matrix: Displays scrolling messages and real-time data.
- AHT10/AHT20 Temperature Sensor: Measures temperature and humidity.
- GPS Module: Captures location and time data.
- SSD1306 OLED Display: Provides a secondary screen for displaying text-based information.
- Button (GP2 Pin): A physical button used to interact with the system.
- SD Card: Used to load waypoint data for location-based applications.
Pin Assignments
Hardware | Pin Assignments |
---|---|
OLED (SSD1306) | SCL → GP15, SDA → GP14 |
Button | Input Pin → GP2 |
GPS Module | TX → GP5, RX → GP4 |
SD Card Reader | SCK → GP6, MOSI → GP7, MISO → GP8, CS → GP9 |
AHT10/20 Sensor | SCL → GP15, SDA → GP14 |
NeoPixel LED Matrix | Data Pin → GP19 |
Key Components of the Code
LED Matrix Control (Output
class)
The Output
class is responsible for handling the display of information on the NeoPixel LED matrix. It includes methods to:
- Fill the Matrix: The
fill()
method colors all the LEDs. - Show Matrix Updates: The
show()
method renders changes on the LED matrix. - Scroll Text: The
scroll_text()
method scrolls a message across the matrix. - Blink Text: The
blink_text()
method displays text in a blinking pattern.
The LED matrix display is ideal for continuously updating data like heart rate, GPS-based distance tracking, and more.
def scroll_text(self, message, duration_ms=7000):
with bitmapfont.BitmapFont(self.display_width, self.display_height, self.write_pixel) as bf:
pos = self.display_width
message_width = bf.width(message)
start = last = utime.ticks_ms()
speed_ms = self.speed / 1000.0
while True:
current = utime.ticks_ms()
delta_ms = utime.ticks_diff(current, last)
elapsed_time = utime.ticks_diff(current, start)
if elapsed_time >= duration_ms:
break
pos -= speed_ms * delta_ms
if pos < -message_width:
pos = self.display_width
self.fill((0, 0, 0)) # Clear display
bf.text(message, int(pos), 0) # Display text
self.show()
utime.sleep_ms(20)
This part of the code is responsible for continuously scrolling the given message. It's a great visual effect for dynamic information like real-time temperature readings or sports statistics.
GPS Data Handling
The system interacts with a GPS module via UART to extract live location and time data. The code supports reading the GPS data, parsing time information, and adjusting it based on the timezone.
def fetch_gps_data():
gps_data = get_gps_data()
if gps_data.startswith('$GPRMC'):
# Extract latitude and longitude from GPRMC data
...
This functionality makes the project useful in outdoor applications such as fitness tracking, where location and time tracking is vital.
OLED Display
The SSD1306 OLED display serves as a secondary output to show additional information, such as temperature, humidity, and GPS data. This is a nice complement to the LED matrix display, especially for more detailed information that doesn’t need to be visualized on the larger LED display.
def update_oled(temp, humidity, gps_data, display_text):
oled.fill(0) # Clear screen
oled.text(f"Temp: {temp:.2f} C", 0, 0)
oled.text(f"Hum: {humidity:.2f} %", 0, 10)
oled.text("GPS:", 0, 20)
oled.text(gps_data if gps_data else "No Data", 0, 30)
oled.text(display_text, 0, 40)
oled.show()
This allows the OLED display to show the temperature, humidity, GPS data, and the text that is being scrolled on the LED matrix.
Button and Timer
A button connected to pin GP2 starts a timer when pressed. This is useful for tracking elapsed time, whether it's for a race or just for general timing purposes.
if not button.value() and not button_pressed:
button_pressed = True
start_time = utime.ticks_ms()
When the button is pressed, it starts counting the time, which can be displayed on the LED matrix in HH:MM:SS format.
Temperature and Humidity Monitoring
Using the AHT10/AHT20 sensor, the code captures the current temperature and humidity, displaying it both on the OLED and the LED matrix.
def read_temperature_and_humidity():
try:
temperature = sensor.temperature
humidity = sensor.relative_humidity
return temperature, humidity
except OSError:
return None, None
This makes the project useful in environmental monitoring or fitness applications where it’s important to track weather conditions.
Application Examples
Here are a few real-world applications of this project:
-
Fitness Tracker: It can display GPS-based metrics like distance, speed, and heart rate on the LED matrix, while also keeping track of environmental data like temperature and humidity.
-
Event Timer: Use the button to start a race or any timed event, and have the LED matrix show the time as it counts.
-
Information Display: This setup can be used as an interactive display in events or kiosks to show useful information like location, temperature, or custom messages.
-
Personalized Smart Home Display: Integrate additional sensors like motion detectors and make a smart notification system for your home.
Conclusion
This project demonstrates how to combine various sensors and modules to create a multi-functional display system. From scrolling messages to real-time sensor data, the possibilities are wide. Whether for fun personal projects or useful real-world applications, this setup has a lot of potential.
Have fun building and customizing this project! What other features would you add?