diff --git a/HAL-9000/hal9000.ino b/HAL-9000/hal9000.ino new file mode 100644 index 00000000..b7d7f838 --- /dev/null +++ b/HAL-9000/hal9000.ino @@ -0,0 +1,98 @@ +// Random HAL demo; adapted from PiSpeak sketch. When button +// on A0 is pressed, plays a random WAV file from a list. + +#include +#include + +// REPLACE THESE WITH YOUR ACTUAL WAVE FILE NAMES: +// These should be at the root level, not in a folder. +static const char PROGMEM + file00[] = "0.wav", + file01[] = "1.wav", + file02[] = "2.wav", + file03[] = "3.wav", + file04[] = "4.wav", + file05[] = "5.wav", + file06[] = "6.wav", + file07[] = "7.wav", + file08[] = "8.wav", + file09[] = "9.wav"; +// If adding files above, include corresponding items here: +static const char * const filename[] PROGMEM = { + file00, file01, file02, file03, file04, + file05, file06, file07, file08, file09 }; +// Sorry for the sillyness, but this is how PROGMEM string +// arrays are handled. + +#define error(msg) error_P(PSTR(msg)) +SdReader card; +FatVolume vol; +FatReader root; +FatReader file; +WaveHC wave; +uint8_t debounce = 0, // Button debounce counter + prev = 255; // Index of last sound played + +void setup() { + Serial.begin(9600); + if(!card.init()) error("Card init. failed!"); + if(!vol.init(card)) error("No partition!"); + if(!root.openRoot(vol)) error("Couldn't open dir"); + // PgmPrintln("Files found:"); + // root.ls(); + + digitalWrite(A0, HIGH); // Enable pullup on button + randomSeed(analogRead(A1)); // Randomize first sound +} + +void loop() { + if(digitalRead(A0) == HIGH) { // Button not pressed + debounce = 0; // Reset debounce counter + return; // and nothing else + } + + if(++debounce >= 20) { // Debounced button press + uint8_t n; + char name[20]; + + do { // Choose a random file... + n = random(sizeof(filename) / sizeof(filename[0])); + } while(n == prev); // ...but don't repeat last one + + prev = n; // Save file # + debounce = 0; // Reset debounce counter + strcpy_P(name, (char *)pgm_read_word(&filename[n])); // PROGMEM->RAM + if(wave.isplaying) wave.stop(); // Stop WAV if playing + + if(!file.open(root, name)) { + PgmPrint("Couldn't open file "); + Serial.print(name); + return; + } + if(!wave.create(file)) { + PgmPrintln("Not a valid WAV"); + return; + } + + wave.play(); // Start playing + while(wave.isplaying); // Wait for completion + sdErrorCheck(); // Check for error during play + while(digitalRead(A0) == LOW); // Wait for button release + } +} + +void error_P(const char *str) { + PgmPrint("Error: "); + SerialPrint_P(str); + sdErrorCheck(); + for(;;); +} + +void sdErrorCheck(void) { + if(!card.errorCode()) return; + PgmPrint("\r\nSD I/O error: "); + Serial.print(card.errorCode(), HEX); + PgmPrint(", "); + Serial.println(card.errorData(), HEX); + for(;;); +}