most functionality to splashdwon, find neutral and start mission. short timeouts still in code for testing, will adjust to go directly to sit_idle after splashdown
Dependencies: mbed MODSERIAL FATFileSystem
MbedLogger/MbedLogger.cpp
- Committer:
- tnhnrl
- Date:
- 2018-07-30
- Revision:
- 73:f6f378311c8d
- Parent:
- 72:250b2665755c
- Child:
- 74:d281aaef9766
File content as of revision 73:f6f378311c8d:
#include "MbedLogger.hpp" #include "StaticDefs.hpp" //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; _full_file_path_string = _file_system_string + "LOG000.csv"; //use multiple logs in the future? (after file size is too large) _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 //NEXT VERSION WILL ELIMINATE LENGTH REQUIREMENT //_heading_string = "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,sys_amps,sys_volts,int_press_PSI\n"; //NEW ALTIMETER READINGS! _heading_string = "state_string,state_number,timer_sec,depth_cmd,depth_ft,pitch_cmd,pitch_deg,rudder_cmd_deg,heading_deg,bce_cmd,bce_mm,batt_cmd,batt_mm,pitch_rate_degs,depth_rate_fps,system_amps,system_volts,altimeter_or_intPSI,BCE_p,i,d,BATT_p,i,d,DEPTH_p,i,d,PITCH_p,i,d\n"; _transmit_packet_num = 0; _fsm_transmit_complete = false; _end_transmit_packet = false; } //this function has to be called for the time to function correctly void MbedLogger::setLogTime() { pc().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_int = mbedLogger().getSystemTime(); //read the system timer to get unix timestamp _data_log[1] = depthLoop().getCommand(); //depth command _data_log[2] = depthLoop().getPosition(); //depth reading (filtered depth) _data_log[3] = pitchLoop().getCommand(); //pitch command _data_log[4] = pitchLoop().getPosition(); //pitch reading (filtered pitch) _data_log[5] = rudder().getPosition_deg(); //rudder command _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().getInternalPressurePSI(); // int_press_PSI //BCE_p,i,d _data_log[16] = bce().getControllerP(); _data_log[17] = bce().getControllerI(); _data_log[18] = bce().getControllerD(); _data_log[19] = batt().getControllerP(); _data_log[20] = batt().getControllerI(); _data_log[21] = batt().getControllerD(); _data_log[22] = depthLoop().getControllerP(); _data_log[23] = depthLoop().getControllerI(); _data_log[24] = depthLoop().getControllerD(); _data_log[25] = pitchLoop().getControllerP(); _data_log[26] = pitchLoop().getControllerI(); _data_log[27] = pitchLoop().getControllerD(); //check what the current state is and create that string 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 == RECEIVE_SEQUENCE) string_state = "RECEIVE_SEQUENCE"; string blank_space = ""; //to get consistent spacing in the file //record the string state, integer state, and then the data //_heading_string is 254 characters long //packet size is 254 characters long //make function that checks length of header versus string below, add padding fprintf(_fp, "%16s,%.2d,",string_state.c_str(),current_state); fprintf(_fp, "%11d,",data_log_int); //length 10 //right here fprintf(_fp, "%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.1f,%6.3f,%6.2f,%6.1f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f%41s\n",_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],blank_space.c_str()); //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; pc().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() )) ) { pc().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; pc().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 pc().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 pc().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(); pc().printf("\n\rLog file closed. Lines in log file: %d.\n\r", _log_file_line_counter); } void MbedLogger::blastData() { pc().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); pc().printf("\r"); // for proper spacing _packet_number++; } else { _packet_number = 0; //reset packet number break; } } /******************************/ //CLOSE THE FILE closeLogFile(); pc().printf("\n\rblastData: Log file closed. %d.\n\r"); } void MbedLogger::openFileForTransmit() { pc().printf("\n\ropenFileForTransmit\n\r"); //open the current file to read the contents string file_name_string = _file_system_string + "LOG000.csv"; _fp = fopen(file_name_string.c_str(), "r"); _file_transmission = true; } 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); //pc().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); //pc().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); //pc().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++) { pc().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); pc().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 //pc().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() { pc().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] = pc().getc(); pc().printf("<%d> ", incoming_byte[bytes_received]); bytes_received++; if (bytes_received > 5) { req_packet_number = incoming_byte[2] * 256 + incoming_byte[3]; pc().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); } void MbedLogger::transmitMultiplePackets() { pc().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[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; //open the file string file_name_string = _file_system_string + "LOG000.csv"; _fp = fopen(file_name_string.c_str(), "r"); while (1) { //INCOMING BYTE incoming_byte[bytes_received] = pc().getc(); pc().printf("<%d> ", incoming_byte[bytes_received]); //EXIT IF YOU RECEIVE... if (incoming_byte[bytes_received] == 16) { //quick and dirty if (pc().getc() == 17) { if (pc().getc() == 18) { if (pc().getc() == 19) { //exit if you get all of these packets hex 10 11 12 13, dec 16 17 18 19 pc().printf("END TRANSMISSION REQUEST RECEIVED!\n\r"); break; } } } } bytes_received++; if (bytes_received > 5) { req_packet_number = incoming_byte[2] * 256 + incoming_byte[3]; pc().printf("req_packet_number = %d\n\r", req_packet_number); //receive correct checksum, immediately send this packet transmitPacketNumber(req_packet_number); //reset bytes_received bytes_received = 0; } } //CLOSE THE FILE fclose(_fp); } void MbedLogger::checkForPythonTransmitRequest() { //pc().printf("checkForPythonTransmitRequest\n"); if ( pc().readable() ) { //PC READABLE DOES NOT WORK HERE?! led2() = !led2(); led3() = !led3(); pc().printf("########################\n"); //pc().printf("%d", pc().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 (pc().readable()) { // incoming_byte[bytes_received] = pc().getc(); // pc().printf("<%d> ", incoming_byte[bytes_received]); // // bytes_received++; // // if (bytes_received > 5) { // // req_packet_number = incoming_byte[2] * 256 + incoming_byte[3]; // // pc().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; // //pc().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(); // //pc().printf(" T P \n\r"); // //pc().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 (pc().readable()) { //don't rely on pc readable being open all the time incoming_byte = pc().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 pc().printf("(TRANSMIT_PACKET_2)reached inside_while_loop = 0\n\r"); //DEBUG break; } //end of switch statement } //end of while loop // else { // //pc().printf("pc not readable \n\r"); // } // } //once you're outside of the while loop inside_while_loop = true; //for next iteration pc().printf("DEBUG: (readTransmitPacket) Outside of while loop\n\r"); return false; } bool MbedLogger::endTransmitPacket() { int incoming_byte; while (pc().readable()) { incoming_byte = pc().getc(); //get first byte if (incoming_byte == 16) { incoming_byte = pc().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) { pc().printf("ERROR: Log file could not be opened\n\r"); } else { pc().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) { //pc().printf("ERROR: Log file could not be opened\n\r"); return false; } else { //pc().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; 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) { pc().printf("\n endTransmissionCloseFile: FILE WAS NOT OPENED!\n\r"); } else { pc().printf("\n endTransmissionCloseFile: FILE FOUND AND CLOSED!\n\r"); closeLogFile(); } _file_transmission = false; } void MbedLogger::openWriteFile() { pc().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 (pc().readable() && !data_transmission_complete) { incoming_byte = pc().getc(); //getc returns an unsigned char cast to an int //pc().printf("DEBUG: State 0\n\r"); switch(process_state) { case HEADER_117: //continue processing if (incoming_byte == 117){ process_state = HEADER_101; //pc().printf("DEBUG: Case 117\n\r"); } //end transmission else if (incoming_byte == 16) { process_state = END_TRANSMISSION; pc().printf("DEBUG: State 16 (END_TRANSMISSION)\n\r"); } else { process_state = HEADER_117; // ??? //pc().printf("DEBUG: State Header 117\n\r"); } break; case HEADER_101: if(incoming_byte == 101) { process_state = PACKET_NUM; //pc().printf("DEBUG: Case 101\n\r"); } break; case PACKET_NUM: receive_packet_number = incoming_byte; process_state = TOTAL_NUM_PACKETS; //pc().printf("DEBUG: Case PACKET_NUM\n\r"); break; case TOTAL_NUM_PACKETS: receive_total_number_packets = incoming_byte; process_state = PACKET_SIZE; //pc().printf("DEBUG: Case TOTAL_NUM_PACKETS\n\r"); break; case PACKET_SIZE: receive_packet_size = incoming_byte; //pc().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 //pc().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 (pc().readable()) { char_buffer[i] = pc().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 = pc().getc(); checksum_two = pc().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(); //pc().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)) { // 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 //have to terminate the string with '\0' temp_char[receive_packet_size] = '\0'; //pc().printf("\n\rDEBUG: ------ Filename? <<%s>>\n\r", temp_char); _received_filename = temp_char; //pc().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 else 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) { //pc().printf("break serial_timeout %d\n\r", serial_timeout); break; } } break; case END_TRANSMISSION: if (pc().getc() == 16) { pc().printf("DEBUG: END_TRANSMISSION REACHED: 1. \n\r"); if (pc().getc() == 16) { pc().printf("DEBUG: END_TRANSMISSION REACHED: 2. \n\r"); endReceiveData(); } } pc().printf("DEBUG: END_TRANSMISSION REACHED: 5. \n\r"); //process_state = HEADER_117; //don't do this unless the check is wrong pc().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) { pc().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++) { pc().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 pc().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; //pc().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() { pc().printf("Opening Mission file (sequence.txt) for reception.\n\r"); string filename_string = _file_system_string + "sequence.txt"; pc().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(); } } // initialize and close the file // log file freezes at 0x0000006c void MbedLogger::initializeLogFile() { string file_name_string = _file_system_string + "LOG000.csv"; pc().printf("%s file system init\n\r", _file_system_string.c_str()); //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 } 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; } //pc().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; } //pc().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 //closeLogFile(); //can probably just close the file pointer and not worry about position pc().printf("%s file size is %d\n\r", filename.c_str(), file_size); return file_size; } int MbedLogger::debugFileState() { pc().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) { pc().printf("specifyFileForTransmit\n\r"); string file_string = _file_system_string + input_string; pc().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() )) ) { pc().printf("MBED directory could not be opened\r\n"); } else { while ( NULL != (dp = readdir( dir )) ) { pc().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(); pc().printf("Type in the number of the file you want to transmit.\n\r"); char message[42]; pc().scanf("%41s", message); pc().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 pc().printf("NOT A VALID FILE NUMBER!\n\r"); } else { //conversion worked! pc().printf("You chose file number: %d\n\r", converted); // transmit the file transmitFileFromDirectory(converted); } } void MbedLogger::closeLogFile() { led4() = 1; if (_fp == NULL){ pc().printf("MbedLogger: (%s) LOG FILE WAS ALREADY CLOSED!\n\r", _file_system_string.c_str()); } else { pc().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::activateReceivePacket() { _mbed_receive_loop = true; } 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); pc().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 pc().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(); //pc().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(); pc().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()); // _heading_string = "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,sys_amps,sys_volts\n(file erased)" 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::sendStatus() { led3() = !led3(); //readPacketInSeries() //uses this functionality //get data depth, pitch, heading, timer //store the data as a hex char array char hex_char_depth[256]; char hex_char_pitch[256]; char hex_char_heading[256]; char hex_char_timer[256]; string string_hex_buffer = ""; //buffer to store the hex data as a string string string_temp; // ELIMINATE THIS ASAP float depth_value = depthLoop().getPosition(); float pitch_value = imu().getPitch(); float heading_value = imu().getHeading(); //float timer_value = stateMachine().getTimer(); float timer_value = 123.123; sprintf(hex_char_depth, "%08X" , *(unsigned int*)&depth_value); sprintf(hex_char_pitch, "%08X" , *(unsigned int*)&pitch_value); sprintf(hex_char_heading, "%08X" , *(unsigned int*)&heading_value); sprintf(hex_char_timer, "%08X" , *(unsigned int*)&timer_value); //store the integer values int hex_to_int[128]; //read through hex string and break apart into chunks and save the decimal values int hex_counter = 0; ////////////////////////// string_hex_buffer = hex_char_depth; for (int i = 0; i < 8; i = i+2) { //substring starts at x substr(x, length of substring) string_temp = string_hex_buffer.substr(i,2); // get substring from string (converted from char array) //convoluted, fix this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // copying the contents of the string to char array char temp_char_array[256]; strcpy(temp_char_array, string_temp.c_str()); //store char array hex value as decimal value int decimal_value; sscanf(temp_char_array,"%x",&decimal_value); hex_to_int[hex_counter] = decimal_value; hex_counter++; //iterate to keep up with for loop //clear the string each time //string_temp = ""; //cout << "string_temp CLEARED? is " << string_temp << endl; //cout << "string_temp is " << string_temp << " and the value is " << decimal_value << endl; } string_hex_buffer = hex_char_pitch; for (int i = 0; i < 8; i = i+2) { //substring starts at x substr(x, length of substring) string_temp = string_hex_buffer.substr(i,2); //convoluted, fix this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // copying the contents of the string to char array char temp_char_array[256]; strcpy(temp_char_array, string_temp.c_str()); //store char array hex value as decimal value int decimal_value; sscanf(temp_char_array,"%x",&decimal_value); hex_to_int[hex_counter] = decimal_value; hex_counter++; //iterate to keep up with for loop //clear the string each time //string_temp = ""; //cout << "string_temp CLEARED? is " << string_temp << endl; //cout << "string_temp is " << string_temp << " and the value is " << decimal_value << endl; } string_hex_buffer = hex_char_heading; for (int i = 0; i < 8; i = i+2) { //substring starts at x substr(x, length of substring) string_temp = string_hex_buffer.substr(i,2); //convoluted, fix this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // copying the contents of the string to char array char temp_char_array[256]; strcpy(temp_char_array, string_temp.c_str()); //store char array hex value as decimal value int decimal_value; sscanf(temp_char_array,"%x",&decimal_value); hex_to_int[hex_counter] = decimal_value; hex_counter++; //iterate to keep up with for loop //clear the string each time //string_temp = ""; //cout << "string_temp CLEARED? is " << string_temp << endl; //cout << "string_temp is " << string_temp << " and the value is " << decimal_value << endl; } string_hex_buffer = hex_char_timer; for (int i = 0; i < 8; i = i+2) { //substring starts at x substr(x, length of substring) string_temp = string_hex_buffer.substr(i,2); //convoluted, fix this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // copying the contents of the string to char array char temp_char_array[256]; strcpy(temp_char_array, string_temp.c_str()); //store char array hex value as decimal value int decimal_value; sscanf(temp_char_array,"%x",&decimal_value); hex_to_int[hex_counter] = decimal_value; hex_counter++; //iterate to keep up with for loop //clear the string each time //string_temp = ""; //cout << "string_temp CLEARED? is " << string_temp << endl; //cout << "string_temp is " << string_temp << " and the value is " << decimal_value << endl; } ////////////////////////// //create new packet based on int array _packet_number = 1; // TEST, FIX THIS _total_number_of_packets = 1; _current_line_length = 16; intCreateDataPacket(hex_to_int,16); transmitDataPacket(); } 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; }