Another emic2 question (speaking variables)
Jim the Hermit
Posts: 79
I was wondering how do I make it say
Serial.Str(String("The temperature is, ")) X
Serial.Str(String("degrees."))
serial.TX(pst#NL)
Serial.Str(String("The temperature is, ")) X
Serial.Str(String("degrees."))
serial.TX(pst#NL)

Comments
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)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 zeroI 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", 0In this last example the names can be any size but need to have a terminating zero.
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"
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", 0Again, 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".
'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",0I was wondering how you did it, Duane. Thanks again.
Here's a link to a tutorial Phil wrote on using code tags.
I take it the code is working as expected?