Skip to content

Commit 9836040

Browse files
authored
Add Adafruit Metro RP2350 DVI Matrix code
1 parent 86866a4 commit 9836040

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

Metro/Metro_HSTX_Matrix/matrix.ino

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
// SPDX-FileCopyrightText: 2021 Anne Barela for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
//
5+
// Based on Adafruit-DVI-HSTX library code written by Jeff Epler
6+
// and use of Claude 3.7 Sonnet
7+
// https://claude.site/artifacts/cf022b66-50c3-43eb-b334-17fbf0ed791c
8+
// on 3/2/2025
9+
10+
#include <Adafruit_dvhstx.h>
11+
12+
// Display configuration for text mode in Adafruit-DVI-HSTX
13+
const int SCREEN_WIDTH = 91;
14+
const int SCREEN_HEIGHT = 30;
15+
16+
// Animation speed (lower = faster)
17+
// Adjust this value to change the speed of the animation
18+
const int ANIMATION_SPEED = 70; // milliseconds between updates
19+
20+
// Initialize display for Adafruit Metro RP2350
21+
DVHSTXText display({14, 18, 16, 12}); // Adafruit Metro HSTX Pinout
22+
23+
// Define structures for character streams
24+
struct CharStream {
25+
int x; // X position
26+
int y; // Y position (head of the stream)
27+
int length; // Length of the stream
28+
int speed; // How many frames to wait before moving
29+
int countdown; // Counter for movement
30+
bool active; // Whether this stream is currently active
31+
char chars[30]; // Characters in the stream
32+
};
33+
34+
// Array of character streams - increased for higher density
35+
// To fill 60-75% of the screen width (91 chars), we need around 55-68 active streams
36+
CharStream streams[250]; // Allow for decent density
37+
38+
// Stream creation rate (higher = more frequent new streams)
39+
const int STREAM_CREATION_CHANCE = 40; // % chance per frame to create new stream
40+
41+
// Initial streams to create at startup
42+
const int INITIAL_STREAMS = 30;
43+
44+
// Random characters that appear in the streams
45+
const char matrixChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]{}|;:,.<>?/\\";
46+
const int numMatrixChars = sizeof(matrixChars) - 1;
47+
48+
// Function declarations
49+
void initStreams();
50+
void updateStreams();
51+
void drawStream(CharStream &stream);
52+
void createNewStream();
53+
char getRandomChar();
54+
55+
void setup() {
56+
// Initialize the display
57+
display.begin();
58+
display.clear();
59+
60+
// Seed the random number generator
61+
randomSeed(analogRead(A0));
62+
63+
// Initialize all streams
64+
initStreams();
65+
}
66+
67+
void loop() {
68+
// Update and draw all streams
69+
updateStreams();
70+
71+
// Randomly create new streams at a higher rate
72+
if (random(100) < STREAM_CREATION_CHANCE) {
73+
createNewStream();
74+
}
75+
76+
// Control animation speed
77+
delay(ANIMATION_SPEED);
78+
}
79+
80+
void initStreams() {
81+
// Initialize all streams as inactive
82+
for (int i = 0; i < sizeof(streams) / sizeof(streams[0]); i++) {
83+
streams[i].active = false;
84+
}
85+
86+
// Create more initial streams for immediate visual impact
87+
for (int i = 0; i < INITIAL_STREAMS; i++) {
88+
createNewStream();
89+
}
90+
}
91+
92+
void createNewStream() {
93+
// Find an inactive stream
94+
for (int i = 0; i < sizeof(streams) / sizeof(streams[0]); i++) {
95+
if (!streams[i].active) {
96+
// Initialize the stream
97+
streams[i].x = random(SCREEN_WIDTH);
98+
streams[i].y = random(5) - 5; // Start above the screen
99+
streams[i].length = random(5, 20);
100+
streams[i].speed = random(1, 4);
101+
streams[i].countdown = streams[i].speed;
102+
streams[i].active = true;
103+
104+
// Fill with random characters
105+
for (int j = 0; j < streams[i].length; j++) {
106+
streams[i].chars[j] = getRandomChar();
107+
}
108+
109+
return;
110+
}
111+
}
112+
}
113+
114+
void updateStreams() {
115+
display.clear();
116+
117+
// Count active streams (for debugging if needed)
118+
int activeCount = 0;
119+
120+
for (int i = 0; i < sizeof(streams) / sizeof(streams[0]); i++) {
121+
if (streams[i].active) {
122+
activeCount++;
123+
streams[i].countdown--;
124+
125+
// Time to move the stream down
126+
if (streams[i].countdown <= 0) {
127+
streams[i].y++;
128+
streams[i].countdown = streams[i].speed;
129+
130+
// Change a random character in the stream
131+
int randomIndex = random(streams[i].length);
132+
streams[i].chars[randomIndex] = getRandomChar();
133+
}
134+
135+
// Draw the stream
136+
drawStream(streams[i]);
137+
138+
// Check if the stream has moved completely off the screen
139+
if (streams[i].y - streams[i].length > SCREEN_HEIGHT) {
140+
streams[i].active = false;
141+
}
142+
}
143+
}
144+
}
145+
146+
void drawStream(CharStream &stream) {
147+
for (int i = 0; i < stream.length; i++) {
148+
int y = stream.y - i;
149+
150+
// Only draw if the character is on screen
151+
if (y >= 0 && y < SCREEN_HEIGHT) {
152+
display.setCursor(stream.x, y);
153+
154+
// Set different colors/intensities based on position in the stream
155+
if (i == 0) {
156+
// Head of the stream is white (brightest)
157+
display.setColor(TextColor::TEXT_WHITE, TextColor::BG_BLACK, TextColor::ATTR_NORMAL_INTEN);
158+
} else if (i < 3) {
159+
// First few characters are bright green
160+
display.setColor(TextColor::TEXT_GREEN, TextColor::BG_BLACK, TextColor::ATTR_NORMAL_INTEN);
161+
} else if (i < 6) {
162+
// Next few are medium green
163+
display.setColor(TextColor::TEXT_GREEN, TextColor::BG_BLACK, TextColor::ATTR_LOW_INTEN);
164+
} else {
165+
// The rest are dim green
166+
display.setColor(TextColor::TEXT_GREEN, TextColor::BG_BLACK, TextColor::ATTR_V_LOW_INTEN);
167+
}
168+
169+
// Draw the character
170+
display.write(stream.chars[i]);
171+
}
172+
}
173+
174+
// Occasionally change a character in the stream
175+
if (random(100) < 25) { // 25% chance
176+
int idx = random(stream.length);
177+
stream.chars[idx] = getRandomChar();
178+
}
179+
}
180+
181+
char getRandomChar() {
182+
return matrixChars[random(numMatrixChars)];
183+
}

0 commit comments

Comments
 (0)