For embedded devices, we have included an example that runs on the ClearCore I/O
controller. Other devices should be similar.
Objective:
This example demonstrates how to send a request to the Burro and read the
resulting response. It also utilizes the splitString
and ParseResponse
functions that can be found elsewhere.
Description:
This example will send a string over TTL to the Burro asking for the station
status and wait for a response. It will then parse that response to see if the
Burro has stopped for a station and flash a light if it does. It also has
informative debug prints to be sent over the ClearCore’s USB-B serial
connection. Errors are printed but otherwise ignored and unhandled.
Requirements:
- A TTL serial connection between COM-1 and the Burro robot.
- A Burro robot with the Burro API
Example_station_status_checker.ino
#define ARDUINOJSON_ENABLE_STD_STRING 1
#undef max
#undef min
#include <sstream>
#include <string>
#include <vector>
#include "ClearCore.h"
std::vector<std::string> splitString(std::string str, char delimiter = ',')
{
std::vector<std::string> splitVect;
std::stringstream ss(str);
std::string substr;
while (ss.good())
{
getline(ss, substr, delimiter);
splitVect.emplace_back(std::move(substr));
}
return splitVect;
}
std::vector<std::string> ParseResponse(std::string response_string){
// The response string is split around a single equals sign '='. There will never be more than one (1) equals
// sign in a response string.
std::vector<std::string> split_response = splitString(response_string.substr(1), '=');
// The underscore '_' indicate the end of a response. It will be in the second slot of the vector along with the
// timestamp and returned values. Strip any characters after it.
int loc = split_response[1].find('_');
split_response[1] = split_response[1].substr(0, loc);
// Strip the leading percent '%' which is indicative of a response. Logic can be performed here to verify that
// the message is a properly formatted response.
std::string s = split_response[1];
// Determine if there is an error in the response.
if (s.find("#ERR") != std::string::npos)
{
std::string err_string = split_response[0] + " had error: " + s;
split_response[1] = err_string;
split_response[0] = "API Returned an error.";
return split_response;
}
// Return the vector so it is known what response matches what original command.
return split_response;
}
// Select the baud rate to match the target device.
#define baudRateSerialPort 115200
#define baudRateInputPort 115200
// Specify which serial interface to use as output.
#define SerialPort ConnectorUsb
// Specify which serial interface to use as input.
#define InputPort ConnectorCOM1
// Container for the byte to be read-in
int16_t input;
int main() {
// Set up serial communication to print out the serial input.
SerialPort.Mode(Connector::USB_CDC);
SerialPort.Speed(baudRateSerialPort);
SerialPort.PortOpen();
// Setup communication over the COM port to communicate with Burro.
InputPort.Mode(Connector::TTL);
InputPort.Speed(baudRateInputPort);
InputPort.Parity(SerialBase::PARITY_N);
InputPort.StopBits(1);
InputPort.FlowControl(false);
InputPort.PortOpen();
while (!InputPort) {
continue;
}
while (true) {
// Send the request for the information you want, in this case station status
InputPort.Send("?STTN_\r");
Delay_ms(100);
// Create a string and read the first character
std::string response = "";
input = InputPort.CharGet();
// While there are bytes to read, read them and add them to our response string
while (input != -1) {
response += (char)input;
input = InputPort.CharGet();
}
// If there was a string read-in, parse it and perform logic.
if (response != "") {
// Display the string received. Mostly for debug purposes, if you don't have a print
// capable monitor connected over USB-B comment this out.
SerialPort.Send("Received:");
SerialPort.SendLine((" " + response).c_str());
// Parse the response to begin to perform logic. The command that was sent is in the 0th spot
// in the vector.
std::vector<std::string> parsed_response = ParseResponse(response);
if ( parsed_response[0] == "?STTN") {
// The parser has the API backend's response to the request in the 1st spot of the vector.
// Split this on spaces to get the timestamp, and then any returned args. ?STTN should only
// return one arg along side the timestamp. This will be 0 if no at a station and 1 if stopped
// for a station.
std::vector<std::string> split_station_response = splitString(parsed_response[1], ' ');
if (split_station_response[1] == "1"){
// Do whatever you want to do if you are stopped at a station. I am printing over USB-B and
// flashing the built in LED on the ClearCore board.
SerialPort.Send("Stopped for station at time");
SerialPort.SendLine((" " + split_station_response[0]).c_str());
ConnectorLed.State(true);
Delay_ms(100);
ConnectorLed.State(false);
Delay_ms(100);
}
}
}
else {
SerialPort.SendLine("No recieved");
}
// Wait a second then repeat...
Delay_ms(1000);
}
}