#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD setup (adjust address if needed, e.g., 0x27 or 0x3F)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Audio input pin (connect microphone module to A0)
const int audioPin = A0;
// Beat detection parameters
const int sampleWindow = 50; // Sample window in ms
const int threshold = 500; // Beat threshold (adjust based on input)
unsigned long lastBeatTime = 0;
const int beatCooldown = 200; // Minimum time between beats in ms
// Waveform parameters
const int numColumns = 16;
int waveOffset = 0;
bool beatDetected = false;
void setup() {
// Initialize LCD
lcd.init();
lcd.backlight();
// Set audio input
pinMode(audioPin, INPUT);
// Optional: Display initial message
lcd.setCursor(0, 0);
lcd.print("Voice Beat Viz");
delay(2000);
}
void loop() {
// Beat detection
unsigned long startMillis = millis();
int signalMax = 0;
int signalMin = 1024;
// Collect samples over the window
while (millis() - startMillis < sampleWindow) {
int sample = analogRead(audioPin);
if (sample < 1024) {
if (sample > signalMax) signalMax = sample;
if (sample < signalMin) signalMin = sample;
}
}
int peakToPeak = signalMax - signalMin;
// Detect beat if above threshold and cooldown passed
if (peakToPeak > threshold && millis() - lastBeatTime > beatCooldown) {
beatDetected = true;
lastBeatTime = millis();
} else {
beatDetected = false;
}
// Clear LCD
lcd.clear();
// Display waveform with beat reaction
for (int col = 0; col < numColumns; col++) {
// Base wave (sine-like)
float angle = (col + waveOffset) * (2 * PI / numColumns);
int baseHeight = (sin(angle) + 1) * 0.5; // 0-1 range
// Boost height on beat
int height = baseHeight;
if (beatDetected) {
height = min(1, height + 0.5); // Pulse up on beat
}
// Display on LCD (using blocks for simplicity)
for (int row = 0; row < 2; row++) {
lcd.setCursor(col, row);
if (height >= (row + 0.5)) { // Threshold for each row
lcd.write(255); // Block
} else {
lcd.write(' '); // Space
}
}
}
// Update offset for scrolling
waveOffset = (waveOffset + 1) % numColumns;
// Animation delay
delay(50);
}