Question on C code to change getc() to gets()?

25 Jun 2010 . Edited: 26 Jun 2010

Hi:

This code is to interface with a VMusic2 mp3 module from vinculum.  I may ask for more help at some point, but for now my challenge is related purely to C programming.

The code below works to allow me to enter a character from the keyboard into Tera Term.

It then processes that character according to one of three options (for now)

Each option outputs a specific command to the VMusic2 as indicated in the comments.

In main() I have a getc() which is reading back the response from the VMusic2 and it displays 1 character at a time on a new line for each character according to the \n\r that I know I have in the code.

What I like about the code is that I don't have to worry about how long the message is as the "while VMusic.readable() stays active until all the characters are read.

I think it would be better to use gets() to grab all the characters into a string in one shot instead of looping through each character individually.

I would appreciate some guidance on changing the getc() to gets() as when I tried to read the content into a string I had several compiler errors about the kinds of data types and not being able to mix them in several lines of code in that "sendcommand" module.

I would like to use the "best practices", but I'm stuck at the moment.  If someone can point to a good book that would help me understand the different types and what goes with what, I would really appreciate it.

Thanks

Tim

http://www.vinculum.com/documents/datasheets/DS_VMUSIC2.pdf

#include "mbed.h"

DigitalOut led1(LED1);            // used in main() as indicator
DigitalOut led2(LED2);            // not yet used
DigitalOut led3(LED3);            // not yet used
DigitalOut led4(LED4);            // not yet used
Serial pc (USBTX,USBRX);          // define serial connection to PC via mbed USB
Serial VMusic (p9, p10);          // define serial connection to VMusic2 module

DigitalOut cts(p8);               // set up output to hold clear to send low
int value;                        // variable to hold characters returned from VMusic2
int command = 0x00;               // just a declaration

//
int sendcommand(char command)     // this will process the key entered and trigger sending command
{                                 // to VMusic2 
   if (command == 'D')            // first letter for "D"ir
   {
      VMusic.printf("dir \r");    // sends directory command to VMusic2
   }
   else if (command == 'A')       // last letter from IPA input set to "A"scii
   {
      VMusic.printf("IPA \r");    // sends "input set to Ascii" to VMusic2
      pc.printf("Setting mode to ASCII input.\n\r ");  // prints status message on screen
   }
   else if (command == 'H')       // last letter from IPH input set to "H"ex
   {
      VMusic.printf("IPH \r");    // sends "input set to Hex" to VMusic2
      pc.printf("Setting mode to HEX input. \n\r");    // prints status message on screen
   }
   else
   { 
      pc.printf("Unsupported Command \n\r");  // handles key entry not in above specific list
   }
   return command;                // makes the compiler happy although I am not using it
}
int main() {
    pc.printf("Starting VMusic2: \n\r");     // just a message to the screen
    while(1) {
        led1 = 1;                            // just indicating that I am in while1 loop
        cts = 0;                             // VMusic2 uses hardware handshaking so this sets CTS
        command == ' ';                      // empty the variable for holding key entered
        pc.scanf( "%c", &command );          // sets input to Tera Term to read keyboard
        pc.printf("Character Entered: %X\n\r", command);  // prints HEX of key entered
        sendcommand(command);                // calls the module to act on key entered
        wait(.1);                            // arbitrary to give command some time
        while (VMusic.readable())            // watches for content in serial input buffer
        {
            value = VMusic.getc();           // copies serial input buffer to variable
            pc.printf("\rCharacter : %c\n\r",value);  // sends captured data to screen
        }  
        wait(0.2);                           // arbitrary left over from original default main()
        led1 = 0;                            // indicate end of main() commands
        wait(0.2);                           // arbitrary eft over from original default main()
    }
}

 

26 Jun 2010 . Edited: 26 Jun 2010

Tim,

I know nothing about VMusic but I think that there are some general ways to deal with this.

Send a command including all data required by it.

Try to read the response which should include timeout for each character.  gets () is not so useful since it will just "hang" if there is something wrong.

 

Timer serial_timeout;

static int readCharTimed ()
  {
    serial_timeout.reset ();
    while (!VMusic.readable ())
      {
        if (serial_timeout.read_ms () > MAX_DELAY_BETWEEN_CHARCTERS_IN_MS)
          {
            myled_1 = 1;
            return -1;
          }
      }
    return VMusic.getc ();
  }

On top of that you should probably parse the response so that you see where the end is if it is response dependent.

Anders

26 Jun 2010

Hi Anders

Thanks for the post.  I don't think I am understanding this or where it would go/what it would replace in my code.

I will have to study this for a bit.  How would I determine the MAX_DELAY_BETWEEN_CHARACTERS_IN_MS?

Thanks

Tim

26 Jun 2010 . Edited: 26 Jun 2010

Hi

I have added the code as I think it is intended to be.  I have moved my getc() into the code to capture the data.

The responses are as expected on entering keys in that if I enter a "A" I see the message indicating that it is being set to Ascii and "H" indicates that it is being set to Hex.

Unfortunately I do not see any of the responses from the VMusic device.  I do see the "character entered" reported from the scanf, but nothing else.

I think I am missing something in my understanding

Thanks

Tim

#include "mbed.h"

DigitalOut led1(LED1);            // used in main() as indicator
DigitalOut led2(LED2);            // not yet used
DigitalOut led3(LED3);            // not yet used
DigitalOut led4(LED4);            // not yet used
Serial pc (USBTX,USBRX);          // define serial connection to PC via mbed USB
Serial VMusic (p9, p10);          // define serial connection to VMusic2 module

DigitalOut cts(p8);               // set up output to hold clear to send low
int value;                        // variable to hold characters returned from VMusic2
int command = 0x00;               // just a declaration
Timer serial_timeout;
//
int sendcommand(char command)     // this will process the key entered and trigger sending command
{                                 // to VMusic2 
   if (command == 'D')            // first letter for "D"ir
   {
      VMusic.printf("dir \r");    // sends directory command to VMusic2
   }
   else if (command == 'A')       // last letter from IPA input set to "A"scii
   {
      VMusic.printf("IPA \r");    // sends "input set to Ascii" to VMusic2
      pc.printf("Setting mode to ASCII input.\n\r ");  // prints status message on screen
   }
   else if (command == 'H')       // last letter from IPH input set to "H"ex
   {
      VMusic.printf("IPH \r");    // sends "input set to Hex" to VMusic2
      pc.printf("Setting mode to HEX input. \n\r");    // prints status message on screen
   }
   else
   { 
      pc.printf("Unsupported Command \n\r");  // handles key entry not in above specific list
   }
   return command;                // makes the compiler happy although I am not using it
}
//
static int readCharTimed()
  {
    serial_timeout.reset ();
    while (!VMusic.readable ())
      {
        if (serial_timeout.read_ms () > 1000)  //max delay between characters in ms
          {
            value = VMusic.getc();             // copies serial input buffer to variable
            pc.printf("\rCharacter : %c\n",value);  // sends captured data to screen
            led1 = 1;
            return -1;
          }
      }
    return VMusic.getc ();
  }

int main() 
{
    cts = 0;                             // VMusic2 uses hardware handshaking so this sets CTS
    pc.printf("Starting VMusic2: \n\r");     // just a message to the screen
    while(1) 
    {
        command == ' ';                      // empty the variable for holding key entered
        pc.scanf( "%c", &command );          // sets input to Tera Term to read keyboard
        pc.printf("Character Entered: %X\n\r", command);  // prints HEX of key entered
        sendcommand(command);                // calls the module to act on key entered
        wait(.1);                            // arbitrary to give command some time
        readCharTimed();
    }
}

 

26 Jun 2010

I just noticed that you mention the VMusic2 device uses hardware handshaking. You initially set CTS to 0, but then you never drive the CTS after that (or the RTS at all). I wonder if this is preventing the device from responding?

26 Jun 2010

Hi Jon:

My wiring is based on a collection of information that I have pulled off the web.  I have written to the manufacturer, but have heard nothing back.  I actually want to talk to this device using SPI but felt the serial approach would be easier to get some initial experience with the device.

My initial code at the beginning of the post does work and the device responds with internal messages that I did not put in any code so I am certain that my hardware is ok.

If I send a command that it does not recognize, that code will return

Character: B
Character: a
Character: d
Character: 
Character: C
Character: o
Character: m
Character: m
Character: a
Character: n
Character: d
Character: 
as it loops through.the getc() and writes the characters into "value".

If I issue the "D" for dir, I get Windows Dir as the same vertical list of characters as above.

At some point I will be dealing with file names and other information such as artist, title, etc that are encoded in the mp3 data so I wanted to clean this code up so that it is not handing me one character at a time.  I had thought that gets() might do that but replacing getc() with gets() gave me compiler errors that I could not get around.

I am not well versed in C.  I have built all sorts of things with the Arduino, but moved to the mbed to get a more powerful environment and to improve my C knowledge.

Thanks

Tim