Sketch for making audio sound module work

hey guys,

Can you guys take a look at the sketch I wrote for the arduino + sparkfun's audio sound module(http://www.sparkfun.com/products/9534
)? Basically since the module plays files named 0x0001 to 0x0500, I am making a sketch that takes 3 numbers that tell the module which file to play. First I concatenate those 3 numbers as decimals since 0's on the left can be ignored once I convert to hex. Then I sprintf it hex. I'm not quite sure if my syntax is right or if this is the right approach. I based my code largely off
http://yapan.googlecode.com/svn/trunk/arduino/examples/SOMO_14D_Test/SOMO_14D_Test.pde

int total=0;
char buf[8]={0};
const int clockPin = 2;  // the pin number of the clock pin
const int dataPin = 3;  // the pin number of the data pin
const int busyPin = 4;  // the pin number of the busy pin
const int resetPin = 5;  // the pin number of the reset pin


const unsigned int VOLUME_7 = 0xFFF7;
const unsigned int STOP = 0xFFFF;

void setup(){

 Serial.begin(9600);
	pinMode(clockPin, OUTPUT);
  	pinMode(dataPin, OUTPUT);
        pinMode(busyPin, INPUT);
  	pinMode(resetPin, OUTPUT);
        digitalWrite(clockPin, HIGH);
  	digitalWrite(dataPin, LOW);
// reset the module
        digitalWrite(resetPin, HIGH);
        delay(100);
        digitalWrite(resetPin, LOW);
        delay(10);
        digitalWrite(resetPin, HIGH);
        delay(100);

  sendCommand(VOLUME_7);

}

void loop(){
if (Serial.available() > 0) {
    int moveServo = Serial.read();
    Serial.flush();
 
     if (moveServo =='a'){
		//audio begins, stop haros movement and start looping    
		myservo.write(94);
		//get first 3 bit of incoming data 001-500 for file name
		while(Serial.available()<3){
		}
		for(int i=0;i<3;i++){
			//gets decimal concat, ignores 0’s on left
			total=total*10+Serial.read();
		}
                sprintf(buf,%X",total)
		sendCommand(buf);
		delay(1000);
		
		
       }


}
void sendCommand(unsigned int command) {
  // start bit
  digitalWrite(clockPin, LOW);
  delay(2);

  // bit15, bit14, ... bit0
  for (unsigned int mask = 0x8000; mask > 0; mask >>= 1) {
    if (command & mask) {
      digitalWrite(dataPin, HIGH);
    }
    else {
      digitalWrite(dataPin, LOW);
    }
    // clock low
    digitalWrite(clockPin, LOW);
    delayMicroseconds(200);

    // clock high
    digitalWrite(clockPin, HIGH);
    delayMicroseconds(200);
  }
  // stop bit
  delay(2);
}

thanks for the help

    int moveServo = Serial.read();
    Serial.flush();

Read one byte and flush the rest. Why?

		//get first 3 bit of incoming data 001-500 for file name
		while(Serial.available()<3){
		}

Now sit around doing nothing waiting for 3 more bytes. Makes sense having flushed the buffer. Flushing the buffer still doesn't, though.

Basically since the module plays files named 0x0001 to 0x0500, I am making a sketch that takes 3 numbers that tell the module which file to play.

0x500 = 1280. So, why are you limiting the range of files to 0x3E7?

                sprintf(buf,%X",total)

Oh, yeah. I'm sure the compiler was happy with that. Missing quotes and semicolons, oh my.

i just want to get the first incoming byte of data so later on if the user enters 'a', I can read the only 3 bytes off the serial. I don't quite get what you saw was problematic there sorry.

For the 3 incoming bytes, say I received 4, then 1, then 2
my code concatenates this to become 412.
What I wanted to do was to take this 412 and make it into 0x412. I should be doing this I guess:

sprintf(text, "0x%X", total);
strtol(text,&total,10)		
sendCommand(total);

I wrote all this up for the algorithm and didn't have the hardware or software on hand to test.

i just want to get the first incoming byte of data so later on if the user enters 'a', I can read the only 3 bytes off the serial. I don't quite get what you saw was problematic there sorry.

What if the user enters a123, and expects you to read the a and the 123. You won't. You'll read the a, and flush the 123, then wait until the use enters the 123.

What I wanted to do was to take this 412 and make it into 0x412. I should be doing this I guess:

No. 412 != 0x412. Are you expecting the user to enter values like 3F6 to play a song?

so I moved the flush to after, though honestly I was writing the code thinking that I would have the "user" input an a and then send the other stuff after a delay. But your way makes much more sense.

As for the hex, yes I realize that they don't equate in that way. I was trying to achieve the following:

-the user enters a400
-arduino gets 400 and gets it as a text "0x400"
-strtol to a real hex

seem right? Attached is the corrected code

int total=0;
char text[6];
const int clockPin = 2;  // the pin number of the clock pin
const int dataPin = 3;  // the pin number of the data pin
const int busyPin = 4;  // the pin number of the busy pin
const int resetPin = 5;  // the pin number of the reset pin


const unsigned int VOLUME_7 = 0xFFF7;
const unsigned int STOP = 0xFFFF;

void setup(){

 Serial.begin(9600);
	pinMode(clockPin, OUTPUT);
  	pinMode(dataPin, OUTPUT);
        pinMode(busyPin, INPUT);
  	pinMode(resetPin, OUTPUT);
        digitalWrite(clockPin, HIGH);
  	digitalWrite(dataPin, LOW);
// reset the module
        digitalWrite(resetPin, HIGH);
        delay(100);
        digitalWrite(resetPin, LOW);
        delay(10);
        digitalWrite(resetPin, HIGH);
        delay(100);

  sendCommand(VOLUME_7);

}

void loop(){
if (Serial.available() > 0) {
    int moveServo = Serial.read();
 
     if (moveServo =='a'){
		//audio begins, stop haros movement and start looping    
		myservo.write(94);
		//get first 3 bit of incoming data 001-500 for file name
		while(Serial.available()<3){
		}
		for(int i=0;i<3;i++){
			//gets decimal concat, ignores 0’s on left
			total=total*10+Serial.read();
		}
                sprintf(text, "0x%d", total);
                total=strtol(text,NULL,0);		
                sendCommand(total);
		delay(1000);
		
		
       }

    Serial.flush();

}
void sendCommand(unsigned int command) {
  // start bit
  digitalWrite(clockPin, LOW);
  delay(2);

  // bit15, bit14, ... bit0
  for (unsigned int mask = 0x8000; mask > 0; mask >>= 1) {
    if (command & mask) {
      digitalWrite(dataPin, HIGH);
    }
    else {
      digitalWrite(dataPin, LOW);
    }
    // clock low
    digitalWrite(clockPin, LOW);
    delayMicroseconds(200);

    // clock high
    digitalWrite(clockPin, HIGH);
    delayMicroseconds(200);
  }
  // stop bit
  delay(2);
}

so I moved the flush to after

Wrong. Get rid of it.

-the user enters a400

What does the user enter to get the previous song (# 0x3FF)?

You need to answer that question before a review of your code is meaningful.

is there a problem for having a flush there? say someone enters a342d, wouldn't the flush help to get rid of the d, which is irrelevant and useless?

as for previous songs. I don't have the need for calling those. The only thing that matters to me is the ability to call specific files.

is there a problem for having a flush there? say someone enters a342d, wouldn't the flush help to get rid of the d, which is irrelevant and useless?

How do you distinguish between a342a128a300, which means play three songs in order, and a324d, which means play one song and some invalid input, without looking at the input? Just dumping random amounts of serial data is NEVER the right answer, no matter what the question was.

as for previous songs. I don't have the need for calling those. The only thing that matters to me is the ability to call specific files.

When you decide to answer the question I am asking, I'll be more interested in helping you.

If the songs to be played are numbered 0x000 to 0x500, then playing 0x300 requires the user to enter either the 3,0,0 or 7,6,8, depending on whether the user is to enter hex digits or not.

To play the song before 0x300, that is song # 0x2FF, the user either needs to enter 2,F,F or 7,6,7

If the user is expected to enter JUST decimal digits, then one conversion process is required. If the user is expected to enter hex digits, then another conversion process is required.

We can't be expected to help you convert some input to a hex value without knowing what you expect the input to be.

I guess i wasn't clear enough. There is technically no user, as in a human being. Only a program will send inputs over, so invalid inputs will not happen unless I code my program erroneously. Also only decimals are entered, no hex, just like I've been doing in my examples. I have a database of what each file, so going by decimal is simplest.

I see your point on flush, and I realized that I never utilized the busy pin. So by adding the following I should fix some issues:

 sprintf(text, "0x%d", total);
                total=strtol(text,NULL,0);		
                sendCommand(total);
               int readPin= digitalRead(busyPin);
                while(readPin==HIGH){
		delay(1000);
                }

;

this way I can pile up a bunch of a342a128a300 and still be fine.

Only a program will send inputs over, so invalid inputs will not happen unless I code my program erroneously.

So, what will this mysterious program send to play the 254th song that the module knows (0xFE)?

That is the whole key.

the 254th song is 0x0253 in hex. The program will send 'a253'

the 254th song is 0x0253 in hex. The program will send 'a253'

And, therein lies the crux of the problem. The 254th song is NOT 0x0253. The 254th song is 0xFE.

I just realized that the function sendCommand can take decimals as well since hex and decimals make no difference....

so if i want to play the 254th song, which is 0xfe in hex, I don't even need to convert
just do sendCommand(253)

blindly following examples is not good...:frowning: