Creating, Sending and Parsing Parameterized Messages
This lesson will show the user how to send a message with a parameter attached as a suffix to the message. Once the message has been received on the other end, the user will have to search the message for the correct command string, delete the characters that are not needed (i.e the letters) and extract the parameter to be used in their program or function call.
Topics Covered In This Lesson:
- Sending and Receiving Data
- Using External Libraries
- Parsing data using the "StringFind" command
- Deleting string data using the "StringDelete" command
- Converting string data into integer values using the "atoi" command
- Developing a Dictionary of Commands
Note: The concepts outlined in this lesson are geared towards an intermediate user of ROBOTC and C Programming languages. Users should familiarize themselves with ROBOTC before beginnging the Multi-Robot lessons.
- Remember when using Multi-Robot communications to always start the robot that is the receiver first. Otherwise, the receiving robot will not be listening when the sending robot broadcasts it's message.
Update your library of actions we previously created in the last lesson so the commands will now accept parameters. Example: “turnLeft90” means turn left 90 degrees Update the code from the previous lesson so that Robot A sends a parameterized string, and Robot B receives and performs parameterized action by parsing the received message.
- Each Robot should have a programmed Xbee radio attached to a NXTBee adapter. The NXTBee Adapter should be connected to sensor port 4 of the LEGO NXT.
Now that we have created a library of commands (a dictionary) that our receiving robot knows about, we are able to send commands and have our robot respond to these commands. The downside to this current method is that we have to pre-program each individual behavior - i.e. move forward 50cm and move forward 100cm are two different messages. Any kind of precise or customizable message now has to have it's own unique command. This will eventually lead to us having a large library of command that do mostly similar behaviors.
So how can we fix this issue? Recall back to the ROBOTC curriculum where we learned about functions and parameters. In order to extend the capabilities of our functions, we could send variables to our functions that contained values that we wanted the function to use to determine the distance or duration of the action. We can do this as well with our Multi-Robot messages as well!
- Move forward x cm
- Turn left y degrees
To do this, we can package multiple strings together into a combined string. Think about an example of wanting to send the message "Move forward for 50cm". Our message might look like this:
- “Forward” + “50” = Forward50
On the receiving end, we can break messages apart to find out the parameters. To do this, we can remove the part of the message that we know (the forward part) and leave our parameter (the numerical value) to use in our program.
- “Forward50” – “Forward” = “50”
Lastly, we'll have to think about how messages are sent. All messages are sent as string, which are known as arrays of characters. A character (char) is not the same as a numerical value, however. A character has a unique value that corresponds a character in a big list known as an ASCII table. So because we have the string characters "50" does not mean that we have the numerical value (50). Luckily, we can use a special command in C-Programming and ROBOTC to convert from this string representation of our number to a numerical representation of our number - this command is the "atoi" command, which you'll learn about below.
- StringFormat(stringToFormat,”New Format”, parameters); - The string format command is used to package up multiple values and string into a single string using a special character formatting method (similar to a C-Style 'printf' statement). This function is very similar to the nxtDisplayTextLine and nxtDisplayString functions, but instead of displaying the value to the LCD, we store the formatted string into a string variable.
- StringDelete(inputString, indexPosition, size); - The string delete command is used to delete a specific number of characters from a specified string.
- atoi(inputString); - The atoi command converts a numerical value represented as a string variable (example: "50") into a numerical value represented by an integer (example: 50). This function can only convert the ASCII characters '0' through '9', any other characters that are placed into the atoi function may return an unexpected value.
- StringFind(stringToCompare, “substring”) - Finds a specific sub-string inside of a string. Function will returns a value of (-1) if the sub-string could not be found. If the sub-string is found, the function will return the index of where the sub-string begins (normally 0).
- InitRS485(); - Function to initializes the XBee radio
- SendString(message); - Sends a string to every other robot in range on the same communication channel. This function will delay the program to allow the message to properly sent (roughly 1ms per character in the string).
- ReceiveString(message); - Receives a string that was sent from another robot. This function will delay the program until a message is received (internal loop).
1. Start with the sample programs the from "Sending and Parsing Commands" lesson.
2. Start with Robot A (sender) - This program is very similar to the Robot A program from the previous Lesson. Robot A should only initialize its radio, and then send a string corresponding to one of the behaviors we'll program into Robot B, but this time with a parameter. Modify your program so that Robot A sends the command "Fwd2500", which will tell the receiving robot (Robot B) to move forward for 2.5 seconds. To do this, you can specify that message specifically, or you can create a string variable and an integer variable and use the "StringFormat" command to combine the two.
- string messageToSend;
- int time = 2500;
- StringFormat(messageToSend, "Fwd%d", time);
3. Robot B should be set up in a similar program as the "Sending and Parsing Commands" lesson. One you have the radio initialized and the received string stored in a variable, we can proceed to parsing/understanding the data.
4. Just like before, Robot B after it has received the string should now compare the incoming string to a set of known data. Using the "StringFind" command, we will want to check each string. We can do this by asking the question of where the "sub-string" that we are looking for appears in the incoming string from Robot A. Using an "if" command, we can ask if the sub-string "Fwd" exists in incomingString we received from Robot A. Your code should look like this:
- if(stringFind(incomingString, "Fwd") >= 0)
This line reads "If the "Fwd" sub-string is found at index 0 or greater in the string "incomingString", then run the code for this condition." We look for an index of 0 or greater to ensure that the string is anywhere inside of what we received. This condition basically says "as long as "Fwd" is somewhere, good enough" and will run the code for the condition. We say "greater than zero" because we will receive a value of (-1) if the sub-string is not found.
5. Once we have found the string that has been received, we must perform two more steps before we can have Robot B begin to respond to the message. The first step is to use the "StringDelete" command to remove the command action from our string. For example, since we received "Fwd2500", we now want to delete the first three characters from the string so we are left with only "2500". To do this, use the StringDelete command.
- StringDelete(incomingString, 0, 3); - This will delete three characters from the string variable incomingString starting at index 0 (the beginning of the string).
6. Add ATOI + Information about while loop - sample program below needs to be modified (T.Friez)
Robot A Source Code
Download Parameterized Messages A
Robot B Source Code
Download Parameterized Messages B