Controlador Clear Core I/O
Para dispositivos embebidos, hemos incluido un ejemplo que se ejecuta en el controlador ClearCore I/O. Otros dispositivos deberían ser similares.
Objetivo:
Este ejemplo demuestra cómo enviar una solicitud al Burro y leer la respuesta
resultante. También utiliza las funciones splitString
y ParseResponse
que se
pueden encontrar en otra parte.
Descripción:
Este ejemplo enviará una cadena por TTL al Burro solicitando el estado de la estación y esperará una respuesta. Luego analizará esa respuesta para ver si el Burro se ha detenido en una estación y encenderá una luz si es así. También tiene impresiones de depuración informativas que se envían por la conexión serial USB-B del ClearCore. Los errores se imprimen pero, de lo contrario, se ignoran y no se manejan.
Requisitos:
- Una conexión serial TTL entre COM-1 y el robot Burro.
- Un robot Burro con la API de Burro
#define ARDUINOJSON_ENABLE_STD_STRING 1
#undef max
#undef min
#include <sstream>
#include <string>
#include <vector>
#include "ClearCore.h"
// Implementación estándar de splitString.
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;
}
/**
* @brief Toma una cadena formateada como respuesta y devuelve el mensaje original, el
* timestamp, cualquier error y/o los valores devueltos por el backend, si los hay.
* Ejemplo: "%?STTN=1 2_\r" devolvería std::vector<std::string> {"?STTN", "1 0"} donde 1
* es el nanosegundo desde el epoch y 0 es el estado de la estación }
*
* @param[in] response_string La cadena de respuesta formateada, devuelta por la API
*
* @return Un std::vector<std::string> con el mensaje original y la respuesta a ese mensaje
* con los delimitadores eliminados.
*/
std::vector<std::string> ParseResponse(std::string response_string){
// La cadena de respuesta se divide alrededor de un solo signo igual '='. Nunca habrá más de un (1) signo igual
// en una cadena de respuesta.
std::vector<std::string> split_response = splitString(response_string.substr(1), '=');
// El guion bajo '_' indica el final de una respuesta. Estará en la segunda posición del vector junto con el
// timestamp y los valores devueltos. Elimina cualquier carácter después de él.
int loc = split_response[1].find('_');
split_response[1] = split_response[1].substr(0, loc);
// Elimina el porcentaje inicial '%' que indica una respuesta. Aquí se puede realizar lógica para verificar que
// el mensaje esté correctamente formateado.
std::string s = split_response[1];
// Determina si hay un error en la respuesta.
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;
}
// Devuelve el vector para saber qué respuesta corresponde a qué comando original.
return split_response;
}
// Selecciona la velocidad de baudios para que coincida con el dispositivo objetivo.
#define baudRateSerialPort 115200
#define baudRateInputPort 115200
// Especifica qué interfaz serial usar como salida.
#define SerialPort ConnectorUsb
// Especifica qué interfaz serial usar como entrada.
#define InputPort ConnectorCOM1
// Contenedor para el byte a leer
int16_t input;
int main() {
// Configura la comunicación serial para imprimir la entrada serial.
SerialPort.Mode(Connector::USB_CDC);
SerialPort.Speed(baudRateSerialPort);
SerialPort.PortOpen();
// Configura la comunicación por el puerto COM para comunicarte con 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) {
// Envía la solicitud de la información que deseas, en este caso el estado de la estación
InputPort.Send("?STTN_\r");
Delay_ms(100);
// Crea una cadena y lee el primer carácter
std::string response = "";
input = InputPort.CharGet();
// Mientras haya bytes para leer, léelos y añádelos a nuestra cadena de respuesta
while (input != -1) {
response += (char)input;
input = InputPort.CharGet();
}
// Si se leyó una cadena, analízala y realiza la lógica.
if (response != "") {
// Muestra la cadena recibida. Principalmente para depuración, si no tienes un monitor
// conectado por USB-B, comenta esto.
SerialPort.Send("Received:");
SerialPort.SendLine((" " + response).c_str());
// Analiza la respuesta para comenzar a realizar la lógica. El comando enviado está en la posición 0
// del vector.
std::vector<std::string> parsed_response = ParseResponse(response);
if ( parsed_response[0] == "?STTN") {
// El parser tiene la respuesta de la API al request en la posición 1 del vector.
// Divide esto en espacios para obtener el timestamp y los argumentos devueltos. ?STTN solo debería
// devolver un argumento junto al timestamp. Será 0 si no está en una estación y 1 si está detenido
// en una estación.
std::vector<std::string> split_station_response = splitString(parsed_response[1], ' ');
if (split_station_response[1] == "1"){
// Haz lo que quieras si estás detenido en una estación. Yo imprimo por USB-B y
// enciendo el LED incorporado en la placa ClearCore.
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 recibido");
}
// Espera un segundo y repite...
Delay_ms(1000);
}
}
¿Esta página le ayudó?