working welcome_demo

This commit is contained in:
Superminaren 2026-05-18 23:12:53 +02:00
parent c7de029363
commit b7fddbec85
350 changed files with 35029 additions and 318 deletions

View File

@ -8,6 +8,9 @@
bool hidMode = false;
static const int8_t cos_lookup[] = { 0, 1, 1, 0, -1, -1, 0, 1 };
static const int8_t sin_lookup[] = { 1, 0, -1, -1, 0, 1, 1, 0 };
// --- Buttons (active LOW, internal pull-ups) ---
// Per schematic: BTN_A=GP8, B=GP9, UP=GP10, DWN=GP11, LFT=GP12, RGT=GP13
#define BTN_A 8
@ -102,109 +105,134 @@ void scanI2C(TwoWire& bus, const char* label) {
// ------------------------------------------------------------------- animation state ---
enum AnimState {
ANIM_ALL_ON,
ANIM_CORNERS,
ANIM_ROW_SWEEP,
ANIM_COL_SWEEP,
ANIM_CHEVRON,
ANIM_DRIVEABLE,
ANIM_RAIN,
ANIM_SPARKLE,
ANIM_BOUNCE,
ANIM_PLASMA,
ANIM_MATRIX,
ANIM_PULSE,
ANIM_TEXT_SCROLL,
ANIM_COUNT
};
AnimState animState = ANIM_ALL_ON;
AnimState animState = ANIM_RAIN;
uint32_t animStartTime = 0;
const uint32_t ANIM_DURATION = 2000;
int scrollPos = 0;
uint32_t lastFrameTime = 0;
const uint32_t FRAME_TIME = 100;
const uint32_t ANIM_DURATION = 4000;
struct Point { int x; int y; };
const Point corners[4] = {
{0, 0},
{MATRIX_W - 1, 0},
{0, MATRIX_H - 1},
{MATRIX_W - 1, MATRIX_H - 1}
};
struct Drop { int x; int y; int8_t vy; };
Drop drops[9];
uint8_t sparkles[MATRIX_W][MATRIX_H];
uint8_t plasma[MATRIX_W][MATRIX_H];
int bounceX = 4, bounceY = 8;
int8_t bounceVX = 1, bounceVY = -1;
void initAnimations() {
for (int i = 0; i < 9; i++) {
drops[i].x = i;
drops[i].y = random(0, 16);
drops[i].vy = random(1, 3);
}
for (int x = 0; x < MATRIX_W; x++)
for (int y = 0; y < MATRIX_H; y++)
sparkles[x][y] = 0;
bounceX = 4; bounceY = 8;
bounceVX = 1; bounceVY = -1;
}
void runAnimation() {
if (!matrix) return;
uint32_t elapsed = millis() - animStartTime;
uint32_t now = millis();
if (now - lastFrameTime < FRAME_TIME) return;
lastFrameTime = now;
switch (animState) {
case ANIM_ALL_ON:
case ANIM_RAIN:
matrix->clear();
matrixFill(50);
if (elapsed > ANIM_DURATION) {
animState = ANIM_CORNERS;
animStartTime = millis();
for (int i = 0; i < 9; i++) {
matrixSetPixel(drops[i].x, drops[i].y, 255);
drops[i].y += drops[i].vy;
if (drops[i].y >= MATRIX_H) {
drops[i].y = 0;
drops[i].x = random(0, MATRIX_W);
}
}
break;
case ANIM_CORNERS: {
int corner = (elapsed / 500) % 4;
case ANIM_SPARKLE: {
matrix->clear();
matrixSetPixel(corners[corner].x, corners[corner].y, 220);
if (elapsed > ANIM_DURATION) {
animState = ANIM_ROW_SWEEP;
animStartTime = millis();
for (int x = 0; x < MATRIX_W; x++) {
for (int y = 0; y < MATRIX_H; y++) {
if (sparkles[x][y] > 0) {
matrixSetPixel(x, y, sparkles[x][y]);
if (sparkles[x][y] > 20) sparkles[x][y] -= 20;
else sparkles[x][y] = 0;
}
}
}
int sx = random(0, MATRIX_W);
int sy = random(0, MATRIX_H);
if (!matrixPixelIsDead(sx, sy)) sparkles[sx][sy] = 255;
break;
}
case ANIM_BOUNCE:
matrix->clear();
if (!matrixPixelIsDead(bounceX, bounceY)) matrixSetPixel(bounceX, bounceY, 255);
bounceX += bounceVX;
bounceY += bounceVY;
if (bounceX <= 0 || bounceX >= MATRIX_W - 1) bounceVX *= -1;
if (bounceY <= 0 || bounceY >= MATRIX_H - 1) bounceVY *= -1;
break;
case ANIM_PLASMA: {
static uint32_t t = 0;
t += 2;
for (int x = 0; x < MATRIX_W; x++) {
for (int y = 0; y < MATRIX_H; y++) {
uint8_t v = 128 + 127 * sin((x * 0.3) + (y * 0.2) + (t * 0.05));
plasma[x][y] = v;
}
}
matrix->clear();
for (int x = 0; x < MATRIX_W; x++)
for (int y = 0; y < MATRIX_H; y++)
if (!matrixPixelIsDead(x, y)) matrixSetPixel(x, y, plasma[x][y]);
break;
}
case ANIM_MATRIX: {
static uint32_t t = 0;
t++;
matrix->clear();
for (int x = 0; x < MATRIX_W; x++) {
int y = (t + x * 3) % MATRIX_H;
int brightness = 255;
for (int dy = 0; dy < 5 && y - dy >= 0; dy++) {
int b = brightness - (dy * 50);
if (b > 0) matrixSetPixel(x, y - dy, b);
}
}
break;
}
case ANIM_ROW_SWEEP: {
int y = (elapsed / 100) % MATRIX_H;
case ANIM_PULSE: {
static uint32_t t = 0;
t++;
matrix->clear();
for (int x = 0; x < MATRIX_W; x++) matrixSetPixel(x, y, 180);
if (elapsed > ANIM_DURATION) {
animState = ANIM_COL_SWEEP;
animStartTime = millis();
}
break;
}
case ANIM_COL_SWEEP: {
int x = (elapsed / 100) % MATRIX_W;
matrix->clear();
for (int y = 0; y < MATRIX_H; y++) matrixSetPixel(x, y, 180);
if (elapsed > ANIM_DURATION) {
animState = ANIM_CHEVRON;
animStartTime = millis();
}
break;
}
case ANIM_CHEVRON: {
static const uint8_t chevron[9][9] = {
{0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,1,0,1},
{0,0,0,0,0,1,0,1,0},
{0,0,0,0,1,0,1,0,0},
{0,0,0,1,0,1,0,0,0},
{0,0,1,0,1,0,0,0,0},
{0,1,0,1,0,0,0,0,0},
{1,0,1,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0},
};
matrix->clear();
for (int y = 0; y < 9; y++)
for (int x = 0; x < MATRIX_W; x++)
matrixSetPixel(x, y, chevron[y][x] ? 200 : 0);
if (elapsed > ANIM_DURATION) {
animState = ANIM_DRIVEABLE;
animStartTime = millis();
}
break;
}
case ANIM_DRIVEABLE: {
matrix->clear();
for (int y = 0; y < MATRIX_H; y++)
for (int x = 0; x < MATRIX_W; x++)
if (!matrixPixelIsDead(x, y)) matrixSetPixel(x, y, 60);
if (elapsed > ANIM_DURATION) {
animState = ANIM_TEXT_SCROLL;
animStartTime = millis();
scrollPos = 16;
int center = 4;
for (int r = 0; r < 8; r++) {
int ring = (t + r) % 8;
uint8_t b = (ring < 4) ? 255 : 100;
for (int a = 0; a < 8; a++) {
int x = center + ring * cos_lookup[a];
int y = center + ring * sin_lookup[a];
if (x >= 0 && x < MATRIX_W && y >= 0 && y < MATRIX_H && !matrixPixelIsDead(x, y))
matrixSetPixel(x, y, b);
}
}
break;
}
@ -218,16 +246,29 @@ void runAnimation() {
matrix->print(scrollText);
scrollPos++;
if (scrollPos > strlen(scrollText) * 6 + 16) {
animState = ANIM_ALL_ON;
animState = ANIM_RAIN;
initAnimations();
}
delay(60);
break;
return;
}
default:
animState = ANIM_ALL_ON;
animState = ANIM_RAIN;
initAnimations();
animStartTime = millis();
break;
}
if (millis() - animStartTime > ANIM_DURATION) {
animState = (AnimState)((animState + 1) % ANIM_TEXT_SCROLL);
animStartTime = millis();
if (animState == ANIM_TEXT_SCROLL) {
scrollPos = 0;
} else {
initAnimations();
}
}
}
// ------------------------------------------------------------------- setup ---
@ -287,6 +328,8 @@ void setup() {
matrix = nullptr;
} else {
Serial.println(" Found! Starting animation loop...");
initAnimations();
lastFrameTime = millis();
animStartTime = millis();
}

View File

@ -1,9 +1,12 @@
[env:rp2040]
[env:rp2040_swd]
platform = raspberrypi
board = rpipico
framework = arduino
monitor_speed = 115200
upload_speed = 115200
upload_protocol = cmsis-dap
debug_tool = cmsis-dap
build_flags =
-D PICO_SCAN_I2C_FOR_WIRE
-I src

View File

@ -1,233 +0,0 @@
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_IS31FL3731.h>
#define I2C_LED_MATRIX_SDA 2
#define I2C_LED_MATRIX_SCL 3
#define BTN_A 9
#define BTN_B 10
#define BTN_UP 11
#define BTN_DWN 12
#define BTN_LFT 13
#define BTN_RGT 14
#define LED_FLASHLIGHT 15
#define LED_FRONT_1 23
#define LED_FRONT_2 24
#define LED_FRONT_3 25
#define LED_FRONT_4 26
Adafruit_IS31FL3731 ledmatrix = Adafruit_IS31FL3731();
int ledPattern[9][9] = {0};
int frameBuffer = 0;
unsigned long lastFrame = 0;
struct Point { int x; int y; };
Point playerPos = {4, 4};
void drawPlayer() {
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
ledmatrix.enable(x, y, false);
}
}
if (playerPos.x >= 0 && playerPos.x < 9 && playerPos.y >= 0 && playerPos.y < 9) {
ledmatrix.enable(playerPos.x, playerPos.y, true);
}
}
void drawSplash() {
ledmatrix.clear();
for (int i = 0; i < 9; i++) {
ledmatrix.enable(i, i, true);
ledmatrix.enable(8 - i, i, true);
}
}
void drawCircle() {
ledmatrix.clear();
for (int angle = 0; angle < 360; angle += 10) {
int x = 4 + (int)(3.5 * cos(angle * PI / 180));
int y = 4 + (int)(3.5 * sin(angle * PI / 180));
if (x >= 0 && x < 9 && y >= 0 && y < 9) {
ledmatrix.enable(x, y, true);
}
}
}
void drawHeart() {
ledmatrix.clear();
int heart[9][9] = {
{0,1,1,0,0,0,1,1,0},
{1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,0},
{0,0,1,1,1,1,1,0,0},
{0,0,0,1,1,1,0,0,0},
{0,0,0,0,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0}
};
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
ledmatrix.enable(x, y, heart[y][x]);
}
}
}
void drawFrame1() {
ledmatrix.clear();
for (int i = 0; i < 9; i++) {
ledmatrix.enable(i, 0, true);
ledmatrix.enable(i, 8, true);
ledmatrix.enable(0, i, true);
ledmatrix.enable(8, i, true);
}
}
void drawFrame2() {
ledmatrix.clear();
for (int i = 1; i < 8; i++) {
ledmatrix.enable(i, 1, true);
ledmatrix.enable(i, 7, true);
ledmatrix.enable(1, i, true);
ledmatrix.enable(7, i, true);
}
}
void drawX() {
ledmatrix.clear();
for (int i = 0; i < 9; i++) {
ledmatrix.enable(i, i, true);
ledmatrix.enable(i, 8 - i, true);
}
}
void cycleGraphics() {
unsigned long now = millis();
if (now - lastFrame > 500) {
lastFrame = now;
frameBuffer = (frameBuffer + 1) % 6;
switch (frameBuffer) {
case 0: drawSplash(); break;
case 1: drawHeart(); break;
case 2: drawCircle(); break;
case 3: drawFrame1(); break;
case 4: drawFrame2(); break;
case 5: drawX(); break;
}
}
}
bool isButtonPressed(int btn) {
return digitalRead(btn) == LOW;
}
void handleButtons() {
if (isButtonPressed(BTN_A)) {
digitalWrite(LED_FRONT_1, HIGH);
playerPos.x = min(8, playerPos.x + 1);
} else {
digitalWrite(LED_FRONT_1, LOW);
}
if (isButtonPressed(BTN_B)) {
digitalWrite(LED_FRONT_2, HIGH);
playerPos.x = max(0, playerPos.x - 1);
} else {
digitalWrite(LED_FRONT_2, LOW);
}
if (isButtonPressed(BTN_UP)) {
digitalWrite(LED_FRONT_3, HIGH);
playerPos.y = max(0, playerPos.y - 1);
} else {
digitalWrite(LED_FRONT_3, LOW);
}
if (isButtonPressed(BTN_DWN)) {
digitalWrite(LED_FRONT_4, HIGH);
playerPos.y = min(8, playerPos.y + 1);
} else {
digitalWrite(LED_FRONT_4, LOW);
}
if (isButtonPressed(BTN_LFT)) {
digitalWrite(LED_FLASHLIGHT, HIGH);
} else {
digitalWrite(LED_FLASHLIGHT, LOW);
}
if (isButtonPressed(BTN_RGT)) {
cycleGraphics();
}
}
void blinkLEDs() {
static unsigned long lastBlink = 0;
static bool blinkState = false;
unsigned long now = millis();
if (now - lastBlink > 1000) {
lastBlink = now;
blinkState = !blinkState;
digitalWrite(LED_FRONT_1, blinkState ? HIGH : LOW);
digitalWrite(LED_FRONT_2, blinkState ? HIGH : LOW);
digitalWrite(LED_FRONT_3, blinkState ? HIGH : LOW);
digitalWrite(LED_FRONT_4, blinkState ? HIGH : LOW);
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("RP2040 Badge TestStarting...");
Wire.setSDA(I2C_LED_MATRIX_SDA);
Wire.setSCL(I2C_LED_MATRIX_SCL);
pinMode(BTN_A, INPUT_PULLUP);
pinMode(BTN_B, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DWN, INPUT_PULLUP);
pinMode(BTN_LFT, INPUT_PULLUP);
pinMode(BTN_RGT, INPUT_PULLUP);
pinMode(LED_FLASHLIGHT, OUTPUT);
pinMode(LED_FRONT_1, OUTPUT);
pinMode(LED_FRONT_2, OUTPUT);
pinMode(LED_FRONT_3, OUTPUT);
pinMode(LED_FRONT_4, OUTPUT);
Serial.println("Initializing LED Matrix...");
if (!ledmatrix.begin(0x74, &Wire)) {
Serial.println("IS31FL3731 not found!");
while (1) delay(1);
}
Serial.println("LED Matrix initialized!");
ledmatrix.setRotation(0);
ledmatrix.clear();
drawSplash();
delay(1000);
Serial.println("Setup complete!");
}
void loop() {
handleButtons();
if (isButtonPressed(BTN_RGT)) {
drawPlayer();
}
if (!isButtonPressed(BTN_A) && !isButtonPressed(BTN_B) &&
!isButtonPressed(BTN_UP) && !isButtonPressed(BTN_DWN) &&
!isButtonPressed(BTN_LFT) && !isButtonPressed(BTN_RGT)) {
blinkLEDs();
}
}

View File

@ -0,0 +1 @@
9a6f4d0322b1fccedc90b4ab9b847df51ed63da3

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More