Shop OBEX P1 Docs P2 Docs Learn Events
emic 2 - skips text while it's speaking? — Parallax Forums

emic 2 - skips text while it's speaking?

I am using a Arduino Mega 2560 board, and a Emic 2 (connected to Serial1 on the board). When I first start up the sketch the emic will either miss words, or miss entire sentences, at least the 1st time it runs though the loop.
Each additional time it runs the loop, it seems to be fine. I've tried a number of different things, putting delays in, taking delays out. changing serial ports, even use a different sketch. I'm not really sure what is going on with it. And was hoping someone here might have a idea.
This video pretty much shows what it is doing,
(you pretty much have to watch the whole video to see it (sorry) - This is my Hero Jr project updating it to modern electronic hardware)
This is test code I was using, I don't think you want me to post the entire "hero jr code" -
int led0 = 22;
int led1 = 24;
int led2 = 26;
int led3 = 28;
int led4 = 30;
int led5 = 32;
int led6 = 34;
int led7 = 36;
int state0 = 1;
int state1 = 1;
int state2 = 1;
int state3 = 1;
int state4 = 1;
int state5 = 1;
int state6 = 1;
int state7 = 1;

void setup() 
{   
	pinMode(led0, OUTPUT);
   pinMode(led1, OUTPUT);
   pinMode(led2, OUTPUT);
   pinMode(led3, OUTPUT);
   pinMode(led4, OUTPUT);
   pinMode(led5, OUTPUT);
   pinMode(led6, OUTPUT);
   pinMode(led7, OUTPUT);
  
   digitalWrite(led0, 1);
   digitalWrite(led1, 1);
   digitalWrite(led2, 1);
   digitalWrite(led3, 1);
   digitalWrite(led4, 1);
   digitalWrite(led5, 1);
   digitalWrite(led6, 1);
   digitalWrite(led7, 1);
   
Serial.begin(9600);
Serial1.begin(9600); //Serial 1 is used for the eMIC 2 
delay(3000); //wait for eMIC 2 to come online
Serial1.flush();
//Serial1.println();
Serial1.println("v10"); //set volume to level 10
delay(500);
Serial1.println("p0"); //set pharser for DECtalk
delay(2000);

} 

void loop() 
{       
	//play Starwars.mp3 (This is the openning title music) While playing have Hero Give a welcome speech
speak ("Welcome to our special, Star Wars Day!");
//speak ("Welcome to our special Star Wars day!");
//Serial1.println("SWelcome to our special Star wars day!");
//speakend();
//Serial1.println("SI am a Hero Junior robot, and one of my most favorite movies is");
//speakend();
//Serial1.println("Sfavorite movies is Star Wars, I wish I could fight against the empire");
//speakend();
//Serial1.println("Salong side of my friends r 2 d 2 and c 3 p o");
//speakend();
//Serial1.println("Sthey are my heros");
//speakend();

//wait for song to end.
//speak ("I am a Hero Junior Robot, and one of my most favorite movies is");
speak ("I am a Hero junior robot and one of my");
speak("favorite movies is Star Wars I wish I could");
speak("fight against the empire alongside of my ");
speak("friends r 2 d 2 and c 3 p o");
//speak ("Star Wars, I wish I could fight against the ");

// play imperial.mp3
//speak ("Impire along side of my Friends, R 2 D 2 and C 3 P O");

//speak("alongside");
//speak("of my");
//speak("friends");
//speak("r 2 d 2");
//speak("and C 3 P O");



//wait for imperial to end, and play r2d2wst.mp3 wait r2d2wst1.mp3 wait.
//play c3po.mp3 wait.
speak("They are my Heros.");
speak("But I am a little afraid of");
//play breath.mp3 
speak("Oh my....Darth Vader. Where is my blaster.");
//if breath is done, play blaster.mp3
speak("Did I scare him off?  I think I scared myself a little bit." );
///play r2d2wstl.mp3 wait till done
//play star-wars-cantina-song.mp3
//while (cantina is playing...) {

speak("Hit a button on my keypad to hear a Star Wars Sound. Hit E to exit.");

}                  


void speak(char say[]) {
speakend();
	//0000000Serial1.flush();
	//Serial1.print("\r");
	//while(Serial1.read() != ':');
	//delay(500);
	String say2 = String(say);
	Serial.println(say2.length());
	Serial1.print("S");
	Serial1.print(say);
	Serial1.print("\r");
	//	ledmouth();
	//Serial1.print("\r");
	//while(Serial1.read() != ':');  
	//delay(500);
	speakend();
}

void speakint(int say) {
 speakend();
//	Serial1.println();
//	while(Serial1.read() != ':'); 
	//delay(500);
	Serial1.print("s");
	Serial1.println(say);
	//	ledmouth();
	//Serial1.println();
    //while(Serial1.read() != ':');// {ledmouth();}
//	delay(500);
}

void speakend() {
	//Serial1.println();
	//Serial.println(Serial1.read());
	Serial1.print("\r");
	while(Serial1.read() != ':') {
		ledmouth();
	//Serial1.print("\r");
	}; 
}

void ledmouth() {
	
	digitalWrite(led0, 1);
   	digitalWrite(led1, 1);
   	digitalWrite(led2, 1);
   	digitalWrite(led3, 1);
   	digitalWrite(led4, 1);
   	digitalWrite(led5, 1);
   	digitalWrite(led6, 1);
   	digitalWrite(led7, 1);
//	while(Serial1.read() != ':') {
	digitalWrite(led4, 1);
	digitalWrite(led3, 1);
	delay(25);
	digitalWrite(led2, 1);
	digitalWrite(led5, 1);
	delay(125);
	digitalWrite(led1, 1);
	digitalWrite(led6, 1);
	delay(125);
	digitalWrite(led0, 1);
	digitalWrite(led7, 1);
	delay(125);
	digitalWrite(led0, 0);
	digitalWrite(led7, 0);
	delay(125);
	digitalWrite(led1, 0);
	digitalWrite(led6, 0);
	delay(125);
	digitalWrite(led2, 0);
	digitalWrite(led5, 0);
	delay(125);
	digitalWrite(led4, 0);
	digitalWrite(led3, 0);
	delay(25);
//	};
digitalWrite(led0, 1);
   	digitalWrite(led1, 1);
   	digitalWrite(led2, 1);
   	digitalWrite(led3, 1);
   	digitalWrite(led4, 1);
   	digitalWrite(led5, 1);
   	digitalWrite(led6, 1);
   	digitalWrite(led7, 1);
	digitalWrite(led0, state0);
	digitalWrite(led1, state1);
   	digitalWrite(led2, state2);
   	digitalWrite(led3, state3);
   	digitalWrite(led4, state4);
   	digitalWrite(led5, state5);
   	digitalWrite(led6, state6);
   	digitalWrite(led7, state7);
   //Serial.println(">");
}

You will see a lot of commented out stuff that I was trying nothing seemed to help or fix the problem. So looking to people who know and understand the emic better.
Thanks
-LeRoy

Comments

  • Have you tried the example sketch?

    Since you're problems occur with the initialization of the Emic2, I'm inclined to think you're not giving the Emic2 enough time at startup. I'm very surprised this is a problem since it looks like you have plenty of delays while starting the Emic2.

    Here's the sketch I have (I'm pretty sure I downloaded it from Parallax.)
    /*
      
      Emic 2 Text-to-Speech Module: Basic Demonstration       
                                                             
      Author: Joe Grand [www.grandideastudio.com]             
      Contact: support@parallax.com                            
      
      Program Description:
      
      This program provides a simple demonstration of the Emic 2 Text-to-Speech
      Module. Please refer to the product manual for full details of system 
      functionality and capabilities.
    
      Revisions:
      
      1.0 (February 13, 2012): Initial release
      
    */
    
    // include the SoftwareSerial library so we can use it to talk to the Emic 2 module
    #include <SoftwareSerial.h>
    
    #define rxPin 2    // Serial input (connects to Emic 2 SOUT)
    #define txPin 3    // Serial output (connects to Emic 2 SIN)
    #define ledPin 13  // Most Arduino boards have an on-board LED on this pin
    
    // set up a new serial port
    SoftwareSerial emicSerial =  SoftwareSerial(rxPin, txPin);
    
    
    void setup()  // Set up code called once on start-up
    {
      // define pin modes
      pinMode(ledPin, OUTPUT);
      pinMode(rxPin, INPUT);
      pinMode(txPin, OUTPUT);
      
      // set the data rate for the SoftwareSerial port
      emicSerial.begin(9600);
    
      digitalWrite(ledPin, LOW);  // turn LED off
      
      /*
        When the Emic 2 powers on, it takes about 3 seconds for it to successfully
        initialize. It then sends a ":" character to indicate it's ready to accept
        commands. If the Emic 2 is already initialized, a CR will also cause it
        to send a ":"
      */
      emicSerial.print('\n');             // Send a CR in case the system is already up
      while (emicSerial.read() != ':');   // When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
      delay(10);                          // Short delay
      emicSerial.flush();                 // Flush the receive buffer
    }
    
    void loop()  // Main code, to run repeatedly
    {
      // Speak some text
      emicSerial.print('S');
      emicSerial.print("Hello. My name is the Emic 2 Text-to-Speech module. I would like to sing you a song.");  // Send the desired string to convert to speech
      emicSerial.print('\n');
      digitalWrite(ledPin, HIGH);         // Turn on LED while Emic is outputting audio
      while (emicSerial.read() != ':');   // Wait here until the Emic 2 responds with a ":" indicating it's ready to accept the next command
      digitalWrite(ledPin, LOW);
        
      delay(500);    // 1/2 second delay
        
      // Sing a song
      emicSerial.print("D1\n");
      digitalWrite(ledPin, HIGH);         // Turn on LED while Emic is outputting audio
      while (emicSerial.read() != ':');   // Wait here until the Emic 2 responds with a ":" indicating it's ready to accept the next command
      digitalWrite(ledPin, LOW);
    
      while(1)      // Demonstration complete!
      {
        delay(500);
        digitalWrite(ledPin, HIGH);
        delay(500);              
        digitalWrite(ledPin, LOW);
      }
    }
    

    The most important part for your problem would likely be these lines:
    /*
        When the Emic 2 powers on, it takes about 3 seconds for it to successfully
        intialize. It then sends a ":" character to indicate it's ready to accept
        commands. If the Emic 2 is already initialized, a CR will also cause it
        to send a ":"
      */
      emicSerial.print('\n');             // Send a CR in case the system is already up
      while (emicSerial.read() != ':');   // When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
      delay(10);                          // Short delay
      emicSerial.flush();                 // Flush the receive buffer
    }
    

    Your "Setup" function waits three seconds, but it's possible you need to wait a bit longer.

    Let us know if you're still having problems and I'll wire up my Emic2 to an Arduino to see if I can duplicate the trouble. I personally haven't used an Emic2 with an Arduino. I use Propeller chips for most of my projects.

    BTW, You might want to check out the robot site RobotRebels.org. It's a fun place to show off and talk about robots people are working on.
  • Duane,
    Yes, thank you - I've thought of that as well, and have had the delay as long as 15 seconds (which seemed excessive), and as short as 1 second (which of course is too short)
    I have looked at the example sketch, and that seems to work, so I was thinking it must be something I am doing.
    It almost seems like the eMic is sending the : before it is done speaking, getting confused when I say "speak something else" - at least over the 1st loop.

    There are two things I noticed in your sketch that I didn't do in mine - I don't have a WHILE waiting after my large delay(3000);
    and I didn't set the serial port pins as INPUT and OUTPUT - which I don't know if that would cause a issue or not on a hardware serial port, but is only a couple extra lines of code
    so worth a try.

    Is it possible to that even though the eMic says it's ready for the next command it's is not (?)
    and I just need some delay before I send it the next "speak something" command?
    I am literally checking for the : once before I say "speak" and once after I say the command to try a solve this issue.

    And was even considering (it's in the back of my mind) cutting the trace to the LED on the emic and wiring that to the arduino - using a digitalRead (when the led is on, it's speaking when it's off, it's not.)
    Not sure if I want to go down that road or not. But it was something I considered.

    I'll have to check out your site, when I have a little more time.
    Thank you for the help and ideas to try.
    -LeRoy
  • kd8bxp wrote: »
    I didn't set the serial port pins as INPUT and OUTPUT - which I don't know if that would cause a issue or not on a hardware serial port, but is only a couple extra lines of code
    so worth a try.

    I have a hard time believing the INPUT and OUTPUT statements make a difference to the operation of the program. If the software serial works at all, I can't see how adding these lines would change anything. I suppose it wouldn't hurt to leaving them in. Hopefully the other differences in the program will be enough to get your code to work as expected.

    kd8bxp wrote: »
    Is it possible to that even though the eMic says it's ready for the next command it's is not (?)
    and I just need some delay before I send it the next "speak something" command?
    I am literally checking for the : once before I say "speak" and once after I say the command to try a solve this issue.

    According to the documentation, the Emic2 sends the ":" character when it's ready for a new command. I suppose this means the Emic2 could still be executing a previous command but the new command sent should be received okay.
    kd8bxp wrote: »
    And was even considering (it's in the back of my mind) cutting the trace to the LED on the emic and wiring that to the arduino - using a digitalRead (when the led is on, it's speaking when it's off, it's not.)
    Not sure if I want to go down that road or not. But it was something I considered.

    I don't think you need to cut a trace to make use of the LED output. You could solder a wire to one side of the surface mount resistor feeding the LED and use this wire to monitor the Emic2.

    I'm not sure which LED does what, but here are the two resistors which limit the current to these LEDs. The spots circled in red are where you'd want to solder a wire. The top resistor feeds the LED closest to the edge of the board.


    Emic2Led.PNG

    Hopefully the setup section of the demo code will be enough to solve your problem and you won't need to start soldering wires to the Emic2.
    582 x 487 - 573K
  • I know on my original DECTalk, it was easy to over run the buffer. Had to send smaller snippets followed by CR.
  • Duane, Thanks again, yes, for sure it is going to be easier to hook a wire to the resistors...I'd have to check again which one I need, one is for power to the device, the other would be the one I need.
    So great info there.

    I think after talking to you a little here, what Publison has also posted, about the buffer over run. I might just need to do the hardware and check to make sure it's not talking before I proceed.

    I'd bet - I am filling the buffer thinking that because it's speaking it's also waiting....the arduino has proceed way past where I think it is, and the eMic is just slow because it's generating sound.

    Like you I have a hard time believing the INPUT/OUTPUT on the serial port would do much of anything, and I bet I'm thinking (wrongly so) that the : means it's done talking.

    Thank both of you for the help and ideas to try, if I get it working I'll post updates, and if not, I'll be back for more ideas :-)
    Thanks again.
    -LeRoy
  • Publison,

    I did think maybe I was filling the buffer at one point - and I was just sending one word or a very small set of words - that did seem to work, but it was so "choppy" to listen too I rejected the though of using it. See my above comment because you might be onto something thou. So I do thank you for at least the idea of what it might be.
    -LeRoy
  • Duane,
    There is an Assembly drawing on Joe Grand's website and on the 2nd page you can see your 2 resistors are.
    http://www.grandideastudio.com/wp-content/uploads/emic2_assembly.pdf
    The Parallax schematic shows that R7 goes to the Green LED of D1 and R8 goes to the Red LED of D1.

    Have you seen the Tymkrs hack that is also linked in Additional Resources?
    They do some really cool things with the EMIC such as sing and play music at the same time. Awesome!!!

    kd8bxp,
    The EMIC-2 is made by Grand Idea Studio so there is a lot more information at that site than on the Parallax page.
    There is a link under Additional Resources tab on the product page but I am also placing it here for you.
    http://www.grandideastudio.com/portfolio/emic-2-text-to-speech-module/

    One of the links from there is an EMIC-2 Arduino tutorial from CodeBender that you should look at.
    http://blog.codebender.cc/2014/02/20/emic2/

  • Ok, so I did try the LED idea I had, and that idea didn't work. (not sure why, it seems like it should have. I even used a pullup resistor just like I should)
    I came across a document for the original emic, and it looks like it had a busy signal
    http://datasheet.octopart.com/30016-Parallax-datasheet-52145.pdf

    which would work perfect for what I'm doing, so question, anyone have any idea where to get one of the original boards?

    Next question - one of the documents on the grandideastudio site said something about a debug pin header, I can't find anything out about it or how to use it -- my question of course is does it have a busy line (?)

    I wonder why the 1st model had a busy line and the emic 2 does not. It seems to me that is something that is sadly missing from this device.

    Thanks again,
    LeRoy
  • LeRoy, do you have a different Arduino you could test the Emic on?

    I have an Uno, Pro Mini and a Nano. I could one of these in an attempt to replicate your trouble but I don't have a Mega.

    These boards only have a single UART and they'd need to use a soft serial. I'd think issue should show up with a soft serial the same as it would for a hardware serial.

    I've been meaning to purchase a Mega clone which I will likely do in next couple days but I'll probably get it from China and shipping will likely take a few weeks.

    It sure seems like this is something which should be solvable. I'm willing to help but I'm not sure how to best test your code.
  • Duane,
    I have since moved the emic 2 to a NANO,
    Seems like it does work better on the Nano with software serial. But at times I have noticed some strangeness, sometimes it seems like it talks over itself - which is just weird.
    The best results I've gotten are from a fresh power up of the emic2 and nano - and then powering up the mega. It does seem less picky on the Nano thou.
    Every example I've seen uses software serial ports - which is why I thought of switching it in the first place.
    I would not have thought it would make a difference thou. So it could be something about the Mega.

    Also I have decided, that the emic 2 while it's a great chip - is probably not the one I need, and I probably need the older emic - it had a busy line that you could check.

    I have not tried this yet, it was on my list of things to do today, and I got side track. But I thought that if I know what the WPM (that can be set, I think the default is 200wpm?) it is speaking is, and I know how many words I tell it to speak
    I could figure out how long it takes to speak those words: (WPM*WORDS)/60 = Time in Seconds - then a statement like
    delay(time*1000); would/should give a pretty close estimate and be ready for the next thing to say.

    I've had other ideas that didn't work out, so I don't know if that one will either, but it kind of sounds reasonable....I think (?)

  • I'm pretty sure the reason there's an Emic 2 is because the parts for the Emic one were end of life. I think you can only find an original Emic either as a used device or a device which has been sitting on a shelf for a long time.

    I have two of the original Emic boards but both of them died on me.

    Do you have some code which consistently has problems with the Emic 2? I'll try it with my Nano and look to see if I can find a way of getting around the problems you haven't already tried.
  • Duane,
    Honestly I was very happy to get the emic2, it seemed that for a while I wasn't able to find any of them either. I think you are right about the original emic thou - it's going to be a long hard search, a quest that may never be full field.

    I think I said this, but maybe not - I have an old Hero Junior robot (1985ish) - it was not working, and I replaced just about everything in it with modern hardware, controllers, etc - really the only thing left is it still looks like a classic Junior - and the motors are original, everything else has pretty much been changed.
    So the emic is providing the speech for it. I guess the code I am having the most problem with can be found here:
    https://codebender.cc/sketch:166750

    It's a large program, and I'm not sure it will run on a Nano as is. -- Probably the startup routine, the testing routines and the "special Star Wars day" stuff if we cut everything else out.
    I'd almost send you a clone Mega for one of the broken emic boards, but I don't think I need any more projects right now that don't work :-)
  • arduinolightarduinolight Posts: 1
    edited 2016-04-30 00:46
    Hello, I seem to have the same problem. Anybody got a solution?

    I connected the EMIC2 via hardware serial 1 of my Mega. In my program, I have a while loop within which there is a bunch of if statements for EMIC2 to talk different things depending on which condition is met during each iteration. I noticed that if I just issue a set of :

    Serial1.print('S');
    Serial1.print("A sentence depending on which if statement is chosen");
    Serial1.print('\n');

    without a delay after Serial1.print(\n'), EMIC2 does not talk each time it is supposed to. It seems like if the call for Serial1.print happens too quick, EMIC2 cannot catch up and as a result, it misses some Serial1.print statements. It also seems that by changing the parameter in delay, I can make the EMIC2 to talk more or less.
    Could you please let me know what is going on and how to determine the proper delay parameter?

    When do I have to issue Serial1.flush(); ?
  • After I send the EMIC2 the newline, I have the program wait until the EMIC2 sends a ready character (':' ascii 58). That way you don't need to guess how long to wait.

    I am using the Propeller microcontroller. In propeller C I use the following statements. I don't know what the corresponding statements would be for the Arduino.
        // ** end the string and speak and wait until EMIC is ready
    dprint(emic,"\n");    // send terminator  
        // ** wait until EMIC is ready - this is needed after the new line is sent 
    while(readChar(emic) != ':');    // check for ':' i.e. dec 58, use single quotes around :
    
    

    Hope this helps,
    Tom
Sign In or Register to comment.