Hello everyone. I am currently writing a program that reads data in chunks from an SD Card that then puts that data into a temporary buffer and then sends the buffer data to an MP3 decoder IC (VS1033d.) I have written the portion of the program that reads from the SD Card and outputs the data. However, I am not getting the results that I expect and at best only get a pattern of clicking from my speaker when data is actually being sent.
At this point I have rewired my circuit to make it easier to work with and really I just want to verify that I can even read and write data from the registers on the IC, namely via the SCI bus. I would like to give it a value for volume and then verify the write by reading that register from the IC and getting a return value equal to what I wrote it to.
The next post is what I have for code. I would like to modify SCI_LISTEN() to allow me to read what the VS1033d is sending back out for a result.
void MP3VOL(byte left, byte right)
{
digitalWrite(SCI_xCS,LOW);
SENDTOSCI(SCI_WRITE); // WRITE INSTRUCTION
SENDTOSCI(VOL); // VOLUME ADDRESS
SENDTOSCI(left); // LEFT VOLUME
SENDTOSCI(right); // RIGHT VOLUME
digitalWrite(SCI_xCS,HIGH);
}
void MP3SCI_COMMAND(byte instruction, byte whatregister, byte MSBbyte, byte LSBbyte)
{
// Supports both WRITE and READ commands based on which one is passed to this function.
digitalWrite(SCI_xCS,LOW);
SENDTOSCI(instruction);
SENDTOSCI(whatregister);
if (instruction == SCI_WRITE)
{
SENDTOSCI(MSBbyte);
SENDTOSCI(LSBbyte);
}
if (instruction == SCI_READ)
{
ReceivedMSB = LISTENTOSCI();
ReceivedLSB = LISTENTOSCI();
}
digitalWrite(SCI_xCS,HIGH);
}
void DisplayVolume()
{
MP3SCI_COMMAND(SCI_READ, VOL, 0, 0);
}
void loop()
{
// ButtonsOnUserInterface();
Check4SerialCOMMANDS() ;
delay(10);
SD_READBYTES(); // Reads from the SD Card and places what is read into a temporary buffer array.
while(digitalRead(SDI_DREQ) != HIGH){ Check4SerialCOMMANDS(); } // Wait until SDI_DREQ is HIGH.
MP3_SENDDATA(); // Send data from the temporary buffer array into the MP3 player.
}
void MP3_SENDDATA()
{
int index = 0 ; // Reset the DataBuffer index placeholder to 0.
digitalWrite(SDI_xDCS, LOW); // Activate (Chip Select is active low)
for (index = 0 ; index <= buffersize ; index++) // Set up a for loop to read the data from DataBuffer.
{ SENDTOSDI(DataBuffer[index]); } // Send the data from the buffer to the mp3
digitalWrite(SDI_xDCS, HIGH); // Deactivate (Chip Select is active low)
}
void SENDTOSDI(byte ThisBYTE) // SERIAL DATA INTERFACE
{
for(int ThisBIT = 1; ThisBIT <= 8; ThisBIT++) // Now, "bit-bang" out the data and clock it out
{
if (ThisBYTE > 127) { digitalWrite (MP3TO, HIGH) ; } // If the MSB is a 1 then set MOSI high
else { digitalWrite (MP3TO, LOW) ; } // If the MSB is a 0 then set MOSI low
digitalWrite (MP3CLK,HIGH) ; // Pulse the clock pin high
ThisBYTE = ThisBYTE << 1 ; // Bit-shift the working byte
digitalWrite(MP3CLK,LOW) ; // Pulse the clock pin low
}
}
void SENDTOSCI(byte ThisBYTE) // SERIAL CONTROL INTERFACE
{
for(int ThisBIT = 1; ThisBIT <= 8; ThisBIT++) // Now, "bit-bang" out the data and clock it out
{
if (ThisBYTE > 127) { digitalWrite (MP3TO, HIGH) ; } // If the MSB is a 1 then set MOSI high
else { digitalWrite (MP3TO, LOW) ; } // If the MSB is a 0 then set MOSI low
digitalWrite (MP3CLK,HIGH) ; // Pulse the clock pin high
ThisBYTE = ThisBYTE << 1 ; // Bit-shift the working byte
digitalWrite(MP3CLK,LOW) ; // Pulse the clock pin low
}
}
byte LISTENTOSCI() // LISTEN TO SERIAL DATA INTERFACE RESPONSE BYTES
{
byte tempin = B00000000;
byte results = B00000000;
for(int ThisBIT = 1; ThisBIT <= 8; ThisBIT++) //
{
digitalWrite (MP3CLK,HIGH) ; delay(2); // Pulse the clock pin high
digitalWrite(MP3CLK,LOW) ; delay(2); // Pulse the clock pin low
tempin = digitalRead(MP3FROM) ;
if (tempin == HIGH) { results = results << 1 ; } //
else { results = results << 0 ; } //
}
return results ;
}
void OUTPUTDATABUFFER()
{
for (int pos = 0 ; pos <= buffersize; pos++)
{Serial.println(DataBuffer[pos]);}
}
void SD_READBYTES()
{
delay(10);
File datafile = SD.open("1.wav") ; // Open a file from the SD Card
if (datafile) // If the file was successfully opened (It would have returned a TRUE.)
{
filesize = datafile.size(); // Find out how big the file is
Serial.print("* SD READ: ") ;
Serial.print(CurrentFilePosition); Serial.print("-"); Serial.print(CurrentFilePosition+buffersize);
Serial.print(" of "); Serial.print(filesize); Serial.print(" ");
// Read bytes. Data Buffer position values are reset each time THIS function runs.
for (DataBufferPOS = 0 ; DataBufferPOS <= buffersize; DataBufferPOS++)
{
if (CurrentFilePosition >= filesize) {CurrentFilePosition=0; break;}
datafile.seek(CurrentFilePosition); // Seek to a position in the file.
DataBuffer[DataBufferPOS] = datafile.peek() ; // Read the current file position's data into the DATABUFFER
Serial.write(datafile.peek() ); // Read the current file position's data to SERIAL
CurrentFilePosition++ ;
if (CurrentFilePosition == filesize) {CurrentFilePosition = 0;}
}
// These 32 bytes have been read.
datafile.close() ; // Close the open file.
Serial.print(" ");
Serial.println("* SD READ: End of read.") ;
return ; // Exit this function
}
else // If the file was NOT successfully opened.
{ // Report to the operator the ERROR condition
Serial.println("ERROR: File could not be opened!! Reinitializing...");
INITSDCARD() ;
}
}
THANKS EVERYONE SO MUCH FOR LOOKING AT THIS... These were my first posts.
Thanks, AWOL, I've implemented that fix. So, sometimes I throw in the proverbial kitchen sink when I ask questions. Let me clarify. I would like to accomplish SPI both in AND out bound but not via the hardware SPI built into the Arduino. This is because I'm dedicating that to the SD Card reader. Also, I am having trouble with the VS1033d MP3 decoder IC that I bought from Sparkfun. I've updated the code above a bit.
Actually, there was no "bang" but I may have been accidentally supplying the VC1033d with the wrong voltage (5 instead of 2.7.) The circuit was rewired recently for neatness and I used the main ground instead of the "ground" from the LM317 adjustable regulator that I am using. Hopefully everything lives. (I did purchase an extra VS1033d just incase though! ;))
Wow, seems I mis-titled this thread. I meant to say "Bit-Bang".
I would like to see some good example code of manually performing SPI reads and writes without using the built in hardware/library. The VS1033d uses SPI Mode 0 and I would like to replicate that version in code.