Shop OBEX P1 Docs P2 Docs Learn Events
Another emic2 question (speaking variables) — Parallax Forums

Another emic2 question (speaking variables)

Jim the HermitJim the Hermit Posts: 79
edited 2014-04-18 19:17 in General Discussion
I was wondering how do I make it say

Serial.Str(String("The temperature is, ")) X
Serial.Str(String("degrees."))
serial.TX(pst#NL)

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-13 19:19
    I was wondering how do I make it say

    Serial.Str(String("The temperature is, ")) X
    Serial.Str(String("degrees."))
    serial.TX(pst#NL)

    Each line sent to the Emic2 needs to start with a "S" in order for it to be said.

    I think this would work.
    Serial.Str(String("[COLOR=#ff0000]S[/COLOR]The temperature is, ")) 
    Serial.[COLOR=#ff0000]Dec[/COLOR](X)
    Serial.Str(String("degrees."))
    serial.TX(pst#NL)
    
  • Jim the HermitJim the Hermit Posts: 79
    edited 2014-04-14 09:00
    Yep! Serial.Dec(x) is what I needed.

    So..... how do I do names?
    "Hello, "; name(1); "I have a message for you."
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-14 11:41
    Yep! Serial.Dec(x) is what I needed.

    So..... how do I do names?
    "Hello, "; name(1); "I have a message for you."

    This kind of depends on how names are stored.

    Here's one example.
    Serial.Str(string("SHello, "))
      Serial.Str(@name1)
      Serial.Str(string("I have a message for you.", 13)) ' Emic2 expects a carriage return at the end of text to be spoken. 13 is the ASCII number for a carriage return.
    
    DAT
    
    name1          byte "Jim The Hermit", 0 ' make sure a string has a terminating zero
    
    

    I haven't tested the above, but I'd be surprised if it didn't work.

    If you want to access a name based on an index number things get a bit trickier. On way to find a string based on an index number is make each string the same length so you know where the string you want starts.
    PUB DisplayGreeting(nameIndex)
     
     Serial.Str(string("SHello, "))
      Serial.Str(@nameList + (nameIndex * BYTES_PER_NAME))
      Serial.Str(string("I have a message for you.", 13)) ' Emic2 expects a carriage return at the end of text to be spoken. 13 is the ASCII number for a carriage return.
    
    CON
    
      BYTES_PER_NAME = 16
    
    DAT
                                
    nameList          byte "Jim The Hermit", 0[BYTES_PER_NAME  - 14]
                          byte "Duane Degn", 0[BYTES_PER_NAME - 10]
                          byte "Joe Blow", 0[BYTES_PER_NAME - 8]
    
    

    With this technique you need to make sure you leave the correct number of zeros to keep the name aligned.

    If you don't want to keep track of the size of names, you can have the Propeller count through the names for you.
    PUB DisplayGreeting(nameIndex)
    
     Serial.Str(string("SHello, "))
      Serial.Str(FindStringOrderPtr(@nameList, nameIndex))
      Serial.Str(string("I have a message for you.", 13)) 
    
    PUB FindStringOrderPtr(firstStr, stringIndex)     '' Finds start address of one string in a list
    '' of string. "firstStr" is the address of 
    '' string #0 in the list. "stringIndex"
    '' indicates which of the strings in the list
    '' the method is to find.
    
    
      result := firstStr
      
      repeat while stringIndex    
        repeat while byte[result++]  
        stringIndex--
    
    
    DAT
                                
    nameList          byte "Jim The Hermit", 0
                          byte "Duane Degn", 0
                          byte "Joe Blow", 0
    

    In this last example the names can be any size but need to have a terminating zero.
  • Jim the HermitJim the Hermit Posts: 79
    edited 2014-04-14 16:45
    Thanks again.
    Sadly, I will probably need the second or third method. Gotta learn more spin first.

    I sure miss commodore basic;
    x=3: dim a$(x)
    a$(0) = "Jim": a$(1) = "Duane": a$(2) = "Joe"
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-14 18:07
    There is way to do something similar in spin but it takes a bit more to setup the array of name locations.
    CON
    
      NAMES_IN_ARRAY = 3
    
    VAR
      word namePtr[NAMES_IN_ARRAY]
    
    PUB Setup
    
      ' fill the array with the memory location of each string
      namePtr[0] := @jim
      namePtr[1] := @duane
      namePtr[2] := @joe
    
      ' start serial terminal and other setup stuff
    
      Main ' Call the main method. Otherwise program would end.
    
    PUB Main
    
      repeat
        repeat result from 0 to NAMES_IN_ARRAY - 1 ' display each name. You could use some other algorithm to determine which name is said.
           DisplayGreeting(result)
          waitcnt(clkfreq + cnt)
    
    PUB DisplayGreeting(nameIndex)
     
      Serial.Str(string("SHello, "))
      Serial.Str(namePtr[nameIndex])
      Serial.Str(string("I have a message for you.", 13)) 
    
    DAT
                                
    nameList
    jim             byte "Jim The Hermit", 0
    duane           byte "Duane Degn", 0
    joe             byte "Joe Blow", 0
    
    

    Again, I haven't tested this code but I'm pretty sure it would cause the Emic2 to cycle through the names in the list.

    Assigning an element in the array "namePtr" with the address of each of the names allows the names to be easily accessed. I think it requires a bit more setup work than your Commodore Basic example but once the array is setup, it's pretty easy to use.

    There are of course many ways to accomplish the same thing in Spin. This is just one of many ways to access text strings with an index number.

    Edit: I just realized I kept using the word "display" when I should have been using "speak" or "say".
  • Jim the HermitJim the Hermit Posts: 79
    edited 2014-04-18 19:04
    'Here a simplified way to get Emic to say different names
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    
      Names_in_array = 4
    
    
    VAR
      word namePtr[Names_in_array]
      byte x
      
     
    OBJ
      pst       : "Parallax Serial Terminal"                   ' Debug Terminal
      serial    : "FullDuplexSerial"                           ' Full Duplex Serial
      
    PUB Setup
    
    
    'Emic2 pin connection
    'SIN     ────── P6
    'SOUT    ────── P7
    
    
    
    
      namePtr[0] := @jim
      namePtr[1] := @joe
      namePtr[2] := @john
      namePtr[3] := @mary
    
    
    
    
      serial.Start(7, 6, 00, 9_600)                      ' Start serial port, normal mode, 9600bps
      serial.TX(pst#NL)                                     ' Send a CR in case the system is already up
      repeat until serial.RxCheck == ":"                    ' When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
      
      waitcnt(clkfreq / 100 + cnt)                          ' Delay 10mS
      serial.RxFlush                                        ' Flush the receive buffer
    
    
      serial.Str(String("R", pst#NL))                        'reset to defaults
      repeat until serial.RxCheck == ":"
    
    
    
    
      serial.Str(String("P0", pst#NL))                       'set Parser to DecTalk
      repeat until serial.RxCheck == ":"
    
    
    
    
    '  serial.Str(String("N2", pst#NL))                      'voice
    '  repeat until serial.RxCheck == ":"
      
      serial.Str(String("V10", pst#NL))                      'volume -48 to 18
      repeat until serial.RxCheck == ":"
      
      serial.Str(String("W240", pst#NL))                    'words per minute
      repeat until serial.RxCheck == ":"
    
    
    Main
    
    
    PUB Main
    
    
    x := 3                                                  'X would change based on voice or facial recognition
    
    
    serial.tx("s")                                          'start speaking
    serial.str(string("Hello, "))
    serial.str(namePtr[x])
    serial.str(string("."," How are you today?", 13))
    
    
    
    
    
    
    DAT             
            jim   byte      "James", 0
            joe   byte      "Joe__sef",0
            john  byte      "Jonn",0
            mary  byte      "Maree__uh",0
    

    I was wondering how you did it, Duane. Thanks again.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-18 19:17
    As you can see, unless you use code tags you loose the indentation of the code.

    Here's a link to a tutorial Phil wrote on using code tags.

    attachment.php?attachmentid=78421&d=1297987572

    I take it the code is working as expected?
Sign In or Register to comment.