Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SPI.h>
- #include <SD.h>
- #include <TMRpcm.h>
- #include <LowPower.h>
- TMRpcm audio;
- #define SD_CS 4
- #define AUDIO_PIN 9
- #define TILT_PIN 2
- const uint8_t totalFiles = 29;
- // Counters
- uint8_t pressCount = 0;
- unsigned long lastPress = 0;
- // Timers
- unsigned long lastActivity = 0;
- const unsigned long sleepDelay = 10000;
- const unsigned long timeoutReset = 10000;
- // Debounce
- uint8_t lastState = 0;
- unsigned long lastDebounce = 0;
- const unsigned long debounceDelay = 40;
- bool shakePlaying = false;
- bool lockInput = false;
- void wakeUp() {}
- // ----------------------------
- // STABILNI SD + SPI RESET
- // ----------------------------
- void resetSDandAudio() {
- // Stop audio fully
- audio.stopPlayback();
- audio.disable();
- delay(5);
- // Reset SPI bus
- SPI.end();
- delay(5);
- SPI.begin();
- delay(5);
- // Reinitialize SD CS
- pinMode(SD_CS, OUTPUT);
- digitalWrite(SD_CS, HIGH);
- delay(10);
- // Re-init SD card
- if (!SD.begin(SD_CS)) {
- Serial.println("[ERR] SD failed, retry...");
- delay(50);
- if (!SD.begin(SD_CS)) {
- Serial.println("[FATAL] SD permanently failed");
- return;
- }
- }
- // Restart audio system
- audio.speakerPin = AUDIO_PIN;
- audio.setVolume(5);
- Serial.println("[SD] Recovered");
- }
- void setup() {
- Serial.begin(9600);
- delay(300);
- pinMode(TILT_PIN, INPUT);
- audio.speakerPin = AUDIO_PIN;
- audio.setVolume(5);
- Serial.println("=== START ===");
- resetSDandAudio(); // use the stable init
- if (!SD.exists("SHAKE.WAV")) {
- Serial.println("[ERR] Missing SHAKE.WAV at startup!");
- }
- lastActivity = millis();
- }
- void loop() {
- // ==== SLEEP MODE ====
- if (millis() - lastActivity > sleepDelay) {
- Serial.println("[SLEEP] Entering sleep");
- audio.stopPlayback();
- shakePlaying = false;
- lockInput = false;
- delay(20);
- attachInterrupt(digitalPinToInterrupt(TILT_PIN), wakeUp, CHANGE);
- Serial.end();
- delay(5);
- LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
- detachInterrupt(digitalPinToInterrupt(TILT_PIN));
- // Clear serial garbage
- Serial.begin(9600);
- delay(20);
- Serial.println("[WAKE]");
- resetSDandAudio(); // <--- FIXES YOUR WAKE SD ERRORS
- pressCount = 0;
- lastActivity = millis();
- lastPress = millis();
- }
- // ==== READ TILT ====
- uint8_t reading = digitalRead(TILT_PIN);
- if (reading != lastState) {
- if (millis() - lastDebounce > debounceDelay) {
- lastState = reading;
- if (reading == HIGH) {
- handleTilt();
- }
- }
- lastDebounce = millis();
- }
- // ==== CHECK AUDIO FINISH ====
- if (!audio.isPlaying()) {
- if (shakePlaying) {
- shakePlaying = false;
- Serial.println("[INFO] Shake done");
- }
- if (lockInput) {
- lockInput = false;
- Serial.println("[INFO] Random audio ended, input unlocked");
- }
- }
- }
- void handleTilt() {
- if (lockInput) {
- Serial.println("[LOCK] Ignored tilt during random playback");
- return;
- }
- unsigned long now = millis();
- lastActivity = now;
- if (now - lastPress > timeoutReset) {
- pressCount = 0;
- Serial.println("[RESET] Timeout");
- }
- pressCount++;
- lastPress = now;
- Serial.print("[TILT] Count ");
- Serial.println(pressCount);
- // 1–6 → SHAKE
- if (pressCount >= 1 && pressCount <= 6) {
- if (!audio.isPlaying()) {
- shakePlaying = true;
- playFile("SHAKE.WAV");
- }
- return;
- }
- // 7 → stop shake
- if (pressCount == 7) {
- audio.stopPlayback();
- shakePlaying = false;
- Serial.println("[STOP] Shake stopped");
- return;
- }
- // 8 → random
- if (pressCount == 8) {
- pressCount = 0;
- playRandom();
- }
- }
- void playFile(const char *name) {
- if (!SD.exists(name)) {
- Serial.print("[ERR] Missing ");
- Serial.println(name);
- return;
- }
- audio.stopPlayback();
- delay(5);
- audio.play(name);
- Serial.print("[PLAY] ");
- Serial.println(name);
- }
- void playRandom() {
- lockInput = true;
- char buf[8];
- uint8_t r = random(1, totalFiles + 1);
- sprintf(buf, "%d.WAV", r);
- playFile(buf);
- }
Advertisement
Add Comment
Please, Sign In to add comment