Toothless, ryta plysch marionett (3 / 7 steg)
Steg 3: Beteendemässiga Kodöversikt
Om ljussensor indata går över ett visst värde, sedan börjar MP3 spela
Om ljussensor indata går under ett visst värde, sedan stoppas MP3
Medan du spelar MP3 omvandlas ljussensor indata till en decibelnivån för MP3, där mer ljus är lika med starkare ljud
Dessutom indatavärden ljussensorn kontroller LED inuti huvudloop och MP3 loop
Som den ljussensor input ökar, den röda LED ökar och den blå lampan minskar
Här är koden som används:
< code >
#include < SPI.h >
#include < SdFat.h >
#include < SdFatUtil.h >
#define sant 1
#define falska 0
Sd2Card kort;
SdVolume volym;
SdFile rot.
SdFile spår;
MP3 spelare sköld pin mappning. Se schematiskt
#define MP3_XCS 6 //Control Chip Välj Pin (för åtkomst till SPI kontroll/Status register)
#define MP3_XDCS 7 //Data Chip Select / BSYNC Pin
#define MP3_DREQ 2 //Data begär Pin: spelare frågar för mer uppgifter
#define MP3_RESET 8 //Reset är aktiv låg
Kom ihåg att du måste redigera Sd2PinMap.h sdfatlib biblioteket för att korrigera kontroll SD-kortet.
VS10xx SCI register
#define SCI_MODE 0x00
#define SCI_STATUS 0x01
#define SCI_BASS 0x02
#define SCI_CLOCKF 0x03
#define SCI_DECODE_TIME 0x04
#define SCI_AUDATA 0x05
#define SCI_WRAM 0x06
#define SCI_WRAMADDR 0x07
#define SCI_HDAT0 0x08
#define SCI_HDAT1 0x09
#define SCI_AIADDR 0x0A
#define SCI_VOL 0x0B
#define SCI_AICTRL0 0x0C
#define SCI_AICTRL1 0x0D
#define SCI_AICTRL2 0x0E
#define SCI_AICTRL3 0x0F
Detta är namnet på filen på microSD-kortet du vill spela
Sticka med normala 8.3 nomeclature. Alla gemena fungerar bra.
Obs: du måste namnge spår på SD-kort med 001, 002, 003, etc.
Till exempel räknar koden med att spela "track002.mp3", inte track2.mp3.
char trackName [] = "sound.mp3";
int spårets nummer = 1;
int previousTrigger = 1; Detta indikerar att vi redan har utlöst på 1
char errorMsg [100]. Detta är en generisk array används för sprintf av felmeddelanden
int inputPin = A0;
int inputValue = 0;
int blueOutputValue = 0;
int blueOutputLED = 5;
int redOutputValue = 0;
int redOutputLED = 10;
int outputVolume = 0;
lång lastCheck; Här lagras den sista millisekunden eftersom vi hade en utlösare
int is_playing;
int time_since_play;
int checkTriggers(void) {
#define DEBOUNCE 100
int foundTrigger = 255;
En gång en utlösare är aktiverat, vill vi inte utlösa på den ständigt
Men efter 3 sekunder, återställa den tidigare trigger nummer
om ((previousTrigger! = 255) & & (millis() - lastCheck) > 3000) {
lastCheck = millis();
previousTrigger = 255;
Serial.println ("föregående utlösa återställning");
}
om (foundTrigger! = previousTrigger) {//We've fick en ny utlösare!
previousTrigger = foundTrigger;
Serial.Print("T");
Serial.println (foundTrigger, DEC);
Return(foundTrigger);
}
annat
Return(255); Ingen utlösare drog låga (aktiverad)
}
playMP3 - inkluderade funktionen från SparkFun exempel
void playMP3 (char * filnamn) {
om (! track.open (& rot, filnamn, O_READ)) {//Open filen i läs-läge.
sprintf (errorMsg, "Det gick inte att öppna %s", filnamnet);
Serial.println(errorMsg);
hemkomst.
}
sprintf (errorMsg, "Spela spår %s", filnamnet);
Serial.println(errorMsg);
uint8_t mp3DataBuffer [32]; Buffert för 32 byte. VS1053 kan ta 32 byte på en gång.
int need_data = sant;
While(1) {
While(!digitalRead(MP3_DREQ)) {
DREQ är låg medan mottagningsbufferten är full
Du kan göra något annat här, bufferten av MP3 är full och glad.
Kanske ställa in volymen eller testa för att se hur mycket vi kan dröja innan vi hör hörbara buggar
Om MP3 IC är nöjd, men vi behöver läsa nya data från SD, nu är en bra tid att göra det.
IF(need_data == true) {
om (! track.read (mp3DataBuffer, sizeof(mp3DataBuffer))) {//Try läsa 32 nya byte av låten
Åh nej! Det finns inga data kvar att läsa!
Dags att avsluta
bryta;
}
need_data = FALSE;
}
Kontrollera för att se om vi behöver borgen på detta spår
IF(checkTriggers()! = 255) {
Serial.println ("spännande MP3!");
Track.Close(); Nära denna låt!
previousTrigger = 255; Knep nästa checken att tro att vi inte har sett en tidigare utlösare
hemkomst.
}
}
IF(need_data == true) {//This är här ifall vi inte har haft någon tid att läsa in nya data
om (! track.read (mp3DataBuffer, sizeof(mp3DataBuffer))) {//Go ut till SD-kortet och försök läsa 32 nya byte av låten
Åh nej! Det finns inga data kvar att läsa!
Dags att avsluta
bryta;
}
need_data = FALSE;
}
När DREQ släpps (hög) mata vi nu 32 byte data till VS1053 från våra SD läsa buffert
digitalWrite (MP3_XDCS, låg); Markera Data
för (int y = 0; y < sizeof(mp3DataBuffer); y ++)
SPI.transfer(mp3DataBuffer[y]); Skicka SPI byte
digitalWrite (MP3_XDCS, hög); Avmarkera Data
need_data = sant; Vi har bara dumpade 32 byte i VS1053 så våra SD läsa buffert är tom. Ange flaggan så vi gå och hämta mer data
inputValue = analogRead(inputPin);
outputVolume = karta (inputValue, 0, 1023, 60, -20); <---det är där du gör det starkare/mjukare beroende på hur mycket ljus ingång din marionett blir
redOutputValue = karta (inputValue, 0, 1023, 0, 255);
blueOutputValue = karta (inputValue, 0, 1023, 255, 0);
Mp3SetVolume (outputVolume, outputVolume);
analogWrite (redOutputLED, redOutputValue);
analogWrite (blueOutputLED, blueOutputValue);
}
While(!digitalRead(MP3_DREQ)); Vänta på DREQ gå höga som indikerar överföringen är klar
digitalWrite (MP3_XDCS, hög); Avmarkera Data
Track.Close(); Stänga ute denna låt
sprintf (errorMsg, "Track %s gjort!", filnamnet);
Serial.println(errorMsg);
}
void setup()
{
pinMode (MP3_DREQ, indata);
pinMode (MP3_XCS, OUTPUT);
pinMode (MP3_XDCS, OUTPUT);
pinMode (MP3_RESET, OUTPUT);
digitalWrite (MP3_XCS, hög); Avmarkera kontroll
digitalWrite (MP3_XDCS, hög); Avmarkera Data
digitalWrite (MP3_RESET, låg); Sätta VS1053 i maskinvaruåterställning
pinMode (inputPin, ingång); förklara LDR som indata
pinMode (redOutputLED, produktionen); förklara ledPin som en utgång
pinMode (blueOutputLED, produktionen);
Serial.BEGIN(57600); Använda följetong för felsökning
Serial.println ("MP3 Player-exemplet med kontrollen");
Setup SD kortet interface
pinMode (10, OUTPUT); Stift 10 måste anges som en utgång för SD att arbeta.
om (! card.init(SPI_FULL_SPEED)) Serial.println ("fel: kort init"); Initiera SD-kortet och konfigurera I/O stift.
om (! volume.init (& kort)) Serial.println ("fel: volym ini"); Initiera en volym på SD-kortet.
om (! root.openRoot (& volym)) Serial.println ("fel: öppna root"); Öppna i rotkatalogen i volymen.
Vi behöver inte konfigurera SPI för VS1053 eftersom detta redan har gjorts av SDfatlib
Från sidan 12 i datablad är max SCI läser CLKI/7. Ingång klocka är 12.288 MHz.
Inre klocka multiplikator är 1.0 x efter makt upp.
Därför är SPI Maxfart 1,75 MHz. Vi använder 1MHz för att vara säker.
SPI.setClockDivider(SPI_CLOCK_DIV16); Som SPI busshastigheten till 1MHz (16MHz / 16 = 1 MHz)
SPI.transfer(0xFF); Kasta en dummy byte på bussen
Initiera VS1053 chip
Delay(10);
digitalWrite (MP3_RESET, hög); Ta upp VS1053
Mp3SetVolume (20, 20); Ange ursprungliga volymen (20 = - 10dB) LOUD
Mp3SetVolume (40, 40); Ange ursprungliga volymen (20 = - 10dB) Övervakningsbar
Mp3SetVolume (80, 80); Ange ursprungliga volymen (20 = - 10dB) mer tyst
Nu när vi har VS1053 upp och kör, öka den inre klocka multiplikatorn och upp vår SPI kurs
Mp3WriteRegister (SCI_CLOCKF, 0x60, 0x00); Ställ in multiplikatorn till 3,0 x
Från sidan 12 i datablad är max SCI läser CLKI/7. Ingång klocka är 12.288 MHz.
Inre klocka multiplikator är nu 3 x.
SPI Maxfart är därför 5 MHz. 4MHz kommer att vara säker.
SPI.setClockDivider(SPI_CLOCK_DIV4); Inställd 4MHz busshastighet SPI (16MHz / 4 = 4 MHz)
MP3 IC setup komplett
Serial.println ("gjort med setup");
}
void loop()
{
inputValue = analogRead(inputPin);
LED ögon bitar (behov tweaking av värden när den placeras i sista puppet)
redOutputValue = karta (inputValue, 0, 1023, 0, 255);
blueOutputValue = karta (inputValue, 0, 1023, 255, 0);
/ * om (inputValue > 50)
{
blueOutputValue = 0;
}
om (inputValue < 20)
{
redOutputValue = 0;
} */
om (inputValue > 600) //if mun är öppen nog
{
om (is_playing == 0)
{
playMP3(trackName);
is_playing = 1;
}
}
om (inputValue < 500) / / om munnen är stängd nog
{
Track.Close();
is_playing = 0;
}
Serial.Print(inputValue); att se om din ljussensor fungerar
Serial.Print("\n");
analogWrite (redOutputLED, redOutputValue);
analogWrite (blueOutputLED, blueOutputValue);
}
Skriva till VS10xx register - från SparkFun exempel
SCI: Dataöverföringar är alltid 16 bit. När en ny SCI operation kommer i
DREQ går låg. Vi måste vänta på DREQ till gå högt igen.
XCS bör vara låg under hela operationen.
void Mp3WriteRegister (unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte) {
While(!digitalRead(MP3_DREQ)); Vänta på DREQ gå höga som anger IC är tillgängliga
digitalWrite (MP3_XCS, låg); Markera kontrollen
SCI består av instruktion byte, adress byte och 16-bitars data word.
SPI.transfer(0x02); Skriv instruktioner
SPI.transfer(addressbyte);
SPI.transfer(highbyte);
SPI.transfer(lowbyte);
While(!digitalRead(MP3_DREQ)); Väntan för DREQ gå höga som anger kommandot är komplett
digitalWrite (MP3_XCS, hög); Avmarkera kontroll
}
Har ställt in VS10xx volym Register - ställa in funktionen från SparkFun exempel
void Mp3SetVolume (unsigned char leftchannel, unsigned char rightchannel) {
Mp3WriteRegister (SCI_VOL, leftchannel, rightchannel);
}
< / code >