Matlåda att spelar utdrag ur "The Simpsons"
Min son är ett stort fan av The Simpsons (och jag antar, det är jag). Jag skapade detta som en gåva till honom i julklapp.
Vad vi har här är en Simpsons matlåda som, när växeln röd trycks, kommer att spela slumpmässigt en av 413 wav-filer som lagras på SD-kortet som används av Adafruit waveshield.
En video av det används följer.
De material som används är:
-Arduino UNO
-Adafruit Wave Shield Kit v1.1
-2GB SD-kort
-Simpsons lunchlåda - från Amazon.com
-2 9 volts batterier och 2 hållare - radio shack
-3 lysdioder
-en 8 ohms högtalare
-en DPDT switch
-ett par kondensatorer, resistorer och en LM386 chip för en liten förstärkare som ljudet av våg sköld inte är högt nog för högtalaren.
-några kablar
Jag använde också en SD-kortläsare och ett program som heter Switch-det för att dekomprimera wav-filer.
Så här:
1. köpte en Arduino Uno - många källor för detta - cirka $25.00
2. köpte en Adafruit Waveshield Kit - ca 22.00.
Detta måste monteras och instruktionerna här:
http://www.Ladyada.net/make/waveshield/make.html
(Dessa är lätt att följa instruktioner med många bra bilder)
3. köpte ett 2gb SD kort som ska användas i våg sköld
4. gjorde en sökning på internet för: "Simpsons wav" och hittade ett par platser som hade ganska bra samling av wav fil utdrag från Simpsons. Jag var (med hjälp av min son) Ladda ner över 400 filer och spara dem till SD-kortet.
-Obs wave skölden inte gillar komprimerade filer så några av de filer som behövs vara okomprimerade vilket jag gjorde med en freeware programvara som kallas "Switch-it".
5. eftersom ljudet våg skålens är OK för hörlurar men var inte högt nog för talaren, har jag skickat utdata från wave skölden till en liten LM386 amp att jag byggde med hjälp av följande instruktioner.
http://www.rason.org/projects/icamps/icamps.htm
6. Lade till lysdioder indikerar strömmen är på (sidoknappen) och indikerar när det är ok att be om en ny fil.
(Observera - jag lagt till en funktion som när man trycker ned den röda switchen när den gröna lysdioden blinkar, alla wave filer spelas)
7. några andra observationer:
-i princip koden väntar röda växeln vara intryckt.
Det genererar sedan en randow nummer beween 1 och 413 (antalet wave-filer). Sedan läser igenom wave-filer och ökar en räknare tills slumptal nås. Det spelar sedan filen. Detta innebär att antalet filer är svårt inkodat i koden. Förmodligen det finns något sätt att ha kod figurera ut hur många filer det finns.
-ibland det inte att spela upp en fil jag tror eftersom det också inte gillar stereo-filer.
8. koden:
-kopierat från olika källor och så som anges i koden. Specifikt, började jag med kod som är på Adafruit plats och ändras efter behov.
/*
tanken är att spela en slumpmässig wav-fil varje gång knappen är press
v2 nu försöker lägga till knappen och annan kod
v2 fungerar bra
v3 - lägga till möjligheten att spela alla låtar genom att hålla knappen ned under den blinkande
*/
#include
#include
SdReader kort; Detta objekt innehåller information för kortet
FatVolume vol; Detta innehåller information för partitionen på kortet
FatReader rot. Detta innehåller information för volymer rotmapp
WaveHC våg; Detta är enda våg (audio)-objektet, eftersom vi bara kommer att spela en i taget
uint8_t dirLevel; indrag för fil/dir namnen (prettyprinting)
dir_t dirBuf; buffert för katalog läsningar
#define DÄMPNINGSTID 5 / / knappen debouncer
CONST int buttonPin = 8; numrera av tryckknapp PIN-koden
int buttonState = 0; variabel för att läsa tryckknapp status
för rsndom spel
lång randNumber;
långa ct = 0;
behövs för att spela alla
int playAll = 0;
int numPress = 0; variabel för att läsa tryckknapp status
int xx = 0;
långa firstTime = 1;
behöver ändra detta lika numberr av wav-filer på sd-kort
lång numWavs = 413;
CONST int ledPin = 7. antal LED stift
Variabler som ändras:
int ledState = hög; ledState används för att ange LED
/*
* Definiera makro för att få felmeddelanden i flash-minne
*/
#define error(msg) error_P(PSTR(msg))
Fungerar definitioner (vi definierar dem här, men koden är nedan)
void spela (FatReader & dir);
Denna behändiga funktionen returnerar antalet byte för närvarande gratis i RAM, bra för felsökning!
int freeRam(void)
{
extern int __bss_end;
extern int * __brkval;
int free_memory;
om ((int) __brkval == 0) {
free_memory = ((int) & free_memory)-((int) & __bss_end);
}
annat {
free_memory = ((int) & free_memory)-((int) __brkval);
}
återvända free_memory;
}
//////////////////////////////////// SETUP
void setup() {
Serial.BEGIN(9600); Ställ in följetong bibliotek på 9600 bps för felsökning
om analog ingångsstift 0 är osammanhängande, slumpmässiga analog
buller gör anropet till randomSeed() att generera
olika utsäde nummer varje gång skissen körs.
randomSeed() kommer sedan shuffle funktionen random.
randomSeed(analogRead(3));
initiera tryckknapp PIN-koden som indata:
pinMode (buttonPin, ingång);
Ange den digitala pin:
pinMode (ledPin, produktionen);
digitalWrite(ledPin,HIGH);
putstring_nl ("\nWave test!"); säga vi vaknade!
putstring ("fri slå ned:"); Detta kan hjälpa till med felsökning, slut RAM är dålig
Serial.println(FreeRam());
om (! card.init()) {//play med 8 MHz spi (standard snabbare!)
fel ("kort init. misslyckades!"); Något gick fel, kan skriva ut varför
}
Aktivera optimera Läs - vissa kort kan timeout. Inaktivera om du har problem
card.partialBlockRead(true);
Nu söker vi en FAT-partition!
uint8_t del;
för (del = 0; del < 5; del ++) {/ / vi har upp till 5 platser att titta i
om (vol.init (kort, del))
bryta; Vi hittade en, låter borgen
}
om (del == 5) {/ / om vi slutade inte att hitta en :(
fel ("ingen giltig FAT-partition!"); Något gick fel, kan skriva ut varför
}
Kan tala om för användaren om vad vi hittade
putstring ("använda partition");
Serial.Print (del, DEC);
putstring (", typ är FAT");
Serial.println(Vol.fatType(), DEC); FAT16 eller FAT32?
Försök öppna rotkatalogen
om (! root.openRoot(vol)) {
fel kan inte ("öppna rotfästa dir!"); Något gick fel,
}
Usch! Vi fick tidigare de hårda delarna.
putstring_nl ("hittade filer (* = fragmenterad):");
Skriva ut alla filer i alla kataloger.
root.ls(LS_R | LS_FLAG_FRAGMENTED);
digitalWrite(ledPin,HIGH);
}
//////////////////////////////////// LOOP
void loop() {
kort slinga 3 sekunder för den första tiden endast
Om knappen nedtryckt mer än en gång, p [Lägg alla vågor
Serial.println (firstTime);
Delay(1000);
om (firstTime == 1) {
göra
{
digitalWrite(ledPin,HIGH);
Delay(250);
digitalWrite(ledPin,LOW);
Delay(250);
numPress = digitalRead(buttonPin);
om (numPress == hög) {
playAll ++;
firstTime ++;
}
xx ++;
Serial.println (xx);
} medan (xx < 10).
firstTime ++;
}
Serial.println (firstTime);
Serial.println (playAll);
Delay(1000);
Läs statligt av tryckknapp värdet:
buttonState = digitalRead(buttonPin);
digitalWrite(ledPin,HIGH);
Kontrollera om tryckknappen trycks.
om det är, är buttonState hög:
om (buttonState == hög) {
CT = 0;
spela en wav-fil dvs fortsätta med koden
digitalWrite(ledPin,LOW);
skriva ut ett slumpmässigt nummer från 1 till 60
randNumber = random (1, numWavs);
Serial.println(randNumber);
Delay(50);
root.Rewind();
Play(root);
}
annat {
gör ingenting
}
}
/////////////////////////////////// HELPERS
/*
* skriva ut felmeddelande och stoppa
*/
void error_P (const char * str) {
PgmPrint ("fel:");
SerialPrint_P(str);
sdErrorCheck();
While(1);
}
/*
* skriva ut felmeddelande och stoppa om SD i/o-fel, bra för felsökning!
*/
void sdErrorCheck(void) {
om (! card.errorCode()) återvända;
PgmPrint ("\r\nSD I/O fel:");
Serial.Print(Card.ErrorCode(), HEX);
PgmPrint (",");
Serial.println(Card.errorData(), HEX);
While(1);
}
/*
* spela rekursivt - möjligt stackspill om underkataloger för kapslade
*/
void spela (FatReader & dir) {
FatReader fil.
samtidigt (dir.readDir(dirBuf) > 0) {/ / läsa alla filer i katalogen en i taget
Hoppa över det om inte en underkatalog och inte en. WAV-fil
IF (!. DIR_IS_SUBDIR(dirBuf)
& & strncmp_P ((char *) & dirBuf.name[8], PSTR("WAV"), 3)) {
fortsätta;
}
Serial.println(); rensa ut en ny rad
för (uint8_t jag = 0; jag < dirLevel; i ++) {
Serial.write(' '); Detta är för prettyprinting, sätta utrymmen framför
}
om (! file.open (vol, dirBuf)) {/ / öppna filen i katalogen
fel ("file.open misslyckades"); något gick fel
}
om (file.isDir()) {/ / kolla om vi öppnade en ny katalog
putstring ("Subdir:");
printEntryName(dirBuf);
Serial.println();
dirLevel += 2. lägga till fler utrymmen
spela upp filer i underkatalog
Play(File); rekursiv!
dirLevel-= 2.
}
annat {
Aha! Vi hittade en fil som inte är en katalog
putstring ("villkor");
printEntryName(dirBuf); skriva ut den
om (! wave.create(file)) {/ / räkna ut, är det en ordentlig WAV?
putstring ("inte en giltig WAV"); OK hoppa över den
} annat {
Serial.println();
Hurra är det en ordentlig WAV!
CT ++;
Serial.println(randNumber);
Serial.println(CT);
här är där vi spela filen
men bara vill ha en wav-fil som är utvald av slumptal
om ((randNumber == ct) || (playAll > 1)) {
Wave.Play();
göra några ljud!
uint8_t n = 0;
samtidigt (wave.isplaying) {/ / spela förekommer i avbrott, så vi skriva ut prickar i realtid
putstring(".");
om (! () ++ n % 32))Serial.println();
Delay(100);
}
digitalWrite(ledPin,HIGH);
}
sdErrorCheck(); allt OK?
om (wave.errors)Serial.println(wave.errors); Wave avkodningsfel
}
}
}
}