serial control of mp3-module

Hi,

I am working on a little robot-project. The robot can open/close mouth and eyes. And I am trying to make him speak (rather spell single chars). My code splits a whole sentence into small parts and converts these parts to phonems (void GraphToPhon). I then play the corresponding mp3-file on a serial-connected mp3-module and move the mouth depending on if the phonem is a vowel or consonant.

All in all, my code works quite ok, but I've got a problem with the calling of the mp3-module. 90-95 % of the detected phonems are played, but every now and then (irregularily) the mp3-file is not played, although the phonem ist correctly converted and the mouth is moved.

It seems to be either a problem with the serial-calling of the module, or the module is over-worked (but to extend the delay between the calling does not help.)

MP3-module: http://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=168_170&products_id=625
datasheet: http://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=168_170&products_id=625

As i am not a C/C++ native speaker, i am not sure if i call the module the propper way, maybe you could check it for me.
(sorry, my code might be a bit blown-up)

Any other suggestions?

kind regards,
P

maybe you could check it for me.

You want us to come there to check your code? Have pizza and beer ready.

sorry, forgot the code... :zipper_mouth_face: ... oh ... code is too long. i shorten the mouth/eye-movement.

#include <SoftwareSerial.h>
#include <Servo.h>

#define rxPin 15 // actually, I am not using a rxPin
#define txPin 14
SoftwareSerial MP3Serial =  SoftwareSerial(rxPin, txPin); // SET UP SERIAL PORT

Servo ServoMouth;  // SERVOS
Servo ServoEyeLeft;
Servo ServoEyeRight;


//--------------- VARIABLES FOR MOVEMENT ----------------

int MouthOpen = 125;
int MouthClosed = 65;

int MouthOld;
int MouthNew;

int EyeLeftOpen = 120;
int EyeLeftClosed = 24;

int EyeRightOpen = 32;
int EyeRightClosed = 127;

int RandomNum = 6;
int Blinky = 0;


//------------------ VARIABLES FOR GRAPHEM TO PHONEM CONVERSION ---------
String URSATZ = "ach wie gut dass niemand weiß, dass ich rumpelstilzchen heiß!";
String SATZ = URSATZ;

String PHON;
int MINIMI;
int MP3;
int LENGTH;
int TIME;

void setup() {
  
  // SATZ = SATZ.toLowerCase(); //                                       UMLAUT PROBLEM ZU LÖSEN !  
  
  pinMode(txPin, OUTPUT);
  MP3Serial.begin(9600);

  ServoMouth.attach(2);
  ServoEyeLeft.attach(4);
  ServoEyeRight.attach(5);
  ServoMouth.write(MouthClosed);
  ServoEyeLeft.write(EyeLeftOpen);
  ServoEyeRight.write(EyeRightOpen); 
  delay (500);
  
}

void loop() {
  GraphToPhon(); // CONVERT GRAPHEM TO PHONEM

  PlayMP3(); // SPEAK
  
  delay(60); LENGTH = LENGTH-60; // DELAY FOR SPEECH & MOVEMENT SYNCRONISATION
  
  TIME = (LENGTH / 10) * 9;
  Move1(); // MOVEMENT 1 
  TIME = LENGTH / 10;
  Move2(); // MOVEMENT 2
  
}

void GraphToPhon() {
  
  String S3 = SATZ.substring(0,3);
  String S2 = SATZ.substring(0,2);
  char S1 = SATZ.charAt(0);
  
  MINIMI = 0;
  MP3 = 0;
  PHON = " ";
  
if(S3.equals("sch") == true) {MINIMI = 3; MP3 = 37; LENGTH = 400;} // PHON = "SCH"; 
if(S3.equals("rrh") == true) {MINIMI = 3; MP3 = 18; LENGTH = 330;} // PHON = "R"; 
if(S3.equals("cch") == true) {MINIMI = 3; MP3 = 11; LENGTH = 330;} // PHON = "K"; 
if(S3.equals("ail") == true) {MINIMI = 3; MP3 = 30; LENGTH = 400;} // PHON = "AI"; 
if(S3.equals("ieh") == true) {MINIMI = 3; MP3 = 9; LENGTH = 400;} // PHON = "I"; 
if(S3.equals("eau") == true) {MINIMI = 3; MP3 = 15; LENGTH = 400;} // PHON = "O"; 
if(S3.equals("chs") == true || S3.equals("cks") == true ) {MINIMI = 3; MP3 = 23; LENGTH = 40;} // PHON = "X"; 
if(S3.equals("äh") == true) {MINIMI = 3; MP3 = 25; LENGTH = 450;} // PHON = "AE"; 
if(S3.equals("öh") == true) {MINIMI = 3; MP3 = 26; LENGTH = 400;} // PHON = "OE"; 
if(S3.equals("üh") == true) {MINIMI = 3; MP3 = 27; LENGTH = 450;} // PHON = "UE"; 
if(S3.equals("äu") == true) {MINIMI = 3; MP3 = 34; LENGTH = 400;} // PHON = "OI"; 

if (MINIMI < 3) {
  if(S2.equals("tt") == true || S2.equals("th") == true || S2.equals("dt") == true) {MINIMI = 2; MP3 = 20; LENGTH = 330;} // PHON = "T"; 
  if(S2.equals("nn") == true) {MINIMI = 2; MP3 = 14; LENGTH = 335;} // PHON = "N"; 
  if(S2.equals("ss") == true || S2.equals("zz") == true || S2.equals("ß") == true) {MINIMI = 2; MP3 = 19; LENGTH = 400;} // PHON = "S"; 
  if(S2.equals("rr") == true || S2.equals("rh") == true) {MINIMI = 2; MP3 = 18; LENGTH = 330;} // PHON = "R"; 
  if(S2.equals("ll") == true) {MINIMI = 2; MP3 = 12; LENGTH = 330;} // PHON = "L"; 
  if(S2.equals("ff") == true || S2.equals("ph") == true) {MINIMI = 2; MP3 = 6; LENGTH = 380;} // PHON = "F"; 
  if(S2.equals("gg") == true || S2.equals("gh") == true) {MINIMI = 2; MP3 = 7; LENGTH = 330;} // PHON = "G"; 
  if(S2.equals("ck") == true || S2.equals("kk") == true) {MINIMI = 2; MP3 = 11; LENGTH = 330;} // PHON = "K"; 
  if(S2.equals("mm") == true) {MINIMI = 2; MP3 = 13; LENGTH = 330;} // PHON = "M"; 
  if(S2.equals("bb") == true) {MINIMI = 2; MP3 = 2; LENGTH = 330;} // PHON = "B"; 
  if(S2.equals("dd") == true) {MINIMI = 2; MP3 = 4; LENGTH = 330;} // PHON = "D"; 
  if(S2.equals("er") == true) {MINIMI = 2; MP3 = 28; LENGTH = 390;} // PHON = "ER"; 
  if(S2.equals("ts") == true || S2.equals("tz") == true || S2.equals("zz") == true) {MINIMI = 2; MP3 = 24; LENGTH = 330;} // PHON = "Z"; 
  if(S2.equals("aa") == true || S2.equals("ah") == true) {MINIMI = 2;  MP3 = 1; LENGTH = 350;}  // PHON = "A"; 
  if(S2.equals("pp") == true) {MINIMI = 2; MP3 = 16; LENGTH = 330;}  // PHON = "P"; 
  if(S2.equals("ei") == true) {MINIMI = 2; MP3 = 29; LENGTH = 450;}  // PHON = "EI"; 
  if(S2.equals("ai") == true) {MINIMI = 2; MP3 = 30; LENGTH = 450;} // PHON = "AI"; 
  if(S2.equals("ng") == true || S2.equals("nk") == true) {MINIMI = 2; MP3 = 31; LENGTH = 350;} // PHON = "NG"; 
  if(S2.equals("ie") == true || S2.equals("ih") == true) {MINIMI = 2; MP3 = 9; LENGTH = 350;}  // PHON = "I"; 
  if(S2.equals("ch") == true) {MINIMI = 2; MP3 = 32; LENGTH = 400;}  // PHON = "CH"; 
  if(S2.equals("eh") == true || S2.equals("ee") == true) {MINIMI = 2; MP3 = 5; LENGTH = 350;} // PHON = "E"; 
  if(S2.equals("uh") == true || S2.equals("ou") == true) {MINIMI = 2; MP3 = 21; LENGTH = 450;} // PHON = "U"; 
  if(S2.equals("au") == true || S2.equals("ow") == true) {MINIMI = 2; MP3 = 33; LENGTH = 390;} // PHON = "AU"; 
  if(S2.equals("oh") == true || S2.equals("oo") == true) {MINIMI = 2; MP3 = 15; LENGTH = 450;} // PHON = "O"; 
  if(S2.equals("eu") == true || S2.equals("oi") == true || S2.equals("oy") == true) {MINIMI = 2; MP3 = 34; LENGTH = 400;} // PHON = "OI"; 
  if(S2.equals("ks") == true) {MINIMI = 2; MP3 = 23; LENGTH = 330;} // PHON = "X"; 
  if(S2.equals("en") == true) {MINIMI = 2; MP3 = 35; LENGTH = 380;} // PHON = "EN"; 
  if(S2.equals("pf") == true) {MINIMI = 2; MP3 = 36; LENGTH = 330;} // PHON = "PF"; 
  if(S2.equals("qu") == true) {MINIMI = 2; MP3 = 17; LENGTH = 410;} // PHON = "Q"; 
  
  if(S2.equals("ä") == true) {MINIMI = 2; MP3 = 25; LENGTH = 380;} // PHON = "AE"; 
  if(S2.equals("ö") == true) {MINIMI = 2; MP3 = 26; LENGTH = 380;} // PHON = "OE"; 
  if(S2.equals("ü") == true) {MINIMI = 2; MP3 = 27; LENGTH = 380;} // PHON = "UE";
}

if (MINIMI < 2) {
  
  switch(S1) {
  case 'a': MP3 = 1; LENGTH = 350; break; // PHON = "A";
  case 'b': MP3 = 2; LENGTH = 330; break; // PHON = "B"; 
  case 'c': MP3 = 3; LENGTH = 330; break; // PHON = "C"; 
  case 'd': MP3 = 4; LENGTH = 355; break; // PHON = "D";
  case 'e': MP3 = 5; LENGTH = 350; break; // PHON = "E";
  case 'f': case 'v': MP3 = 6; LENGTH = 370; break; // PHON = "F";
  case 'g': MP3 = 7; LENGTH = 340; break; // PHON = "G";
  case 'h': MP3 = 8; LENGTH = 335; break; // PHON = "H";
  case 'i': case 'y': MP3 = 9; LENGTH = 350; break; // PHON = "I";
  case 'j': MP3 = 10; LENGTH = 340; break; // PHON = "J";
  case 'k': MP3 = 11; LENGTH = 340; break; // PHON = "K";
  case 'l': MP3 = 12; LENGTH = 330; break; // PHON = "L";
  case 'm': MP3 = 13; LENGTH = 330; break; // PHON = "M";
  case 'n': MP3 = 14; LENGTH = 335; break; // PHON = "N";
  case 'o': MP3 = 15; LENGTH = 370; break; // PHON = "O";
  case 'p': MP3 = 16; LENGTH = 330; break; // PHON = "P";
  case 'q': MP3 = 17; LENGTH = 380; break; // PHON = "Q";
  case 'r': MP3 = 18; LENGTH = 350; break; // PHON = "R";
  case 's': MP3 = 19; LENGTH = 385; break; // PHON = "S";
  case 't': MP3 = 20; LENGTH = 340; break; // PHON = "T";
  case 'u': MP3 = 21; LENGTH = 370; break; // PHON = "U";
  case 'w': MP3 = 22; LENGTH = 335; break; // PHON = "W";
  case 'x': MP3 = 23; LENGTH = 340; break; // PHON = "X";
  case 'z': MP3 = 24; LENGTH = 340; break; // PHON = "Z";
  case ' ': case ',': case '.': case ';': case ':': case '!': case '?': case '-': MP3 = 0; LENGTH = 400; break; // PHON = " ";
  }
  MINIMI = 1;
}
  
  SATZ = SATZ.substring(MINIMI);    // SHORTEN SENTENCE !
  
  if (SATZ.length() <= 0)           // REPEAT !
  {
  SATZ = URSATZ;
  }
  
}


void PlayMP3() {

int MP3ONES = 0;
byte TENS = 0;
byte ONES = 0;

if (MP3 >= 0 && MP3 < 10) {MP3ONES = MP3; TENS = 0x30;}
if (MP3 >= 10 && MP3 < 20) {MP3ONES = MP3-10; TENS = 0x31;}
if (MP3 >= 20 && MP3 < 30) {MP3ONES = MP3-20; TENS = 0x32;}
if (MP3 >= 30 && MP3 < 40) {MP3ONES = MP3-30; TENS = 0x33;}

switch (MP3ONES){
  case 0: ONES = 0x30; break;
  case 1: ONES = 0x31; break;
  case 2: ONES = 0x32; break;
  case 3: ONES = 0x33; break;
  case 4: ONES = 0x34; break;
  case 5: ONES = 0x35; break;
  case 6: ONES = 0x36; break;
  case 7: ONES = 0x37; break;
  case 8: ONES = 0x38; break;
  case 9: ONES = 0x39; break;
}

MP3Serial.print(0x7E,BYTE);
MP3Serial.print(0x07,BYTE);
MP3Serial.print(0xB0,BYTE);
MP3Serial.print(0x30,BYTE);
MP3Serial.print(0x31,BYTE);
MP3Serial.print(0x30,BYTE);
MP3Serial.print(TENS,BYTE);
MP3Serial.print(ONES,BYTE);
MP3Serial.print(0x7E,BYTE);

}

}

yeah, come over! beer and pizza is ready. Location: Bielefeld, germany. Sun is shinig as well! :%

if(S3.equals("sch") == true) {MINIMI = 3; MP3 = 37; LENGTH = 400;} // PHON = "SCH"; 
if(S3.equals("rrh") == true) {MINIMI = 3; MP3 = 18; LENGTH = 330;} // PHON = "R"; 
if(S3.equals("cch") == true) {MINIMI = 3; MP3 = 11; LENGTH = 330;} // PHON = "K"; 
if(S3.equals("ail") == true) {MINIMI = 3; MP3 = 30; LENGTH = 400;} // PHON = "AI"; 
if(S3.equals("ieh") == true) {MINIMI = 3; MP3 = 9; LENGTH = 400;} // PHON = "I"; 
if(S3.equals("eau") == true) {MINIMI = 3; MP3 = 15; LENGTH = 400;} // PHON = "O"; 
if(S3.equals("chs") == true || S3.equals("cks") == true ) {MINIMI = 3; MP3 = 23; LENGTH = 40;} // PHON = "X"; 
if(S3.equals("äh") == true) {MINIMI = 3; MP3 = 25; LENGTH = 450;} // PHON = "AE"; 
if(S3.equals("öh") == true) {MINIMI = 3; MP3 = 26; LENGTH = 400;} // PHON = "OE"; 
if(S3.equals("üh") == true) {MINIMI = 3; MP3 = 27; LENGTH = 450;} // PHON = "UE"; 
if(S3.equals("äu") == true) {MINIMI = 3; MP3 = 34; LENGTH = 400;} // PHON = "OI";

The == true bit is unnecessary, since the equals() method returns true or false.

I think you need the second and subsequent if statements to be else statements, and you need an else statement that defines what to do if none of these are true.

switch (MP3ONES){
  case 0: ONES = 0x30; break;
  case 1: ONES = 0x31; break;
  case 2: ONES = 0x32; break;
  case 3: ONES = 0x33; break;
  case 4: ONES = 0x34; break;
  case 5: ONES = 0x35; break;
  case 6: ONES = 0x36; break;
  case 7: ONES = 0x37; break;
  case 8: ONES = 0x38; break;
  case 9: ONES = 0x39; break;
}

As opposed to

if(MP3ONES >= 0 && MP3ONES <= 9)
   ONES = MP3ONES + 0x30;

? You do like to type.

There are no Serial.print() statements anywhere in the code you posted. You should add some to see what values GraphToPhon() is setting, and what values PlayMPS3() is getting and creating.

Hi,

thanks for the hints to save my fingertips from glowing. :stuck_out_tongue:
i had some serial-print-lines in my code, the returns were ok. (checked that again, returns are still ok.)

the PlayMP3-Function gets and returns the right values.

Any further suggestions?

Kind Regards,
P

Any further suggestions?

One.

#define rxPin 15 // actually, I am not using a rxPin
#define txPin 14
SoftwareSerial MP3Serial =  SoftwareSerial(rxPin, txPin); // SET UP SERIAL PORT

Does the device you are talking to return anything if the input it gets is unintelligible? Does it return anything if the input it gets is intelligible?

Hallo,

unfortunately there is no return from the device. But my problem seems to be solved. i updated to arduino 1.0 and the "NewSoftSerial"-library seems to transfer more properly and reliable.

THANKS !
P

Actually, the correct software serial library for 1.0 IS SoftwareSerial. SoftwareSerial for 1.0 is the same as NewSoftSerial that you should have been using prior to 1.0. The SoftwareSerial library under 0023 and earlier was obsolete.

exactly.
thanks again!