Go Down

Topic: SpeakJet /TTS Serial Question (Read 9470 times) previous topic - next topic

MobileWill

I have searched and can't figure this out

I have a basic sketch for reading from the serial port and sending it to the TTS chip which sends to the speakjet. I am using the sparkfun voice shield with the TTS chip in the proto area.

Problem is I can't send commands from serial. It works if I do a println but not from the serial.

For example speakjet.println("Test\375"); that works but if i type Test\375 from the serial monitor it speaks the \ 3 7 5.  (375 is the code for 253 for gunshot sound per example in http://www.sparkfun.com/datasheets/Components/General/TTS256_Datasheet_prelim.pdf

It doesn't read the escape character correctly.

Below is my code. This is based on the Sparkfun example, I removed my LCD code.

Code: [Select]
/*
Testing Sketch for Robot
*/

//Soft serial library used to send serial commands on pin 2 instead of regular serial pin.
#include <SoftwareSerial.h>

//Define the Pin Numbers of the Voicebox shield for the sketch.
#define E0  5
#define E1  6
#define E2  7
#define E3  8
#define E4  9
#define E5  10
#define E6  11
#define E7  12

#define RDY  13
#define RES  3
#define SPK  4

//Pin 2 of the shield should be wired to the TTS256 chip.
#define txPin  2

//Create a SoftSerial Object to send strings to the TTS256 chip.
SoftwareSerial speakjet = SoftwareSerial(0, txPin);

//Create a message buffer to hold the ascii message to be converted to sound
char message[128]="";

void setup()  
{
 //Configure the pins for the SpeakJet module
 pinMode(txPin, OUTPUT);
 pinMode(SPK, INPUT);
 
 //Set up a serial port to talk from Arduino to the SpeakJet module on pin 3.
 speakjet.begin(9600);    
 
 //Set up a serial port to get the ascii message from the host
 Serial.begin(9600);
 
 //Configure the Ready pin as an input
 pinMode(RDY, INPUT);
 
 //Configure Reset line as an output
 pinMode(RES, OUTPUT);
     
 //Configure all of the Event pins as outputs from Arduino, and set them Low.
 for(int i=E0; i<=E7; i++)
 {
   pinMode(i, OUTPUT);
   digitalWrite(i, LOW);
 }
 
 //All I/O pins are configured. Reset the SpeakJet module
 digitalWrite(RES, LOW);
 delay(100);
 digitalWrite(RES, HIGH);
 delay(1000);
 char sounds[] = {200, 201, 202, 203, 220, 221, 222};
 speakjet.println(sounds);
 //speakjet.println("Test\375"); // This works for sending commands inline
 
}

void loop()
{  
 //Get a message from the serial port
 getMessage(message);
 
 //Send the message to the TTS256
 speakjet.println(message);
 Serial.println(message);
 print(message);
 print(" ");
 
 
 //Wait 12ms before checking the ready line (specified in TTS256 datasheet)
 delay(12);
 //Wait for the Speakjet to become 'ready' before sending more text.
 while(digitalRead(RDY)==0);
}

//Function: getMessage(char *)
//Description: Retrieves a string from the Serial port. Doesn't return the string until a carriage return character is detected.
//Inputs: None
//Outputs: char * message - The message received on the serial port.
//Returns: Nothing
//usage: getMessage(english_sentance);
void getMessage(char * message)
{
   char in_char=0;    //Create a character to store the incoming byte from the serial port.
   //Wait for a character to come into the serial port
   while(Serial.available() <=0);
   //Copy the incoming character to our variable.
   in_char=Serial.read();
   //Keep retreiving characters until the 'end of sentance(0x0D)' character is received.
   while(in_char != 0x0D){
       *message++=in_char;    //Every time we receive a character we should add the character to the message string.
       while(Serial.available() <=0);    //Now wait for the next character...
       in_char = Serial.read();            //and copy it to the variable again.
   }
  *message='\0';    //Strings must end with a Null terminator so we need to add this to our message.
   return;
}



Thanks.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

Quote
For example speakjet.println("Test\375"); that works but if i type Test\375 from the serial monitor it speaks the \ 3 7 5.

When the compiler runs, it sees the \375 in the string, and substitutes a different value. The string that is passed to the speakjet.println function does not contain a \ and the characters 3, 7, and 5.

In your code to read from the serial port, you need to make that same substitution. The value following the \ is an octal value.

375 base 8 is 253 base 10.

MobileWill

#2
Jan 23, 2011, 07:21 pm Last Edit: Jan 23, 2011, 07:24 pm by wgarrido Reason: 1
I had tried that as well as other codes it still just speaks it instead of the making the sound for the code. Any more ideas?
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

Quote
I had tried that as well as other codes it still just speaks it instead of the making the sound for the code. Any more ideas?

Where is the code that converts \375 to 253 for sending to the speaker chip?

MobileWill

That happens on the TTS per the linked documentation above. Either way if I type in the actually code it doesn't work. The TTS has to read that and send it to the speakjet as a code.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

ASCII code 253 (375 in base 8) does not correspond to a key you can type, like A, f, 5, or @. So, you have to define the code as \375, which is not the same as '\', '3', '7', '5'.

When the Arduino reads '\', '3', '7', and '5' from the serial port, it needs to see that as an escape sequence, and print something different to the speaker chip.

You keep saying "yeah, I know that", but you have not shown any code that understands that \ is the start of an escape sequence, rather than just another character.

Do you have such code that you are unwilling to share, or do you not understand that YOU have to write such code?

MobileWill

#6
Jan 23, 2011, 08:49 pm Last Edit: Jan 23, 2011, 08:49 pm by wgarrido Reason: 1
I guess I am not understanding correctly. So I have to parse the array and look for \ and interpret it that? I thought the TTS would take care of that since the direct println works.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

Quote
I thought the TTS would take care of that since the direct println works.

No, the compiler does the parsing when storing the data in memory. You need to do the parsing in your code for the serial input.

MobileWill

Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

Quote
What would I convert it to?

Probably from octal to decimal, and use the speaker.write() function (hopefully there is one) to send the decimal value.

See if there is a write() function. If there is, try writing 253 to the chip, in setup() or loop(), to see that it processes the value correctly.

MobileWill

#10
Jan 24, 2011, 03:02 am Last Edit: Jan 24, 2011, 03:03 am by wgarrido Reason: 1
Looks like write() isn't available in the software serial. Any other ideas?

I am using a Mega2560 so I could try and reroute the TTS RX to the one of the real Serial ports. Only want to do that if that will solve my problem though.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

Does the speakjet class derive from Serial or Print? Does the print() method support optional 2nd arguments, like Serial.print() does? If so, speakjet.print(val, BYTE); could be used.

MobileWill

#12
Jan 24, 2011, 03:50 am Last Edit: Jan 24, 2011, 03:51 am by wgarrido Reason: 1
Thanks that might work.

On a side note I haven't done C++ in so long I am having a hard time reading though the array to search for \ (hex 0x5C).

After the getmessage routine get the all the characters I cycle through it again to look for it. But doesn't seem to work. The way the char array is setup can you use message
  • to search each position?

    Thanks
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

I tested using BYTE and that will work if I can separate out the '\200' from the message.

Thanks.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

I am going to try to separate out the code while they they being read from serial.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

Go Up