testArduino/mission/DeviceHandler/ArduinoComIF.cpp

329 lines
13 KiB
C++

/*
* Title: ArduinoComIF.cpp
* Author: Marco Modè
* Last version: 24/09/2021
* Project: ESBO-DS
*-------------------------------------------------------------------------------------------------------------------
*
*/
#include <mission/DeviceHandler/ArduinoComIF.h>
#include <mission/DeviceHandler/ArduinoCookie.h>
ArduinoComIF::ArduinoComIF(object_id_t objectId) :
SystemObject(objectId) {
}
ArduinoComIF::~ArduinoComIF() {
}
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF *cookie) {
ArduinoCookie *Cookie = dynamic_cast<ArduinoCookie*>(cookie);
/* The Arduino device which manage the sensors of temperature,
* environmental data and orientation, sends through serial
* output these data employing a USB port.
* Here it is then set-up the interface to manage this communication.
*
* In typical UNIX style, serial ports are represented by files
* within the operating system.
* These files usually pop-up in /dev/, and begin with the name tty*.
*
* To write/read to a serial port, you write/read to the file.
* Here the serial port parameters are defined exploiting a
* special tty configuration struct.
*/
// Set-up of the Linux serial port.
// The serial port is here opened. Change device path as needed.
int serial_port = open("/dev/ttyACM0", O_RDWR);
// Create new termios struc, we call it 'tty' for convention.
struct termios tty;
// Read in existing settings, and handle any error.
if (tcgetattr(serial_port, &tty) != 0) {
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return 1;
}
// Set-up of the configuration serial port.
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size
tty.c_cflag |= CS8; // 8 bits per byte (most common)
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
tty.c_lflag &= ~ICANON; //Canonical mode is disabled
tty.c_lflag &= ~ECHO; // Disable echo
tty.c_lflag &= ~ECHOE; // Disable erasure
tty.c_lflag &= ~ECHONL; // Disable new-line echo
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Disable any special handling of received bytes
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
tty.c_cc[VTIME] = 0; // No blocking time (Arduino complete measurement cycle time is 16 ds)
tty.c_cc[VMIN] = 255; // Limit number of bytes which can be read in one time by Linux serial port
// Set in/out baud rate to be 115200 bps (same of Arduino)
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
// Save tty settings, also checking for error
if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return 1;
}
printf(
"***********************************************************************************************\n");
printf(
"***********************************************************************************************\n");
printf("\nSerial port set. \n");
// End of Linux serial port set-up.
/* The serial port number is saved in the cookie such that it can
* be exploited from other functionalities or components.
*/
Cookie->Serial_port_number = serial_port;
return RETURN_OK;
}
ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie,
const uint8_t *sendData, size_t sendLen) {
return RETURN_OK;
}
ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) {
return RETURN_OK;
}
ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie,
size_t requestLen) {
return RETURN_OK;
}
ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie,
uint8_t **buffer, size_t *size) {
ArduinoCookie *Cookie = dynamic_cast<ArduinoCookie*>(cookie);
// The buffer elements are set to 0 at the beginning of each read-loop.
memset(&read_buf, '\0', sizeof(read_buf));
memset(&read_buf1, '\0', 255);
memset(&read_buf2, '\0', 255);
memset(&read_buf3, '\0', 255);
memset(&read_buf4, '\0', 255);
memset(&read_buf5, '\0', 255);
memset(&read_buf6, '\0', 255);
memset(&read_buf7, '\0', 255);
memset(&read_buf8, '\0', 255);
memset(&read_buf9, '\0', 255);
memset(&read_buf10, '\0', 255);
memset(&read_buf11, '\0', 255);
memset(&read_buf12, '\0', 255);
memset(&read_buf13, '\0', 255);
memset(&read_buf14, '\0', 255);
memset(&read_buf15, '\0', 255);
memset(&read_buf16, '\0', 255);
memset(&read_buf17, '\0', 255);
memset(&read_buf18, '\0', 255);
memset(&read_buf19, '\0', 255);
memset(&read_buf20, '\0', 255);
memset(&read_buf21, '\0', 255);
memset(&read_buf22, '\0', 255);
memset(&read_buf23, '\0', 255);
memset(&read_buf24, '\0', 255);
memset(&read_buf25, '\0', 255);
memset(&read_buf26, '\0', 255);
memset(&read_buf27, '\0', 255);
memset(&read_buf28, '\0', 255);
memset(&read_buf29, '\0', 255);
memset(&read_buf30, '\0', 255);
memset(&read_buf31, '\0', 90);
/* Read bytes. The behaviour of read() depends on the configuration
* settings in initializeInterface, specifically VMIN and VTIME.
*/
int num_bytes1 = read(Cookie->Serial_port_number, &read_buf1,
sizeof(read_buf1));
int num_bytes2 = read(Cookie->Serial_port_number, &read_buf2,
sizeof(read_buf2));
int num_bytes3 = read(Cookie->Serial_port_number, &read_buf3,
sizeof(read_buf3));
int num_bytes4 = read(Cookie->Serial_port_number, &read_buf4,
sizeof(read_buf4));
int num_bytes5 = read(Cookie->Serial_port_number, &read_buf5,
sizeof(read_buf5));
int num_bytes6 = read(Cookie->Serial_port_number, &read_buf6,
sizeof(read_buf6));
int num_bytes7 = read(Cookie->Serial_port_number, &read_buf7,
sizeof(read_buf7));
int num_bytes8 = read(Cookie->Serial_port_number, &read_buf8,
sizeof(read_buf8));
int num_bytes9 = read(Cookie->Serial_port_number, &read_buf9,
sizeof(read_buf9));
int num_bytes10 = read(Cookie->Serial_port_number, &read_buf10,
sizeof(read_buf10));
int num_bytes11 = read(Cookie->Serial_port_number, &read_buf11,
sizeof(read_buf11));
int num_bytes12 = read(Cookie->Serial_port_number, &read_buf12,
sizeof(read_buf12));
int num_bytes13 = read(Cookie->Serial_port_number, &read_buf13,
sizeof(read_buf13));
int num_bytes14 = read(Cookie->Serial_port_number, &read_buf14,
sizeof(read_buf14));
int num_bytes15 = read(Cookie->Serial_port_number, &read_buf15,
sizeof(read_buf15));
int num_bytes16 = read(Cookie->Serial_port_number, &read_buf16,
sizeof(read_buf16));
int num_bytes17 = read(Cookie->Serial_port_number, &read_buf17,
sizeof(read_buf17));
int num_bytes18 = read(Cookie->Serial_port_number, &read_buf18,
sizeof(read_buf18));
int num_bytes19 = read(Cookie->Serial_port_number, &read_buf19,
sizeof(read_buf19));
int num_bytes20 = read(Cookie->Serial_port_number, &read_buf20,
sizeof(read_buf20));
int num_bytes21 = read(Cookie->Serial_port_number, &read_buf21,
sizeof(read_buf21));
int num_bytes22 = read(Cookie->Serial_port_number, &read_buf22,
sizeof(read_buf22));
int num_bytes23 = read(Cookie->Serial_port_number, &read_buf23,
sizeof(read_buf23));
int num_bytes24 = read(Cookie->Serial_port_number, &read_buf24,
sizeof(read_buf24));
int num_bytes25 = read(Cookie->Serial_port_number, &read_buf25,
sizeof(read_buf25));
int num_bytes26 = read(Cookie->Serial_port_number, &read_buf26,
sizeof(read_buf26));
int num_bytes27 = read(Cookie->Serial_port_number, &read_buf27,
sizeof(read_buf27));
int num_bytes28 = read(Cookie->Serial_port_number, &read_buf28,
sizeof(read_buf28));
int num_bytes29 = read(Cookie->Serial_port_number, &read_buf29,
sizeof(read_buf29));
int num_bytes30 = read(Cookie->Serial_port_number, &read_buf30,
sizeof(read_buf30));
int num_bytes31 = read(Cookie->Serial_port_number, &read_buf31,
sizeof(read_buf31));
int num_bytes = num_bytes1 + num_bytes2 + num_bytes3 + num_bytes4
+ num_bytes5 + num_bytes6 + num_bytes7 + num_bytes8 + num_bytes9
+ num_bytes10 + num_bytes11 + num_bytes12 + num_bytes13
+ num_bytes14 + num_bytes15 + num_bytes16 + num_bytes17
+ num_bytes18 + num_bytes19 + num_bytes20 + num_bytes21
+ num_bytes22 + num_bytes23 + num_bytes24 + num_bytes25
+ num_bytes26 + num_bytes27 + num_bytes28 + num_bytes29
+ num_bytes30 + num_bytes31;
// The 11 buffer arrays are here concatenated in one single vector.
std::copy(read_buf1, read_buf1 + 255, read_buf);
std::copy(read_buf2, read_buf2 + 255, read_buf + 255);
std::copy(read_buf3, read_buf3 + 255, read_buf + 2 * 255);
std::copy(read_buf4, read_buf4 + 255, read_buf + 3 * 255);
std::copy(read_buf5, read_buf5 + 255, read_buf + 4 * 255);
std::copy(read_buf6, read_buf6 + 255, read_buf + 5 * 255);
std::copy(read_buf7, read_buf7 + 255, read_buf + 6 * 255);
std::copy(read_buf8, read_buf8 + 255, read_buf + 7 * 255);
std::copy(read_buf9, read_buf9 + 255, read_buf + 8 * 255);
std::copy(read_buf10, read_buf10 + 255, read_buf + 9 * 255);
std::copy(read_buf11, read_buf11 + 255, read_buf + 10 * 255);
std::copy(read_buf12, read_buf12 + 255, read_buf + 11 * 255);
std::copy(read_buf13, read_buf13 + 255, read_buf + 12 * 255);
std::copy(read_buf14, read_buf14 + 255, read_buf + 13 * 255);
std::copy(read_buf15, read_buf15 + 255, read_buf + 14 * 255);
std::copy(read_buf16, read_buf16 + 255, read_buf + 15 * 255);
std::copy(read_buf17, read_buf17 + 255, read_buf + 16 * 255);
std::copy(read_buf18, read_buf18 + 255, read_buf + 17 * 255);
std::copy(read_buf19, read_buf19 + 255, read_buf + 18 * 255);
std::copy(read_buf20, read_buf20 + 255, read_buf + 19 * 255);
std::copy(read_buf21, read_buf21 + 255, read_buf + 20 * 255);
std::copy(read_buf22, read_buf22 + 255, read_buf + 21 * 255);
std::copy(read_buf23, read_buf23 + 255, read_buf + 22 * 255);
std::copy(read_buf24, read_buf24 + 255, read_buf + 23 * 255);
std::copy(read_buf25, read_buf25 + 255, read_buf + 24 * 255);
std::copy(read_buf26, read_buf26 + 255, read_buf + 25 * 255);
std::copy(read_buf27, read_buf27 + 255, read_buf + 26 * 255);
std::copy(read_buf28, read_buf28 + 255, read_buf + 27 * 255);
std::copy(read_buf29, read_buf29 + 255, read_buf + 28 * 255);
std::copy(read_buf30, read_buf30 + 255, read_buf + 29 * 255);
std::copy(read_buf31, read_buf31 + 90, read_buf + 30 * 255);
// num_bytes is the number of bytes read (n=0: no bytes received, n=-1: error).
if (num_bytes < 0) {
printf("Error reading: %s", strerror(errno));
return 1;
}
printf("Read %i bytes.\n", num_bytes);
// Loop to define the adress of the buffer start
/*
* Here it is performed a control loop in order to ensure the identification
* of a full and not-corrupted array of measurement in the buffer defined above.
* The index related to the first byte of the array is saved in the
* variable first_index which is given as output.
* It will then will be exploited in the device handler by ScanForReply and
* InterpreteForReply.
*/
int first_index = 0;
while (first_index < 7740) {
// start character: '['
if (read_buf[first_index] == 91) {
// fourth character: 'S' (First variable is the char [ChStr])
if (read_buf[first_index + 3] == 83) {
// first channel must be channel 1 (SPCChNumber: 1)
if (read_buf[first_index + 9] == 1) {
// last channel of temperature board must be channel 39 (SPCChNumber: 39)
if (read_buf[first_index + 27 * 35 + 9] == 39) {
// 22nd character of last channel of temperature board: 'E' ([ChEnd])
if (read_buf[first_index + 27 * 35 + 22] == 69) {
// second to last channel of orientation board must be channel 122 (SPCChNumber: 122)
if (read_buf[first_index + 27 * 45 + 91 * 13 + 9]
== 122) {
// last channel of orientation board must be channel 123 (SPCChNumber: 123)
if (read_buf[first_index + 27 * 45 + 91 * 14 + 9]
== 123) {
// 69th character of last channel of orientation board: 'E' ([ChEnd])
if (read_buf[first_index + 27 * 45 + 91 * 14
+ 86] == 69) {
break;
} else {
first_index++;
}
} else {
first_index++;
}
} else {
first_index++;
}
} else {
first_index++;
}
} else {
first_index++;
}
} else {
first_index++;
}
} else {
first_index++;
}
} else {
first_index++;
}
}
// Definition of buffer size and buffer array start to return after reading.
*size = num_bytes;
*buffer = &read_buf[first_index];
return RETURN_OK;
}