Components and supplies
LED Matrix Panel
MPU6050 Accelerometer
ESP32
Push Button
Tools and machines
Soldering kit
Apps and platforms
Arduino IDE
Project description
Code
CODE Color palette
cpp
...
1#include <FastLED.h> 2#include <Wire.h> 3#include <MPU6050.h> 4 5// Pin definitions 6#define LED_PIN 5 7#define SDA_PIN 21 8#define SCL_PIN 22 9 10#define NUM_LEDS 256 11#define MATRIX_WIDTH 16 12#define MATRIX_HEIGHT 16 13#define FLUID_PARTICLES 64 14#define BRIGHTNESS 100 15 16// Structures 17struct Vector2D { 18 float x; 19 float y; 20}; 21 22struct Particle { 23 Vector2D position; 24 Vector2D velocity; 25}; 26 27// Global variables 28CRGB leds[NUM_LEDS]; 29MPU6050 mpu; 30Particle particles[FLUID_PARTICLES]; 31Vector2D acceleration = {0, 0}; 32 33// Mutex for synchronization 34portMUX_TYPE dataMux = portMUX_INITIALIZER_UNLOCKED; 35 36// Adjusted constants for smoother motion 37const float GRAVITY = 0.3f; //0.03f 38const float DAMPING = 0.60f; // 0.98f 39const float MAX_VELOCITY = 0.7f; //0.3f 40const float MIN_MOVEMENT = 0.001f; //0.001f 41 42// Function prototypes 43void initMPU6050(); 44void initLEDs(); 45void initParticles(); 46void updateParticles(); 47void drawParticles(); 48void MPUTask(void *parameter); 49void LEDTask(void *parameter); 50 51// Function to convert x,y coordinates to LED index 52int xy(int x, int y) { 53 x = constrain(x, 0, MATRIX_WIDTH - 1); 54 y = constrain(y, 0, MATRIX_HEIGHT - 1); 55 return (y & 1) ? (y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x)) : (y * MATRIX_WIDTH + x); 56} 57 58void drawParticles() { 59 FastLED.clear(); 60 61 // Create occupancy grid 62 bool occupied[MATRIX_WIDTH][MATRIX_HEIGHT] = {{false}}; 63 64 // Get and smooth gravity direction 65 static Vector2D lastGravityDir = {0, 1}; 66 Vector2D currentGravityDir; 67 68 portENTER_CRITICAL(&dataMux); 69 currentGravityDir = acceleration; 70 portEXIT_CRITICAL(&dataMux); 71 72 const float GRAVITY_SMOOTHING = 0.95f; 73 lastGravityDir.x = lastGravityDir.x * GRAVITY_SMOOTHING + currentGravityDir.x * (1 - GRAVITY_SMOOTHING); 74 lastGravityDir.y = lastGravityDir.y * GRAVITY_SMOOTHING + currentGravityDir.y * (1 - GRAVITY_SMOOTHING); 75 76 // Normalize gravity vector 77 float gravMagnitude = sqrt(lastGravityDir.x * lastGravityDir.x + lastGravityDir.y * lastGravityDir.y); 78 Vector2D gravityDir = {0, 1}; // Default down direction 79 80 if (gravMagnitude > 0.1f) { 81 gravityDir.x = lastGravityDir.x / gravMagnitude; 82 gravityDir.y = lastGravityDir.y / gravMagnitude; 83 } 84 85 // Calculate heights and prepare for drawing 86 float heights[FLUID_PARTICLES]; 87 float minHeight = 1000; 88 float maxHeight = -1000; 89 90 for (int i = 0; i < FLUID_PARTICLES; i++) { 91 heights[i] = -(particles[i].position.x * gravityDir.x + 92 particles[i].position.y * gravityDir.y); 93 minHeight = min(minHeight, heights[i]); 94 maxHeight = max(maxHeight, heights[i]); 95 } 96 97 float heightRange = max(maxHeight - minHeight, 1.0f); 98 99 // Draw particles 100 int visibleCount = 0; 101 for (int i = 0; i < FLUID_PARTICLES; i++) { 102 int x = round(constrain(particles[i].position.x, 0, MATRIX_WIDTH - 1)); 103 int y = round(constrain(particles[i].position.y, 0, MATRIX_HEIGHT - 1)); 104 105 if (!occupied[x][y]) { 106 int index = xy(x, y); 107 if (index >= 0 && index < NUM_LEDS) { 108 float relativeHeight = (heights[i] - minHeight) / heightRange; 109 uint8_t hue = relativeHeight * 160; // Map from 0 (red) to 160 (blue) 110 uint8_t sat = 255; // Full saturation for vibrant colors 111 uint8_t val = 220 + (relativeHeight * 35); // Slightly brighter at top; 112 113 leds[index] = CHSV(hue, sat, val); 114 occupied[x][y] = true; 115 visibleCount++; 116 } 117 } else { 118 // Find nearest empty position 119 for (int dx = -1; dx <= 1; dx++) { 120 for (int dy = -1; dy <= 1; dy++) { 121 if (dx == 0 && dy == 0) continue; 122 123 int newX = x + dx; 124 int newY = y + dy; 125 126 if (newX >= 0 && newX < MATRIX_WIDTH && 127 newY >= 0 && newY < MATRIX_HEIGHT && 128 !occupied[newX][newY]) { 129 int index = xy(newX, newY); 130 if (index >= 0 && index < NUM_LEDS) { 131 float relativeHeight = (heights[i] - minHeight) / heightRange; 132 uint8_t hue = relativeHeight * 160; // Map from 0 (red) to 160 (blue) 133 uint8_t sat = 255; // Full saturation for vibrant colors 134 uint8_t val = 220 + (relativeHeight * 35); // Slightly brighter at top 135 136 137 leds[index] = CHSV(hue, sat, val); 138 occupied[newX][newY] = true; 139 visibleCount++; 140 goto particleDrawn; 141 } 142 } 143 } 144 } 145 particleDrawn: continue; 146 } 147 } 148 149 // Debug output 150 static unsigned long lastDebugTime = 0; 151 if (millis() - lastDebugTime > 1000) { 152 Serial.printf("Visible particles: %d of %d\n", visibleCount, FLUID_PARTICLES); 153 lastDebugTime = millis(); 154 } 155 156 FastLED.show(); 157} 158 159 160 161void updateParticles() { 162 Vector2D currentAccel; 163 portENTER_CRITICAL(&dataMux); 164 currentAccel = acceleration; 165 portEXIT_CRITICAL(&dataMux); 166 167 // Reduce acceleration sensitivity 168 currentAccel.x *= 0.3f; 169 currentAccel.y *= 0.3f; 170 171 // Update and constrain each particle 172 for (int i = 0; i < FLUID_PARTICLES; i++) { 173 // Update velocity with acceleration 174 particles[i].velocity.x = particles[i].velocity.x * 0.95f + (currentAccel.x * GRAVITY); 175 particles[i].velocity.y = particles[i].velocity.y * 0.95f + (currentAccel.y * GRAVITY); 176 177 // Hard constrain velocity 178 particles[i].velocity.x = constrain(particles[i].velocity.x, -MAX_VELOCITY, MAX_VELOCITY); 179 particles[i].velocity.y = constrain(particles[i].velocity.y, -MAX_VELOCITY, MAX_VELOCITY); 180 181 // Calculate new position 182 float newX = particles[i].position.x + particles[i].velocity.x; 183 float newY = particles[i].position.y + particles[i].velocity.y; 184 185 // Strict boundary checking with bounce 186 if (newX < 0.0f) { 187 newX = 0.0f; 188 particles[i].velocity.x = fabs(particles[i].velocity.x) * DAMPING; 189 } 190 else if (newX >= (MATRIX_WIDTH - 1.0f)) { 191 newX = MATRIX_WIDTH - 1.0f; 192 particles[i].velocity.x = -fabs(particles[i].velocity.x) * DAMPING; 193 } 194 195 if (newY < 0.0f) { 196 newY = 0.0f; 197 particles[i].velocity.y = fabs(particles[i].velocity.y) * DAMPING; 198 } 199 else if (newY >= (MATRIX_HEIGHT - 1.0f)) { 200 newY = MATRIX_HEIGHT - 1.0f; 201 particles[i].velocity.y = -fabs(particles[i].velocity.y) * DAMPING; 202 } 203 204 // Ensure positions are always within bounds 205 particles[i].position.x = constrain(newX, 0.0f, MATRIX_WIDTH - 1.0f); 206 particles[i].position.y = constrain(newY, 0.0f, MATRIX_HEIGHT - 1.0f); 207 208 // Additional safety check 209 if (isnan(particles[i].position.x) || isnan(particles[i].position.y)) { 210 particles[i].position.x = MATRIX_WIDTH / 2; 211 particles[i].position.y = MATRIX_HEIGHT / 2; 212 particles[i].velocity.x = 0; 213 particles[i].velocity.y = 0; 214 } 215 } 216 217 // Particle collision detection and resolution 218 for (int i = 0; i < FLUID_PARTICLES; i++) { 219 for (int j = i + 1; j < FLUID_PARTICLES; j++) { 220 float dx = particles[j].position.x - particles[i].position.x; 221 float dy = particles[j].position.y - particles[i].position.y; 222 float distSquared = dx * dx + dy * dy; 223 224 if (distSquared < 1.0f && distSquared > 0.0f) { 225 float dist = sqrt(distSquared); 226 float nx = dx / dist; 227 float ny = dy / dist; 228 229 // Push particles apart 230 float pushDistance = (1.0f - dist) * 0.5f; 231 float pushX = nx * pushDistance; 232 float pushY = ny * pushDistance; 233 234 // Update positions while ensuring they stay in bounds 235 particles[i].position.x = constrain(particles[i].position.x - pushX, 0.0f, MATRIX_WIDTH - 1.0f); 236 particles[i].position.y = constrain(particles[i].position.y - pushY, 0.0f, MATRIX_HEIGHT - 1.0f); 237 particles[j].position.x = constrain(particles[j].position.x + pushX, 0.0f, MATRIX_WIDTH - 1.0f); 238 particles[j].position.y = constrain(particles[j].position.y + pushY, 0.0f, MATRIX_HEIGHT - 1.0f); 239 240 // Exchange velocities with damping 241 float tempVelX = particles[i].velocity.x; 242 float tempVelY = particles[i].velocity.y; 243 particles[i].velocity.x = particles[j].velocity.x * DAMPING; 244 particles[i].velocity.y = particles[j].velocity.y * DAMPING; 245 particles[j].velocity.x = tempVelX * DAMPING; 246 particles[j].velocity.y = tempVelY * DAMPING; 247 } 248 } 249 } 250} 251 252 253 254 255void initMPU6050() { 256 Serial.println("Initializing MPU6050..."); 257 mpu.initialize(); 258 259 if (!mpu.testConnection()) { 260 Serial.println("MPU6050 connection failed!"); 261 while (1) { 262 delay(100); 263 } 264 } 265 266 mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2); 267 Serial.println("MPU6050 initialized"); 268} 269 270void initLEDs() { 271 Serial.println("Initializing LEDs..."); 272 FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS); 273 FastLED.setBrightness(BRIGHTNESS); 274 FastLED.clear(true); 275 Serial.println("LEDs initialized"); 276} 277 278void initParticles() { 279 Serial.println("Initializing particles..."); 280 int index = 0; 281 282 for (int y = MATRIX_HEIGHT - 4; y < MATRIX_HEIGHT; y++) { 283 for (int x = 0; x < MATRIX_WIDTH && index < FLUID_PARTICLES; x++) { 284 Serial.printf("Initializing particle %d at x=%d, y=%d\n", index, x, y); 285 particles[index].position = {static_cast<float>(x), static_cast<float>(y)}; 286 particles[index].velocity = {0.0f, 0.0f}; 287 index++; 288 } 289 } 290 291 Serial.printf("Total particles initialized: %d\n", index); 292 Serial.println("Particles initialized"); 293} 294 295void MPUTask(void *parameter) { 296 while (true) { 297 int16_t ax, ay, az; 298 mpu.getAcceleration(&ax, &ay, &az); 299 300 portENTER_CRITICAL(&dataMux); 301 acceleration.x = -constrain(ax / 16384.0f, -1.0f, 1.0f); 302 acceleration.y = constrain(ay / 16384.0f, -1.0f, 1.0f); 303 portEXIT_CRITICAL(&dataMux); 304 305 vTaskDelay(pdMS_TO_TICKS(10)); 306 } 307} 308 309void LEDTask(void *parameter) { 310 TickType_t xLastWakeTime = xTaskGetTickCount(); 311 const TickType_t xFrequency = pdMS_TO_TICKS(16); 312 313 while (true) { 314 updateParticles(); 315 drawParticles(); 316 vTaskDelayUntil(&xLastWakeTime, xFrequency); 317 } 318} 319 320void setup() { 321 Serial.begin(115200); 322 delay(1000); 323 Serial.println("Starting initialization..."); 324 325 Wire.begin(SDA_PIN, SCL_PIN); 326 Wire.setClock(400000); 327 328 initMPU6050(); 329 initLEDs(); 330 initParticles(); 331 332 xTaskCreatePinnedToCore( 333 MPUTask, 334 "MPUTask", 335 4096, 336 NULL, 337 2, 338 NULL, 339 0 340 ); 341 342 xTaskCreatePinnedToCore( 343 LEDTask, 344 "LEDTask", 345 4096, 346 NULL, 347 1, 348 NULL, 349 1 350 ); 351 352 Serial.println("Setup complete"); 353} 354 355void loop() { 356 vTaskDelete(NULL); 357}
CODE Colors Button
cpp
...
1// colors: 0 = Red, 32 = Orange, 64 = Yellow, 96 = Green, 128 = Aqua, 160 = Blue, 192 = Purple, 224 = Pink 2 3 4#include <FastLED.h> 5#include <Wire.h> 6#include <MPU6050.h> 7 8// Pin definitions 9#define LED_PIN 5 10#define SDA_PIN 21 11#define SCL_PIN 22 12#define BUTTON_PIN 4 // Button for color switching 13 14#define NUM_LEDS 256 15#define MATRIX_WIDTH 16 16#define MATRIX_HEIGHT 16 17#define FLUID_PARTICLES 64 //80/64 18#define BRIGHTNESS 30 19#define NUM_COLORS 3 // Number of color options 20 21// Structures 22struct Vector2D { 23 float x; 24 float y; 25}; 26 27struct Particle { 28 Vector2D position; 29 Vector2D velocity; 30}; 31 32// Global variables 33CRGB leds[NUM_LEDS]; 34MPU6050 mpu; 35Particle particles[FLUID_PARTICLES]; 36Vector2D acceleration = {0, 0}; 37 38// Color switching variables 39uint8_t currentColorIndex = 0; 40unsigned long lastDebounceTime = 0; 41const unsigned long debounceDelay = 200; 42 43// Define the colors (you can change these hue values) 44const uint8_t COLORS[NUM_COLORS] = { 45 160, // Blue 46 0, // Red 47 96 // Green 48}; 49 50// Mutex for synchronization 51portMUX_TYPE dataMux = portMUX_INITIALIZER_UNLOCKED; 52 53// Constants for physics 54const float GRAVITY = 0.08f; //0.3f /098f 55const float DAMPING = 0.92f; //0.99f /0.9f 56const float MAX_VELOCITY = 0.6f; //0.6f /2.9f 57 58// Function prototypes 59void initMPU6050(); 60void initLEDs(); 61void initParticles(); 62void updateParticles(); 63void drawParticles(); 64void MPUTask(void *parameter); 65void LEDTask(void *parameter); 66void checkButton(); 67 68// Function to convert x,y coordinates to LED index 69int xy(int x, int y) { 70 x = constrain(x, 0, MATRIX_WIDTH - 1); 71 y = constrain(y, 0, MATRIX_HEIGHT - 1); 72 return (y & 1) ? (y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x)) : (y * MATRIX_WIDTH + x); 73} 74 75void checkButton() { 76 static bool lastButtonState = HIGH; 77 bool buttonState = digitalRead(BUTTON_PIN); 78 79 if (buttonState == LOW && lastButtonState == HIGH) { // Button pressed 80 if ((millis() - lastDebounceTime) > debounceDelay) { 81 currentColorIndex = (currentColorIndex + 1) % NUM_COLORS; 82 lastDebounceTime = millis(); 83 } 84 } 85 lastButtonState = buttonState; 86} 87 88void drawParticles() { 89 FastLED.clear(); 90 91 bool occupied[MATRIX_WIDTH][MATRIX_HEIGHT] = {{false}}; 92 93 struct ParticleIndex { 94 int index; 95 float position; 96 }; 97 98 ParticleIndex sortedParticles[FLUID_PARTICLES]; 99 for (int i = 0; i < FLUID_PARTICLES; i++) { 100 sortedParticles[i].index = i; 101 sortedParticles[i].position = particles[i].position.y * MATRIX_WIDTH + particles[i].position.x; 102 } 103 104 for (int i = 0; i < FLUID_PARTICLES - 1; i++) { 105 for (int j = 0; j < FLUID_PARTICLES - i - 1; j++) { 106 if (sortedParticles[j].position > sortedParticles[j + 1].position) { 107 ParticleIndex temp = sortedParticles[j]; 108 sortedParticles[j] = sortedParticles[j + 1]; 109 sortedParticles[j + 1] = temp; 110 } 111 } 112 } 113 114 for (int i = 0; i < FLUID_PARTICLES; i++) { 115 int particleIndex = sortedParticles[i].index; 116 int x = round(particles[particleIndex].position.x); 117 int y = round(particles[particleIndex].position.y); 118 119 x = constrain(x, 0, MATRIX_WIDTH - 1); 120 y = constrain(y, 0, MATRIX_HEIGHT - 1); 121 122 if (!occupied[x][y]) { 123 int index = xy(x, y); 124 if (index >= 0 && index < NUM_LEDS) { 125 float speed = sqrt( 126 particles[particleIndex].velocity.x * particles[particleIndex].velocity.x + 127 particles[particleIndex].velocity.y * particles[particleIndex].velocity.y 128 ); 129 130 uint8_t hue = COLORS[currentColorIndex]; 131 uint8_t sat = 255; 132 uint8_t val = constrain(180 + (speed * 50), 180, 255); 133 134 leds[index] = CHSV(hue, sat, val); 135 occupied[x][y] = true; 136 } 137 } else { 138 for (int r = 1; r < 3; r++) { 139 for (int dx = -r; dx <= r; dx++) { 140 for (int dy = -r; dy <= r; dy++) { 141 if (abs(dx) + abs(dy) == r) { 142 int newX = x + dx; 143 int newY = y + dy; 144 if (newX >= 0 && newX < MATRIX_WIDTH && 145 newY >= 0 && newY < MATRIX_HEIGHT && 146 !occupied[newX][newY]) { 147 int index = xy(newX, newY); 148 if (index >= 0 && index < NUM_LEDS) { 149 leds[index] = CHSV(COLORS[currentColorIndex], 255, 180); 150 occupied[newX][newY] = true; 151 goto nextParticle; 152 } 153 } 154 } 155 } 156 } 157 } 158 nextParticle: 159 continue; 160 } 161 } 162 163 FastLED.show(); 164} 165 166void updateParticles() { 167 Vector2D currentAccel; 168 portENTER_CRITICAL(&dataMux); 169 currentAccel = acceleration; 170 portEXIT_CRITICAL(&dataMux); 171 172 currentAccel.x *= 0.3f; 173 currentAccel.y *= 0.3f; 174 175 for (int i = 0; i < FLUID_PARTICLES; i++) { 176 particles[i].velocity.x = particles[i].velocity.x * 0.9f + (currentAccel.x * GRAVITY); 177 particles[i].velocity.y = particles[i].velocity.y * 0.9f + (currentAccel.y * GRAVITY); 178 179 particles[i].velocity.x = constrain(particles[i].velocity.x, -MAX_VELOCITY, MAX_VELOCITY); 180 particles[i].velocity.y = constrain(particles[i].velocity.y, -MAX_VELOCITY, MAX_VELOCITY); 181 182 float newX = particles[i].position.x + particles[i].velocity.x; 183 float newY = particles[i].position.y + particles[i].velocity.y; 184 185 if (newX < 0.0f) { 186 newX = 0.0f; 187 particles[i].velocity.x = fabs(particles[i].velocity.x) * DAMPING; 188 } 189 else if (newX >= (MATRIX_WIDTH - 1)) { 190 newX = MATRIX_WIDTH - 1; 191 particles[i].velocity.x = -fabs(particles[i].velocity.x) * DAMPING; 192 } 193 194 if (newY < 0.0f) { 195 newY = 0.0f; 196 particles[i].velocity.y = fabs(particles[i].velocity.y) * DAMPING; 197 } 198 else if (newY >= (MATRIX_HEIGHT - 1)) { 199 newY = MATRIX_HEIGHT - 1; 200 particles[i].velocity.y = -fabs(particles[i].velocity.y) * DAMPING; 201 } 202 203 particles[i].position.x = constrain(newX, 0.0f, MATRIX_WIDTH - 1); 204 particles[i].position.y = constrain(newY, 0.0f, MATRIX_HEIGHT - 1); 205 206 particles[i].velocity.x *= 0.95f; 207 particles[i].velocity.y *= 0.95f; 208 } 209 210 for (int i = 0; i < FLUID_PARTICLES; i++) { 211 for (int j = i + 1; j < FLUID_PARTICLES; j++) { 212 float dx = particles[j].position.x - particles[i].position.x; 213 float dy = particles[j].position.y - particles[i].position.y; 214 float distanceSquared = dx * dx + dy * dy; 215 216 if (distanceSquared < 1.0f) { 217 float distance = sqrt(distanceSquared); 218 float angle = atan2(dy, dx); 219 220 float repulsionX = cos(angle) * 0.5f; 221 float repulsionY = sin(angle) * 0.5f; 222 223 particles[i].position.x -= repulsionX * 0.3f; 224 particles[i].position.y -= repulsionY * 0.3f; 225 particles[j].position.x += repulsionX * 0.3f; 226 particles[j].position.y += repulsionY * 0.3f; 227 228 Vector2D avgVel = { 229 (particles[i].velocity.x + particles[j].velocity.x) * 0.5f, 230 (particles[i].velocity.y + particles[j].velocity.y) * 0.5f 231 }; 232 233 particles[i].velocity = avgVel; 234 particles[j].velocity = avgVel; 235 } 236 } 237 } 238} 239 240void initMPU6050() { 241 Serial.println("Initializing MPU6050..."); 242 mpu.initialize(); 243 244 if (!mpu.testConnection()) { 245 Serial.println("MPU6050 connection failed!"); 246 while (1) { 247 delay(100); 248 } 249 } 250 251 mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2); 252 Serial.println("MPU6050 initialized"); 253} 254 255void initLEDs() { 256 Serial.println("Initializing LEDs..."); 257 FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS); 258 FastLED.setBrightness(BRIGHTNESS); 259 FastLED.clear(true); 260 Serial.println("LEDs initialized"); 261} 262 263void initParticles() { 264 Serial.println("Initializing particles..."); 265 int index = 0; 266 267 for (int y = MATRIX_HEIGHT - 4; y < MATRIX_HEIGHT; y++) { 268 for (int x = 0; x < MATRIX_WIDTH && index < FLUID_PARTICLES; x++) { 269 particles[index].position = {static_cast<float>(x), static_cast<float>(y)}; 270 particles[index].velocity = {0.0f, 0.0f}; 271 index++; 272 } 273 } 274 275 Serial.printf("Total particles initialized: %d\n", index); 276} 277 278void MPUTask(void *parameter) { 279 while (true) { 280 int16_t ax, ay, az; 281 mpu.getAcceleration(&ax, &ay, &az); 282 283 portENTER_CRITICAL(&dataMux); 284 acceleration.x = -constrain(ax / 16384.0f, -1.0f, 1.0f); 285 acceleration.y = constrain(ay / 16384.0f, -1.0f, 1.0f); 286 portEXIT_CRITICAL(&dataMux); 287 288 vTaskDelay(pdMS_TO_TICKS(10)); 289 } 290} 291 292void LEDTask(void *parameter) { 293 TickType_t xLastWakeTime = xTaskGetTickCount(); 294 const TickType_t xFrequency = pdMS_TO_TICKS(16); 295 296 while (true) { 297 checkButton(); 298 updateParticles(); 299 drawParticles(); 300 vTaskDelayUntil(&xLastWakeTime, xFrequency); 301 } 302} 303 304void setup() { 305 Serial.begin(115200); 306 delay(1000); 307 Serial.println("Starting initialization..."); 308 309 // Initialize button pin 310 pinMode(BUTTON_PIN, INPUT_PULLUP); 311 312 Wire.begin(SDA_PIN, SCL_PIN); 313 Wire.setClock(400000); 314 315 initMPU6050(); 316 initLEDs(); 317 initParticles(); 318 319 xTaskCreatePinnedToCore( 320 MPUTask, 321 "MPUTask", 322 4096, 323 NULL, 324 2, 325 NULL, 326 0 327 ); 328 329 xTaskCreatePinnedToCore( 330 LEDTask, 331 "LEDTask", 332 4096, 333 NULL, 334 1, 335 NULL, 336 1 337 ); 338 339 Serial.println("Setup complete"); 340} 341 342void loop() { 343 vTaskDelete(NULL); 344}
Downloadable files
Libraries
Libraries.zip
Documentation
Schematic
...
Schematic.jpg
Comments
Only logged in users can leave comments