Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed MODSERIAL FATFileSystem
MbedLogger/MbedLogger.cpp
- Committer:
- joel_ssc
- Date:
- 2019-02-15
- Revision:
- 82:0981b9ada820
- Parent:
- 80:4e5d306d695b
- Child:
- 84:eccd8e837134
File content as of revision 82:0981b9ada820:
#include "MbedLogger.hpp"
#include "StaticDefs.hpp"
#include <stdarg.h>
//Timer t; //used to test time to create packet //timing debug
MbedLogger::MbedLogger(string file_system_input_string) {
_file_system_string = file_system_input_string; // how to make the LOG000.csv a variable string?
_full_file_path_string = _file_system_string + "LOG000.csv"; //use multiple logs in the future? (after file size is too large)
_full_diagfile_path_string = _file_system_string + "DIAG000.txt";
_file_number = 0;
_file_transmission = true;
_confirmed_packet_number = 0; //must set this to zero
_transmit_counter = 0;
_file_transmission_state = -1;
_total_number_of_packets = 0;
_mbed_transmit_loop = false;
_received_filename = "";
_log_file_line_counter = 0; //used to set timer in finite state machine based on size of log
//heading string is 254 bytes long, FIXED LENGTH
_heading_string = "StateStr,St#,TimeSec,DepthCmd,DepthFt,PitchCmd,PitchDeg,RudderPWM,RudderCmdDeg,HeadDeg,bceCmd,bce_mm,battCmd,batt_mm,PitchRateDegSec,depth_rate_fps,SystemAmps,SystemVolts,AltChRd,Int_PSI,BCE_p,i,d,BATT_p,i,d,DEPTH_p,i,d,fq,db,PITCH_p,i,d,HEAD_p,i,d,fq,db\n";
_diag_heading_string = "Diagnostics file header \n";
_fsm_transmit_complete = false;
_end_transmit_packet = false;
_end_sequence_transmission = false;
}
//this function has to be called for the time to function correctly
void MbedLogger::setLogTime() {
xbee().printf("\n%s log time set.\n\r", _file_system_string.c_str());
set_time(1518467832); // Set RTC time to Mon, 12 FEB 2018 15:37
}
//in the future create the ability to set the start time
int MbedLogger::getSystemTime() {
time_t seconds = time(NULL); // Time as seconds since January 1, 1970
return seconds;
}
void MbedLogger::recordData(int current_state) {
int data_log_time = mbedLogger().getSystemTime(); //read the system timer to get unix timestamp
int start_time = 1518467832;
_data_log[0] = depthLoop().getCommand(); //depth command
_data_log[1] = depthLoop().getPosition(); //depth reading (filtered depth)
_data_log[2] = pitchLoop().getCommand(); //pitch command
_data_log[3] = pitchLoop().getPosition(); //pitch reading (filtered pitch)
_data_log[4] = rudder().getSetPosition_pwm(); //rudder command PWM
_data_log[5] = rudder().getSetPosition_deg(); //rudder command DEG
_data_log[6] = headingLoop().getPosition(); //heading reading (filtered heading)
_data_log[7] = bce().getSetPosition_mm(); //BCE command
_data_log[8] = bce().getPosition_mm(); //BCE reading
_data_log[9] = batt().getSetPosition_mm(); //Batt command
_data_log[10] = batt().getPosition_mm(); //Batt reading
_data_log[11] = pitchLoop().getVelocity(); // pitchRate_degs (degrees per second)
_data_log[12] = depthLoop().getVelocity(); // depthRate_fps (feet per second)
_data_log[13] = sensors().getCurrentInput(); // i_in
_data_log[14] = sensors().getVoltageInput(); // v_in
_data_log[15] = sensors().getAltimeterChannelReadings(); // Altimeter Channel Readings
_data_log[16] = sensors().getInternalPressurePSI(); // int_press_PSI
//BCE_p,i,d,freq,deadband
_data_log[17] = bce().getControllerP();
_data_log[18] = bce().getControllerI();
_data_log[19] = bce().getControllerD();
_data_log[20] = batt().getControllerP();
_data_log[21] = batt().getControllerI();
_data_log[22] = batt().getControllerD();
_data_log[23] = depthLoop().getControllerP();
_data_log[24] = depthLoop().getControllerI();
_data_log[25] = depthLoop().getControllerD();
_data_log[26] = depthLoop().getFilterFrequency();
_data_log[27] = depthLoop().getDeadband();
_data_log[28] = pitchLoop().getControllerP();
_data_log[29] = pitchLoop().getControllerI();
_data_log[30] = pitchLoop().getControllerD();
_data_log[31] = headingLoop().getControllerP();
_data_log[32] = headingLoop().getControllerI();
_data_log[33] = headingLoop().getControllerD();
_data_log[34] = headingLoop().getFilterFrequency();
_data_log[35] = headingLoop().getDeadband();
string string_state;
if (current_state == SIT_IDLE)
string_state = "SIT_IDLE";
else if (current_state == FIND_NEUTRAL)
string_state = "FIND_NEUTRAL";
else if (current_state == DIVE)
string_state = "DIVE";
else if (current_state == RISE)
string_state = "RISE";
else if (current_state == FLOAT_LEVEL)
string_state = "FLOAT_LEVEL";
else if (current_state == FLOAT_BROADCAST)
string_state = "FLOAT_BROADCAST";
else if (current_state == EMERGENCY_CLIMB)
string_state = "EMERGENCY_CLIMB";
else if (current_state == MULTI_DIVE)
string_state = "MULTI_DIVE";
else if (current_state == MULTI_RISE)
string_state = "MULTI_RISE";
else if (current_state == KEYBOARD)
string_state = "KEYBOARD";
else if (current_state == CHECK_TUNING)
string_state = "CHECK_TUNING";
else if (current_state == POSITION_DIVE)
string_state = "POSITION_DIVE";
else if (current_state == POSITION_RISE)
string_state = "POSITION_RISE";
else if (current_state == TX_MBED_LOG)
string_state = "TX_MBED_LOG";
else if (current_state == RX_SEQUENCE)
string_state = "RECEIVE_SEQUENCE";
else if (current_state == LEG_POSITION_DIVE)
string_state = "LEG_POS_DIVE";
else if (current_state == LEG_POSITION_RISE)
string_state = "LEG_POS_RISE";
else if (current_state == FB_EXIT)
string_state = "FB_EXIT";
string blank_space = ""; //to get consistent spacing in the file (had a nonsense char w/o this)
//below this format is used for data transmission, each packet needs to be 254 characters long (not counting newline char)
//verified that this generates the correct line length of 254 using SOLELY an mbed 08/16/2018
fprintf(_fp, "%17s,%.2d,%10d,%5.1f,%5.1f,%6.1f,%6.1f,%4.0f,%4.0f,%6.1f,%5.1f,%6.1f,%5.1f,%6.1f,%6.1f,%6.1f,%6.3f,%6.2f,%5.0f,%6.2f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%6.2f,%5.3f,%5.3f,%4.1f,%4.1f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%4.1f,%4.1f\n",
string_state.c_str(),current_state,data_log_time-start_time,
_data_log[0],_data_log[1],_data_log[2],_data_log[3],_data_log[4],_data_log[5],_data_log[6],_data_log[7],_data_log[8],_data_log[9],_data_log[10],_data_log[11],_data_log[12],_data_log[13],_data_log[14],_data_log[15],
_data_log[16],_data_log[17],_data_log[18],_data_log[19],_data_log[20],_data_log[21],_data_log[22],_data_log[23],_data_log[24],_data_log[25],_data_log[26],_data_log[27],_data_log[28],_data_log[29],_data_log[30],
_data_log[31],_data_log[32],_data_log[33],_data_log[34],_data_log[35]);
//each line in the file is 160 characters long text-wise, check this with a file read
}
void MbedLogger::printMbedDirectory() {
DIR *dir;
struct dirent *dp; //dirent.h is the format of directory entries
int log_found =0,loop=0;
long int temp=0;
//char * char_pointer;
char * numstart;
//char *numstop;
xbee().printf("\n\rPrinting out the directory of device %s\n\r", _file_system_string.c_str());
if ( NULL == (dir = opendir( _file_system_string.c_str() )) ) {
xbee().printf("MBED directory could not be opened\r\n");
}
else
{
while ( NULL != (dp = readdir( dir )) )
{
if(strncmp(dp->d_name,"LOG",3)==0)
{
log_found=1;
/*numstart = dp->d_name; //Look for third character (do safety)
numstop = strchr(dp->d_name,'.');
if(numstart!=NULL&&numstop!=NULL)
{
temp=numstop-numstart;
}
else
log_found=0; //Something is not right. Ignore
*/
numstart=dp->d_name+3;
temp=strtol(numstart,NULL,10); //add in check to see if this is null (start logs at one)
}
else
log_found=0;
xbee().printf( "%d. %s (log file: %d, %d)\r\n", loop, dp->d_name,log_found,temp);
loop++;
}
}
}
//prints current log file to the screen (terminal)
void MbedLogger::printCurrentLogFile() {
//open the file for reading
string file_name_string = _file_system_string + "LOG000.csv";
_log_file_line_counter = 0;
_fp = fopen(file_name_string.c_str(), "r");
char buffer[500];
//read the file line-by-line and print that to the screen
xbee().printf("\n\rCURRENT MBED LOG FILE /local/Log%03d.csv:\n\n\r",_file_number);
while (!feof(_fp)) {
// read in the line and make sure it was successful
if (fgets(buffer,500,_fp) != NULL) { //stops at new line
xbee().printf("%s\r",buffer);
_log_file_line_counter++;
}
}
//fgets stops when either (n-1) characters are read, the newline character is read,
// or the end-of-file is reached
//close the file
closeLogFile();
xbee().printf("\n\rLog file closed. Lines in log file: %d.\n\r", _log_file_line_counter);
}
void MbedLogger::blastData() {
xbee().printf("blastData FUNCTION\n\r");
//OPEN FILE FOR READING
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "r");
/******************************/
while(1) {
wait(0.05);
if (!feof(_fp)) { //check for end of file
//based on the internal packet number of the class //createDataPacket //transmit data packet
transmitPacketNumber(_packet_number);
xbee().printf("\r"); // for proper spacing
_packet_number++;
}
else {
_packet_number = 0; //reset packet number
break;
}
}
/******************************/
//CLOSE THE FILE
closeLogFile();
xbee().printf("\n\rblastData: Log file closed. %d.\n\r");
}
void MbedLogger::createDataPacket() {
// packet is 7565 0001 FFFF EEEE CC DATA DATA DATA ... CRC1 CRC2
//CLEAR: Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.
_data_packet.clear();
//DATA PACKET HEADER
_data_packet.push_back(117); //0x75
_data_packet.push_back(101); //0x65
_data_packet.push_back(_packet_number/256); //current packet number in 0x#### form
_data_packet.push_back(_packet_number%256); //current packet number in 0x#### form
_data_packet.push_back(_total_number_of_packets/256); //total number of packets, 0x#### form
_data_packet.push_back(_total_number_of_packets%256); //total number of packets, 0x#### form
_data_packet.push_back(_current_line_length);
//xbee().printf("DEBUG: Current line buffer: %s\n\r", _line_buffer); //debug
//DATA FROM LINE READ (read string character by chracter)
for (int i = 0; i < _current_line_length; i++) {
_data_packet.push_back(_line_buffer[i]);
}
//CRC CALCULATIONS BELOW
//character version of calculation screws up on null character 0x00, scrapped and using vector of integers
int crc_one = calcCrcOne();
int crc_two = calcCrcTwo();
//place the crc bytes into the data packet that is transmitted
_data_packet.push_back(crc_one);
_data_packet.push_back(crc_two);
}
//new 6/27/2018
void MbedLogger::createDataPacket(char line_buffer_sent[], int line_length_sent) {
// packet is 7565 0001 FFFF EEEE CC DATA DATA DATA ... CRC1 CRC2
//CLEAR: Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.
_data_packet.clear();
//DATA PACKET HEADER
_data_packet.push_back(117); //0x75
_data_packet.push_back(101); //0x65
_data_packet.push_back(_packet_number/256); //current packet number in 0x#### form
_data_packet.push_back(_packet_number%256); //current packet number in 0x#### form
_data_packet.push_back(_total_number_of_packets/256); //total number of packets, 0x#### form
_data_packet.push_back(_total_number_of_packets%256); //total number of packets, 0x#### form
_data_packet.push_back(line_length_sent);
//xbee().printf("DEBUG: Current line buffer: %s\n\r", _line_buffer); //debug
//DATA FROM LINE READ (read string character by chracter)
for (int i = 0; i < line_length_sent; i++) {
_data_packet.push_back(line_buffer_sent[i]);
}
//CRC CALCULATIONS BELOW
//character version of calculation screws up on null character 0x00, scrapped and using vector of integers
int crc_one = calcCrcOne();
int crc_two = calcCrcTwo();
//place the crc bytes into the data packet that is transmitted
_data_packet.push_back(crc_one);
_data_packet.push_back(crc_two);
//xbee().printf("debug createDataPacket(char line_buffer_sent[], int line_length_sent)\n\r");
}
//should i save it as a string and transmit the string? next iteration maybe
void MbedLogger::transmitDataPacket() {
//WRITE the data (in bytes) to the serial port
for (_it=_data_packet.begin(); _it < _data_packet.end(); _it++) {
xbee().putc(*_it); //send integers over serial port one byte at a time
}
}
// test to see if transmitDataPacket is working slower than you think.
// REACH ONE CHAR AT A TIME (EACH ITERATION OF STATE MACHINE...)
void MbedLogger::continuouslyTransmitDataNoTimer() {
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "r");
static int packet_num = 0;
while(!feof(_fp)) {
_packet_number = packet_num;
readPacketInSeries(); //not using this but for testing purposes...
// // createDataPacket requires _packet_number, _total_number_of_packets, _current_line_length (data packet size)
// // uses char _line_buffer[256] variable to hold characters read from the file
// // packs this into a vector for transmission
createDataPacket();
transmitDataPacket();
packet_num++;
led3() = !led3();
//check for incoming request
}
closeLogFile(); //close log file if open
led4() = !led4();
}
void MbedLogger::fsmTransmitData() { //using the finite state machine
if ( !feof(_fp) and (!_fsm_transmit_complete) ) { //check for end of file
//based on the internal packet number of the class //createDataPacket //transmit data packet
transmitPacketNumber(_packet_number);
xbee().printf("\r"); // for proper spacing
_packet_number++;
led2() = !led2();
}
else {
_packet_number = 0; //reset packet number
_fsm_transmit_complete = true;
led3() = !led3();
}
}
//transmitting log file with fixed length of characters to receiver program
void MbedLogger::transmitPacketNumber(int line_number) {
int line_size = 254; //length of lines in the log file, EVERY LINE MUST BE THE SAME LENGTH
fseek(_fp,(line_size+1)*line_number,SEEK_SET); //fseek must use the +1 to get the newline character
//write over the internal _line_buffer //start from the beginning and go to this position
fread(_line_buffer, 1, line_size, _fp); //read the line that is exactly 160 characters long
//xbee().printf("Debug (transmitPacketNumber): line_buffer <<%s>> (line size: %d)\n\r", line_buffer,line_size);
// createDataPacket requires _packet_number, _total_number_of_packets, _current_line_length (data packet size)
// uses char _line_buffer[256] variable to hold characters read from the file
// packs this into a vector for transmission
//change the internal member variable for packet number, reorg this later
_packet_number = line_number;
createDataPacket(_line_buffer, line_size); //create the data packet from the _line_buffer (char array)
transmitDataPacket(); //transmit the assembled packet
}
//receive correct data packet from python, immediately send a transmit packet from the MBED
void MbedLogger::transmitOnePacket() {
xbee().printf("transmitOnePacket\n");
static int transmit_state = HEADER_117; //state in switch statement
//int incoming_byte = -1; //reset each time a character is read
int requested_packet_number = -1; //reset each time a character is read
static int input_packet[4]; //changed from char in previous iteration 03/28/2018
static int transmit_crc_one = 0; //hold crc values until they're reset with calculations
static int transmit_crc_two = 0;
int incoming_byte[6];
static int bytes_received = 0;
int req_packet_number = -1;
while (1) {
incoming_byte[bytes_received] = xbee().getc();
xbee().printf("<%d> ", incoming_byte[bytes_received]);
bytes_received++;
if (bytes_received > 5) {
req_packet_number = incoming_byte[2] * 256 + incoming_byte[3];
xbee().printf("req_packet_number = %d\n\r", req_packet_number);
bytes_received = 0;
break;
}
}
setTransmitPacketNumber(0);
//open the file
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "r");
//receive correct checksum, immediately send this packet
transmitPacketNumber(req_packet_number);
//fclose(_fp);
closeLogFile();
}
void MbedLogger::transmitMultiplePackets() {
xbee().printf("transmitMultiplePackets\n");
//static int transmit_state = HEADER_117; //state in switch statement
//int incoming_byte = -1; //reset each time a character is read
//int requested_packet_number = -1; //reset each time a character is read
static int input_packet; //changed from char in previous iteration 03/28/2018
static int transmit_crc_one = 0; //hold crc values until they're reset with calculations
static int transmit_crc_two = 0;
int current_byte = -1;
static int bytes_received = 0;
int req_packet_number = -1;
//GET TOTAL NUMBER OF PACKETS!
getNumberOfPacketsInCurrentLog();
//GET TOTAL NUMBER OF PACKETS!
//open the file
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "r");
//DEFAULT STATE
static int current_state = HEADER_117;
bool active_loop = true;
while (active_loop) {
//INCOMING BYTE
current_byte = xbee().getc();
//provide the next byte / state
switch (current_state) {
case HEADER_117:
//xbee().printf("HEADING 117\n\r");
if (current_byte == 0x75) {
current_state = HEADER_101;
}
else if (current_byte == 0x10) {
current_state = END_TX_1;
}
break;
case HEADER_101:
//xbee().printf("HEADING 101\n\r");
if (current_byte == 0x65) {
current_state = PACKET_NO_1;
}
break;
case PACKET_NO_1:
//xbee().printf("PACKET_NO_1\n\r");
input_packet = current_byte * 256;
current_state = PACKET_NO_2;
//xbee().printf("PACKET # 1 current byte %d\n\r", current_byte);
break;
case PACKET_NO_2:
//xbee().printf("PACKET_NO_2\n\r");
input_packet = input_packet + current_byte;
current_state = PACKET_CRC_ONE;
//xbee().printf("PACKET # 2 current byte %d (req packet num: %d)\n\r", current_byte, input_packet);
break;
case PACKET_CRC_ONE:
//xbee().printf("PACKET_CRC_ONE\n\r");
current_state = PACKET_CRC_TWO;
break;
case PACKET_CRC_TWO:
//xbee().printf("PACKET_CRC_TWO\n\r");
current_state = HEADER_117;
transmitPacketNumber(input_packet);
break;
case END_TX_1:
//xbee().printf("END_TX_1\n\r");
current_state = END_TX_2;
break;
case END_TX_2:
//xbee().printf("END_TX_2\n\r");
current_state = HEADER_117;
active_loop = false;
break;
default:
//reset state
//xbee().printf("DEFAULT. HEADER_117\n\r");
current_state = HEADER_117; //reset here
break;
}
}
//CLOSE THE FILE
closeLogFile();
xbee().printf("08/05/2018 CLOSE THE LOG FILE\n\r");
//RESET THE STATE
//current_state = HEADER_117;
}
void MbedLogger::checkForPythonTransmitRequest() {
//xbee().printf("checkForPythonTransmitRequest\n");
if ( xbee().readable() ) {
//PC READABLE DOES NOT WORK HERE?!
led2() = !led2();
led3() = !led3();
xbee().printf("########################\n");
//xbee().printf("%d", xbee().getc());
}
// static int transmit_state = HEADER_117; //state in switch statement
// //int incoming_byte = -1; //reset each time a character is read
// int requested_packet_number = -1; //reset each time a character is read
// static int input_packet[4]; //changed from char in previous iteration 03/28/2018
// static int transmit_crc_one = 0; //hold crc values until they're reset with calculations
// static int transmit_crc_two = 0;
//
// static int incoming_byte[6];
//
// static int bytes_received = 0;
//
// int req_packet_number = -1;
//
// if (xbee().readable()) {
// incoming_byte[bytes_received] = xbee().getc();
// xbee().printf("<%d> ", incoming_byte[bytes_received]);
//
// bytes_received++;
//
// if (bytes_received > 5) {
//
// req_packet_number = incoming_byte[2] * 256 + incoming_byte[3];
//
// xbee().printf("req_packet_number = %d\n\r", req_packet_number);
//
// //reset
// bytes_received = 0;
// }
// }
//
// //setTransmitPacketNumber(0);
//
// /* OPEN THE FILE */
// string file_name_string = _file_system_string + "LOG000.csv";
//_fp = fopen(file_name_string.c_str(), "r");
/* RECEIVE CORRECT CHECKSUM, SEND PACKET */
//transmitPacketNumber(req_packet_number);
//fclose(_fp);
// switch(transmit_state) {
// case HEADER_117:
// led3() = !led3();
//
// //continue processing
// if (incoming_byte == 117){ //"u"
// transmit_state = HEADER_101;
// }
// //did not receive byte 1
// else {
// transmit_state = HEADER_117; //go back to checking the first packet
// }
// break;
//
// case HEADER_101:
// if(incoming_byte == 101) { //"e"
// transmit_state = TRANSMIT_PACKET_1;
// //xbee().printf(" U E \n\r");
// }
// else {
// transmit_state = HEADER_117;
// }
// break;
//
// case TRANSMIT_PACKET_1:
// if (incoming_byte >= 0) {
// input_packet[0] = 117;
// input_packet[1] = 101;
// input_packet[2] = incoming_byte;
//
// transmit_state = TRANSMIT_PACKET_2;
// //_reply_byte3 = incoming_byte;
//
// led1() = !led1();
// //xbee().printf(" T P \n\r");
// //xbee().printf("DEBUG: Transmit Packet %d\n\r", incoming_byte);
// }
// break;
//
// case TRANSMIT_PACKET_2:
//
// if (incoming_byte >= 0) {
// input_packet[3] = incoming_byte;
// //_reply_byte4 = incoming_byte;
// }
// transmit_state = PACKET_CRC_ONE;
//
// break;
//
// case (PACKET_CRC_ONE):
// transmit_crc_one = calcCrcOneArray(input_packet, 4); //calc CRC 1 from the input packet (size 4)
//
// if (incoming_byte == transmit_crc_one) {
// transmit_state = PACKET_CRC_TWO;
// }
//
// else
// transmit_state = HEADER_117;
// //or state remains the same?
//
// break;
//
// case (PACKET_CRC_TWO):
// transmit_state = HEADER_117;
// transmit_crc_two = calcCrcTwoArray(input_packet, 4); //calc CRC 2 from the input packet (size 4)
//
// //check if CRC TWO is correct (then send full packet)
// if (incoming_byte == transmit_crc_two) {
// requested_packet_number = input_packet[2] * 256 + input_packet[3]; //compute the numbers 0 through 65535 with the two bytes
//
// //receive correct checksum, immediately send this packet
// transmitPacketNumber(requested_packet_number);
//
// //fseek(_fp, 0, SEEK_END); //reset _fp (this was causing errors with the other function)
// led3() = !led3();
//
// } //end of checksum (incoming_byte) if statement
//
// break;
// } //switch statement complete
// } //while statement complete
}
int MbedLogger::readTransmitPacket() {
_file_transmission = true;
_file_transmission_state = 0;
//first check if you're receiving data, then read four bytes
int transmit_state = 0; //for state machine
int incoming_byte = -1;
int requested_packet_number = -1;
static int inside_while_loop = 1;
while (inside_while_loop) {
if (xbee().readable()) { //don't rely on pc readable being open all the time
incoming_byte = xbee().getc();
switch(transmit_state) {
case (HEADER_117):
//continue processing
if (incoming_byte == 117){
transmit_state = HEADER_101;
}
//end transmission
else if (incoming_byte == 16) {
transmit_state = END_TRANSMISSION;
}
else {
transmit_state = HEADER_117;
}
break;
case (HEADER_101):
if(incoming_byte == 101) {
transmit_state = TRANSMIT_PACKET_1;
}
break;
case (TRANSMIT_PACKET_1):
if (incoming_byte >= 0) {
transmit_state = TRANSMIT_PACKET_2;
_reply_byte3 = incoming_byte;
}
break;
case (TRANSMIT_PACKET_2):
if (incoming_byte >= 0) {
_reply_byte4 = incoming_byte;
}
requested_packet_number = _reply_byte3 * 256 + _reply_byte4; //compute the numbers 0 through 65535 with the two bytes
if (requested_packet_number != _previous_reply_byte) { //CHANGE THE NAME TO SOMETHING NOT BYTE!
//MUST SET THE PACKET NUMBER
_packet_number = requested_packet_number;
readPacketInSeries();
createDataPacket();
_previous_reply_byte = requested_packet_number; //RECORD THIS BYTE to prevent new packets being created
}
//continuously transmit current packet until it tells you to do the next packet (response from Python program)
transmitDataPacket();
//TRANSMIT_PACKET_2
inside_while_loop = 0; //exit the while loop with this
xbee().printf("(TRANSMIT_PACKET_2)reached inside_while_loop = 0\n\r"); //DEBUG
break;
} //end of switch statement
} //end of while loop
// else {
// //xbee().printf("pc not readable \n\r");
// }
//
}
//once you're outside of the while loop
inside_while_loop = true; //for next iteration
xbee().printf("DEBUG: (readTransmitPacket) Outside of while loop\n\r");
return false;
}
bool MbedLogger::endTransmitPacket() {
int incoming_byte;
while (xbee().readable()) {
incoming_byte = xbee().getc(); //get first byte
if (incoming_byte == 16) {
incoming_byte = xbee().getc(); //get second byte
return true;
}
//quick and dirty
}
return false;
}
void MbedLogger::reOpenLineReader() {
//open a new one
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "r"); //open the log file to read
//check if this actually worked...
if (!_fp) {
xbee().printf("ERROR: Log file could not be opened\n\r");
}
else {
xbee().printf("Current Log file (LOG000.csv) was opened.\n\r");
}
}
bool MbedLogger::openLineReader() {
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "r"); //open the log file to read
//check if this actually worked...
if (!_fp) {
//xbee().printf("ERROR: Log file could not be opened\n\r");
return false;
}
else {
//xbee().printf("Current Log file (LOG000.csv) was opened.\n\r");
return true;
}
}
//VERIFIED THIS IS WORKING
void MbedLogger::readPacketInSeries(){
memset(&_line_buffer[0], 0, sizeof(_line_buffer)); //clear buffer each time, start at the address, fill with zeroes, go to the end of the char array
//read the current line in the file
fgets(_line_buffer, 256, _fp); //reads the line of characters until you reach a newline character
//RECORD THE STRING LENGTH
_current_line_length = strlen(_line_buffer);
}
int MbedLogger::getNumberOfPacketsInCurrentLog() {
//takes less than a second to complete, verified 7/24/2018
//open the file
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "r");
fseek(_fp, 0L, SEEK_END);
size_t size = ftell(_fp);
//move the FILE pointer back to the start
fseek(_fp, 0, SEEK_SET); // SEEK_SET is the beginning of file
_total_number_of_packets = size/254;
//CLOSE THE FILE
closeLogFile();
return _total_number_of_packets;
}
void MbedLogger::endTransmissionCloseFile() {
// if the file pointer is null, the file was not opened in the first place
if (!_fp) {
xbee().printf("\n endTransmissionCloseFile: FILE WAS NOT OPENED!\n\r");
}
else {
xbee().printf("\n endTransmissionCloseFile: FILE FOUND AND CLOSED!\n\r");
closeLogFile();
}
_file_transmission = false;
}
void MbedLogger::openWriteFile() {
xbee().printf("Opening file for reception.\n\r");
string file_name_string = _file_system_string + "LOG000.csv";
_fp = fopen(file_name_string.c_str(), "w");
}
//weird bug noticed on 5/25/2018 where if you're not sending data the function is not completing
// function checks for incoming data (receiver function) from a Python program that transmits a file
// current limit is a file that has 255 lines of data
bool MbedLogger::checkForIncomingData() {
int receive_packet_number;
int receive_total_number_packets;
int receive_packet_size;
bool data_transmission_complete = false;
int incoming_byte;
char char_buffer[256] = {}; //create empty buffer
//starting state
int process_state = HEADER_117;
//variables for processing data below
int checksum_one = -1;
int checksum_two = -1;
int i = 5;
int serial_timeout = 0;
while (xbee().readable() && !data_transmission_complete) {
incoming_byte = xbee().getc(); //getc returns an unsigned char cast to an int
//xbee().printf("DEBUG: State 0\n\r");
switch(process_state) {
case HEADER_117:
//continue processing
if (incoming_byte == 117){
process_state = HEADER_101;
//xbee().printf("DEBUG: Case 117\n\r");
}
//end transmission
else if (incoming_byte == 16) {
process_state = END_TRANSMISSION;
//xbee().printf("DEBUG: State 16 (END_TRANSMISSION)\n\r");
}
else {
process_state = HEADER_117; // ???
//xbee().printf("DEBUG: State Header 117\n\r");
}
break;
case HEADER_101:
if(incoming_byte == 101) {
process_state = PACKET_NUM;
//xbee().printf("DEBUG: Case 101\n\r");
}
break;
case PACKET_NUM:
receive_packet_number = incoming_byte;
process_state = TOTAL_NUM_PACKETS;
//xbee().printf("DEBUG: Case PACKET_NUM\n\r");
break;
case TOTAL_NUM_PACKETS:
receive_total_number_packets = incoming_byte;
process_state = PACKET_SIZE;
//xbee().printf("DEBUG: Case TOTAL_NUM_PACKETS\n\r");
break;
case PACKET_SIZE:
receive_packet_size = incoming_byte;
//xbee().printf("DEBUG: Case PACKET_SIZE\n\r");
//write the header stuff to it
char_buffer[0] = 117;
char_buffer[1] = 101;
char_buffer[2] = receive_packet_number;
char_buffer[3] = receive_total_number_packets;
char_buffer[4] = receive_packet_size;
// tests confirmed that packet number is zero, number of packets is 12, packet size is 12
//xbee().printf("char_buffer 2/3/4: %d %d %d\n\r", receive_packet_number,receive_total_number_packets,receive_packet_size);
//process packet data, future version will append for larger data sizes, 0xFFFF
// IF YOU GET AN INTERRUPTED DATA STREAM YOU NEED TO BREAK OUT OF THE LOOP
i = 5;
serial_timeout = 0;
while (true) {
if (xbee().readable()) {
char_buffer[i] = xbee().getc(); //read all of the data packets
i++;
serial_timeout = 0; //reset the timeout
}
else {
serial_timeout++;
}
// When full data packet is received...
if (i >= receive_packet_size+5) { //cannot do this properly with a for loop
//get checksum bytes
checksum_one = xbee().getc();
checksum_two = xbee().getc();
//calculate the CRC from the header and data bytes using _data_packet (vector)
//found out calculating crc with string was dropping empty or null spaces
_data_packet.clear(); //clear it just in case
for (int a = 0; a < receive_packet_size+5; a++) {
_data_packet.push_back(char_buffer[a]); //push the character array into the buffer
}
//calculate the CRC using the vector (strings will cut off null characters)
int calc_crc_one = calcCrcOne();
int calc_crc_two = calcCrcTwo();
//xbee().printf("DEBUG: calc crc 1: %d, crc 2: %d\n\r", calc_crc_one, calc_crc_two);
// first confirm that the checksum is correct
if ((calc_crc_one == checksum_one) and (calc_crc_two == checksum_two)) {
//xbee().printf("DEBUG: checksums are good!\n\r");
//xbee().printf("receive_packet_number %d and _confirmed_packet_number %d\n\r", receive_packet_number, _confirmed_packet_number); //debug
// // CHECKSUM CORRECT & get the filename from the first packet (check that you receive first packet)
// if (receive_packet_number == 0) {
// char temp_char[receive_packet_size+1]; //temp array for memcpy
// memset(&temp_char[0], 0, sizeof(temp_char)); //clear full array (or get random characters)
// strncpy(temp_char, char_buffer + 5 /* Offset */, receive_packet_size*sizeof(char) /* Length */); //memcpy introduced random characters
//
// //xbee().printf("SEQUENCE: <<%s>>\n\r", temp_char]) // ERASE
//
// //have to terminate the string with '\0'
// temp_char[receive_packet_size] = '\0';
//
// //xbee().printf("\n\rDEBUG: ------ Filename? <<%s>>\n\r", temp_char);
// //_received_filename = temp_char;
//
// //xbee().printf("\n\rDEBUG: _received_filename <<%s>>\n\r", _received_filename);
//
// //open a file for writing
// //openReceiveFile(_received_filename);
//
// //send a reply to Python transmit program
// sendReply();
//
// led3() = 1;
//
// // even if correct CRC, counter prevents the program from writing the same packet twice
// _confirmed_packet_number++;
// }
// check if the packet that you're receiving (receive_packet_number) has been received already...
//CHECKSUM CORRECT & packet numbers that are 1 through N packets
if (receive_packet_number == _confirmed_packet_number){
//save the data (char buffer) to the file if both checksums work...
// when a packet is received (successfully) send a reply
//sendReply();
// write correct data to file
fprintf(_fp, "%s", char_buffer+5);
// even if correct CRC, counter prevents the program from writing the same packet twice
_confirmed_packet_number++;
}
//clear the variables
checksum_one = -1;
checksum_two = -1;
}
process_state = HEADER_117;
break;
}
// //counter breaks out of the loop if no data received
// if (serial_timeout >= 10000) {
// //xbee().printf("break serial_timeout %d\n\r", serial_timeout);
// break;
// }
}
break;
case END_TRANSMISSION:
if (xbee().getc() == 16) {
//xbee().printf("DEBUG: END_TRANSMISSION REACHED: 1. \n\r");
if (xbee().getc() == 16) {
//xbee().printf("DEBUG: END_TRANSMISSION REACHED: 2. \n\r");
_end_sequence_transmission = true;
//endReceiveData();
}
}
//xbee().printf("DEBUG: END_TRANSMISSION REACHED: 5. \n\r");
//process_state = HEADER_117; //don't do this unless the check is wrong
//xbee().printf("END_TRANSMISSION process_state is %d\n\r", process_state); //should be 5 (debug) 02/06/2018
data_transmission_complete = true;
break;
}//END OF SWITCH
if (data_transmission_complete) {
//xbee().printf("DEBUG: checkForIncomingData data_transmission_complete \n\r");
break; //out of while loop
}
} // while loop
led3() = !led3();
if (data_transmission_complete)
return false; //tell state machine class that this is done (not transmitting, false)
else {
return true;
}
}
int MbedLogger::sendReply() {
//being explicit in what's being transmitted
//change this method to be more explicit later
//integer vector _data_packet is used here, cleared fist just in case
_data_packet.clear(); //same data packet for transmission
_data_packet.push_back(117);
_data_packet.push_back(101);
//_confirmed_packet_number comes from the packet number that is sent from the Python program
_data_packet.push_back(_confirmed_packet_number / 256); //packet number only changed when confirmed
_data_packet.push_back(_confirmed_packet_number % 256); //split into first and second byte
//compute checksums
int receiver_crc_one = calcCrcOne();
int receiver_crc_two = calcCrcTwo();
_data_packet.push_back(receiver_crc_one);
_data_packet.push_back(receiver_crc_two);
//transmit this packet
for (_it=_data_packet.begin(); _it < _data_packet.end(); _it++) {
xbee().putc(*_it); //send integers over serial port one byte at a time
}
//change process methodology later...
return _confirmed_packet_number;
}
void MbedLogger::endReceiveData() { //DLE character * 4 ==> 10 10 10 10
closeLogFile(); //close the file here
xbee().printf("endReceiveData closed the file and ended transmission\n\r");
}
//calculate the crc with an integer array
int MbedLogger::calcCrcOneArray(int *input_array, int array_length) {
//can't initialize the table in the constructor in c++
int crc_table [256] = {0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448};
int crc = 0;
for (int z = 0; z < array_length; z++) {
crc = (crc_table[(input_array[z] ^ crc) & 0xff] ^ (crc >> 8)) & 0xFFFF;
}
return crc / 256; //second-to-last byte
}
int MbedLogger::calcCrcTwoArray(int *input_array, int array_length) {
//can't initialize the table in the constructor in c++
int crc_table [256] = {0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448};
int crc = 0;
for (int z = 0; z < array_length; z++) {
crc = (crc_table[(input_array[z] ^ crc) & 0xff] ^ (crc >> 8)) & 0xFFFF;
}
return crc % 256; //second-to-last byte
}
int MbedLogger::calcCrcOne() {
//can't initialize the table in the constructor in c++
int crc_table [256] = {0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448};
int crc = 0;
for (_it=_data_packet.begin(); _it < _data_packet.end(); _it++)
crc = (crc_table[(*_it ^ crc) & 0xff] ^ (crc >> 8)) & 0xFFFF;
return crc / 256; //second-to-last byte
}
int MbedLogger::calcCrcTwo() {
int crc_table [256] = {0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448};
int crc = 0;
for (_it=_data_packet.begin(); _it < _data_packet.end(); _it++)
crc = (crc_table[(*_it ^ crc) & 0xff] ^ (crc >> 8)) & 0xFFFF;
//xbee().printf("DEBUG: calcCrcTwo string length: %d crc: %d\n\r", input_array.length(), crc % 256);
return crc % 256; //last byte
}
void MbedLogger::resetReplyPacket() {
_confirmed_packet_number = 0;
}
void MbedLogger::openNewMissionFile() {
xbee().printf("Opening Mission file (sequence.txt) for reception.\n\r");
string filename_string = _file_system_string + "sequence.txt";
xbee().printf("openNewMissionFile: %s\n\r", filename_string.c_str());
_fp = fopen(filename_string.c_str(), "w");
}
void MbedLogger::openReceiveFile(string filename) {
string filename_string = _file_system_string + filename; //example "sequence.txt"
_fp = fopen(filename_string.c_str(), "w"); //open a file for writing
}
void MbedLogger::setDataCounter(int input_counter) {
_transmit_counter = input_counter;
}
void MbedLogger::closeIncompleteFile() {
fprintf(_fp, "TRANSMISSION INTERRUPTED!"); //write this warning to the file
closeLogFile(); //close file
}
void MbedLogger::appendLogFile(int current_state, int option) {
//option one means write to file
if (option == 1) {
if (!_fp) { //if not present
_fp = fopen(_full_file_path_string.c_str(), "a");
}
//record data using the recordData function (takes in the state integer)
recordData(current_state);
}
else {
closeLogFile();
}
}
void MbedLogger::appendDiagFile(char *printf_string, int flushclose) {
//
int start_time = 1518467832;
//in the future create the ability to set the start time
int time_now = mbedLogger().getSystemTime();
if (!_fp2) { //if not present
_fp2 = fopen(_full_diagfile_path_string.c_str(), "a");
}
int del_time = time_now - start_time;
//record data using the recordData function (takes in the state integer)
fprintf(_fp2, "time=%d seconds ", del_time);
fprintf(_fp2, printf_string);
if(flushclose == 1) { fflush(_fp2); }
if(flushclose == 0) {fclose(_fp2); _fp2 = NULL; }
}
// initialize and close the file
// log file freezes at 0x0000006c
void MbedLogger::initializeLogFile() {
string file_name_string = _file_system_string + configFileIO().logFilesStruct.logFileName; // "DIAG000.txt";
//string file_name_string = _file_system_string + "LOG000.csv"; // how to pass in log file name as a string?
_full_file_path_string = file_name_string;
char buf[256];
xbee().printf("%s file system init\n\r", _file_system_string.c_str());
sprintf(buf, "%s mbedlogger():initializelogfile: file system init\n\r", _file_system_string.c_str());
appendDiagFile(buf,1);
//try to open this file...
_fp = fopen(file_name_string.c_str(), "r");
//if the file is empty, create this.
if (!_fp) {
_fp = fopen(file_name_string.c_str(), "w"); //write,print,close
//fprintf(_fp,"state_string,state_ID,timer,depth_cmd,depth_ft,pitch_cmd,pitch_deg,bce_cmd,bce_mm,batt_cmd,batt_mm,pitchRate_degs,depthRate_fps\nempty log file!\n");
fprintf(_fp,_heading_string.c_str());
closeLogFile();
}
else
closeLogFile(); //close the opened read file
}
void MbedLogger::initializeDiagFile(int print_diag) {
//string file_name_string = _file_system_string + "DIAG000.txt"; // how to pass in log file name as a string?
string file_name_string = _file_system_string + configFileIO().logFilesStruct.diagFileName; // "DIAG000.txt";
_full_diagfile_path_string = file_name_string;
char buf[256];
xbee().printf("%s file system init\n\r", _file_system_string.c_str());
sprintf(buf, "mbedlogger():Initializediagfile input variable diagfilename: %s file system init\n\r", file_name_string.c_str());
if(print_diag == 1) {appendDiagFile(buf,3);} //configFileIO().logFilesStruct.diagFileName
//try to open this file...
if( _fp2 == NULL) { _fp2 = fopen(file_name_string.c_str(), "r"); }
//if the file is empty, create this.
if (!_fp2) {
_fp2 = fopen(file_name_string.c_str(), "w"); //write,print,close
//fprintf(_fp,"state_string,state_ID,timer,depth_cmd,depth_ft,pitch_cmd,pitch_deg,bce_cmd,bce_mm,batt_cmd,batt_mm,pitchRate_degs,depthRate_fps\nempty log file!\n");
fprintf(_fp2,_diag_heading_string.c_str());
closeDiagFile();
}
else
closeDiagFile(); //close the opened read file
}
int MbedLogger::fileTransmitState() {
return _file_transmission_state;
}
int MbedLogger::calcCrcOneString (string input_string) {
int crc_table [256] = {0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448};
int crc = 0;
for (unsigned int i = 0; i < input_string.length(); i++) {
//convert each character to an integer
int character_to_integer = input_string[i]; //correct
crc = (crc_table[(character_to_integer ^ crc) & 0xff] ^ (crc >> 8)) & 0xFFFF;
}
//xbee().printf("DEBUG: calcCrcOne string length: %d crc: %d\n\r", input_string.length(), crc/256);
return crc / 256; //second-to-last byte
}
int MbedLogger::calcCrcTwoString (string input_string) {
int crc_table [256] = {0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448};
int crc = 0;
for (unsigned int i = 0; i < input_string.length(); i++) {
//convert each character to an integer
int character_to_integer = input_string[i]; //correct
crc = (crc_table[(character_to_integer ^ crc) & 0xff] ^ (crc >> 8)) & 0xFFFF;
}
//xbee().printf("DEBUG: calcCrcTwo string length: %d crc: %d\n\r", input_string.length(), crc % 256);
return crc % 256; //last byte
}
void MbedLogger::createEmptyLog() {
string file_name_string = _file_system_string + "LOG000.csv";
string empty_log = "EMPTY LOG";
_fp = fopen(file_name_string.c_str(), "w");
fprintf(_fp, "%.25s\n",empty_log.c_str()); //just write this string to the log (processing needs a file size that is not zero)
closeLogFile();
}
int MbedLogger::getFileSize(string filename) {
// fixed the const char * errror:
// https://stackoverflow.com/questions/347949/how-to-convert-a-stdstring-to-const-char-or-char
const char * char_filename = filename.c_str(); // Returns a pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object.
//http://www.cplusplus.com/reference/string/string/c_str/
_fp = fopen(filename.c_str(), "rb"); //open the file for reading as a binary file
fseek(_fp, 0, SEEK_END); //SEEK_END is a constant in cstdio (end of the file)
unsigned int file_size = ftell(_fp); //For binary streams, this is the number of bytes from the beginning of the file.
fseek(_fp, 0, SEEK_SET); //SEEK_SET is hte beginning of the file, not sure this is necessary
xbee().printf("%s file size is %d bytes.\n\r", filename.c_str(), file_size);
closeLogFile(); //can probably just close the file pointer and not worry about position
return file_size;
}
int MbedLogger::debugFileState() {
xbee().printf("What is _fp right now? %p\n\r", _fp); //pointer notation
if (_fp)
return 1; //file pointer does exist
else
return 0; //file pointer does not exist
}
void MbedLogger::specifyFileForTransmit(string input_string) {
xbee().printf("specifyFileForTransmit\n\r");
string file_string = _file_system_string + input_string;
xbee().printf("file_string is <%s>\n\r", file_string.c_str());
//open this file to read
_fp = fopen(file_string.c_str(), "r");
//transmit that file
//transmitDataWithTicker(); //replaced ticker
_file_transmission = true;
}
void MbedLogger::transmitFileFromDirectory( int file_number ) {
file_number = file_number + 1; //to get the correct number
DIR *dir;
struct dirent *dp; //dirent.h is the format of directory entries
int log_found =0, loop=1; //start file numbers at 1
long int temp=0;
// char * char_pointer;
// char * numstart, *numstop;
if ( NULL == (dir = opendir( _file_system_string.c_str() )) ) {
xbee().printf("MBED directory could not be opened\r\n");
}
else
{
while ( NULL != (dp = readdir( dir )) )
{
xbee().printf( "%d. %s (log file: %d, %d)\r\n", loop, dp->d_name,log_found,temp);
//process current file if it matches the file number
if (file_number == loop) {
char * current_file_name = dp->d_name; //pointer to this char array
specifyFileForTransmit(current_file_name);
break;
}
loop++;
}
}
}
void MbedLogger::accessMbedDirectory() {
printMbedDirectory();
xbee().printf("Type in the number of the file you want to transmit.\n\r");
char message[42];
xbee().scanf("%41s", message);
xbee().printf("Input received!\n\r");
//check if char array is an integer
char* conversion_pointer;
long converted = strtol(message, &conversion_pointer, 10);
if (*conversion_pointer) {
//conversion failed because the input was not a number
xbee().printf("NOT A VALID FILE NUMBER!\n\r");
}
else {
//conversion worked!
xbee().printf("You chose file number: %d\n\r", converted);
// transmit the file
transmitFileFromDirectory(converted);
}
}
void MbedLogger::closeLogFile() {
led4() = 1;
if (_fp == NULL){
xbee().printf("MbedLogger: (%s) LOG FILE WAS ALREADY CLOSED!\n\r", _file_system_string.c_str());
}
else {
xbee().printf("MbedLogger: (%s) CLOSING LOG FILE!\n\r", _file_system_string.c_str());
//close file
fclose(_fp);
_fp = NULL; //set pointer to zero
}
}
void MbedLogger::closeDiagFile() { // closes he present diag file on _fp2
led4() = 1;
if (_fp2 == NULL){
xbee().printf("MbedLogger: (%s) DIAG FILE WAS ALREADY CLOSED!\n\r", _full_diagfile_path_string.c_str());
}
else {
xbee().printf("MbedLogger: (%s) CLOSING LOG FILE!\n\r", _full_diagfile_path_string.c_str());
//close file
fclose(_fp2);
_fp2 = NULL; //set pointer to zero
}
}
void MbedLogger::activateReceivePacket() {
_mbed_receive_loop = true;
}
void MbedLogger::receiveSequenceFile() {
//restart each time
_end_sequence_transmission = false;
openNewMissionFile();
//zero will be reserved for the file name, future
_confirmed_packet_number = 1; //in sendReply() function that transmits a reply for incoming data
// int current_packet_number = 1;
// int last_packet_number = -1;
// int break_transmission = 0;
int counter = 0;
while(1) {
wait(0.25); //runs at 4 Hz
checkForIncomingData();
//xbee().printf("\n\rDEBUG: _confirmed_packet_number%d\n\r", _confirmed_packet_number);
counter++;
sendReply(); //bad name, should call it send request or something
if (_end_sequence_transmission)
break;
}
closeLogFile();
}
void MbedLogger::receiveMissionDataWithFSM() {
checkForIncomingData();
// Example: send reply 75 65 00 00
// Example: send reply 75 65 00 01
}
void MbedLogger::receiveMissionDataWithTicker() {
openNewMissionFile(); //sequence.txt file opened
_mbed_receive_ticker.attach(callback(this, &MbedLogger::activateReceivePacket), 0.5);
xbee().printf("\n\r02/09/2018 MbedLogger receiveMissionData Beginning to receive sequence data...\n\r");
resetReplyPacket(); //reset the reply packet
//idea for stopping this if data not being received
int current_packet_number = 0;
int last_packet_number = -1;
int break_transmission = 0;
while(1) {
//runs at 10 hz
if (_mbed_receive_loop) {
if (!checkForIncomingData()) { // run this until it finishes
//when you complete data reception, this will become false
xbee().printf("\n\rMbedLogger: Data RECEPTION complete.\n\r");
_mbed_receive_ticker.detach();
break;
}
else {
// SEND REPLY 75 65 00 00
// SEND REPLY 75 65 00 01
//check if you keep getting the same thing
current_packet_number = sendReply();
//xbee().printf("DEBUG: current packet number %d (last packet number %d) \n\r", current_packet_number, last_packet_number); //debug
//let this count up a few times before it exits
if (current_packet_number == last_packet_number) {
break_transmission++;
//break transmission after 50 failed attempts (was 100)
if (break_transmission >= 50) {
closeIncompleteFile(); //close the file
_mbed_receive_ticker.detach();
xbee().printf("MbedLogger: TRANSMISSION INTERRUPTED!\n\r");
break;
}
}
else
last_packet_number = current_packet_number;
}
_mbed_receive_loop = false; // wait until the loop rate timer fires again
}
}
}
//only do this for the MBED because of the limited file size
//write one line to the file (open to write, this will erase all other data) and close it.
void MbedLogger::eraseFile() {
_fp = fopen(_full_file_path_string.c_str(), "w"); // LOG000.csv
fprintf(_fp,_heading_string.c_str());
closeLogFile();
}
void MbedLogger::intCreateDataPacket(int data_buffer[],int payload_length) {
// packet is 7565 0001 FFFF EEEE CC DATA DATA DATA ... CRC1 CRC2
//check here https://www.rapidtables.com/convert/number/hex-to-decimal.html?x=01c0
// ieee 754: http://www6.uniovi.es/~antonio/uned/ieee754/IEEE-754hex32.html
//CLEAR: Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.
_data_packet.clear();
//DATA PACKET HEADER
_data_packet.push_back(117); //0x75
_data_packet.push_back(101); //0x65
_data_packet.push_back(_packet_number/256); //current packet number in 0x#### form
_data_packet.push_back(_packet_number%256); //current packet number in 0x#### form
_data_packet.push_back(_total_number_of_packets/256); //total number of packets, 0x#### form
_data_packet.push_back(_total_number_of_packets%256); //total number of packets, 0x#### form
_data_packet.push_back(_current_line_length);
//DATA FROM INTEGER ARRAY (read the array)
for (int i = 0; i < payload_length; i++) {
_data_packet.push_back(data_buffer[i]);
}
//CRC CALCULATIONS BELOW, character version of calculation screws up on null character 0x00, scrapped and using vector of integers
int crc_one = calcCrcOne();
int crc_two = calcCrcTwo();
//place the crc bytes into the data packet that is transmitted
_data_packet.push_back(crc_one);
_data_packet.push_back(crc_two);
}
void MbedLogger::setTransmitPacketNumber(int packet_number) {
_transmit_packet_num = packet_number;
//also needed to reset a boolean flag on the transmit
_fsm_transmit_complete = false;
_end_transmit_packet = false;
}
int MbedLogger::currentPacketNumber() {
return _packet_number;
}