Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Datalogger Serial Communication - break detection work unstable - isr wrong

  1. #1
    Junior Member
    Join Date
    Jun 2014
    Posts
    16

    Datalogger Serial Communication - break detection work unstable - isr wrong

    I need some Help, could someone look over my code i have no idea why my code works unreliable.

    The code is for a datalogger project with a special serial communication protocol.
    The protocol is like LIN Protocol but with higher speed and no synch byte.

    The communication speed is 57600 Baud.
    The frame starts with a break. for this the rx line is for 230 microseconds pulled down, after this the rx line is high for at least 16 microseconds - after this normal serial communication for this frame start.

    below is my code - i think it is instable if the high time after data transmission and break sequence is short.
    The code is a mix of chrisstaite teensy dmx and openlog with modification.
    My code should have following behavior :
    frame rx is hwserial1
    * every frame start by break signature (234microseconds low, 16microseconds high) after this the dataframe start.
    * if the frame is complete - which is dectected by next break the last frame is extended with prefix ("S:") [ Microsecondes since start (ulong)] folowed by [0x09]- [frame data].
    This data is written to a buffer which is if limit is reached is written to SD card.
    The program is doing something, data is also logged to sd card - but sometime i see no break is detected - which result in the effect that sometimes the data of one written frame to SD has the data of one or more frame because break is not stable detected.
    Below my code - if someone see something, than please give me some comment.
    At this time i search for the reason of this bad behavior but i did'nt have some idea.

    The most important code is the detection of break , the reception of data in the isr and the initialising of Serial Port.


    Best regard, Frank


    Code:
      
    
    #include <Arduino.h>
    
    // C++ includes
    #include <cstdint>
    
    #include <cstring>
    
    #include <EEPROM.h>
    #include <SdFat.h> //We do not use the built-in SD.h file because it calls Serial.print
    
    
    
    
    #define Debug 0
     
    #define SBUS_Baudrate 57600
    #define SBUS_Serial Serial1
    #define HWSERIAL2 Serial2
    
    #define UART0_C2_RX_ENABLE UART_C2_RE | UART_C2_RIE | UART_C2_ILIE
       
     
    constexpr int max_SBUS_Datasize = 513; 
    // Keeps track of when the last frame was received.
    elapsedMillis lastFrameTime;
    // Interval between printing received values.
    constexpr unsigned long kPrintInterval = 5;
     unsigned long  p;
    
    // The last value sent to kChannel.
    uint8_t lastValue;
    
    boolean first;
      uint8_t buf1[max_SBUS_Datasize];
      uint8_t buf2[max_SBUS_Datasize];
      uint8_t *activeBuf;
      uint8_t *inactiveBuf;
      int activeBufIndex;
      uint16_t packetCount;
      volatile uint32_t packetTimestamp;
      volatile int16_t bufcounter;
      uint16_t packetSize;
    
    
    void uart0_rx_status_isr();
    void uart0_rx_error_isr();
    void SBUS_begin(void);
    int SBUS_readFrameData(uint8_t *buf,uint16_t len);
    
    #define writebuffer_size 1000
     uint8_t buffer1[writebuffer_size]; 
     uint8_t buffer2[writebuffer_size];
     uint8_t *activeWritebuffer;
     uint8_t *inactiveWritebuffer;
    uint8_t activeWritebufferIndex;
    volatile uint16_t buffer1counter,buffer2counter,DataReadCounter, DataToWriteCounter;
    bool set_datawrite_flag,compareResult;;
    
    const uint8_t ErrorFrame[5] ={0x1,0xF,0x21,0x87,0x2A};
    const bool ErrorFrameVerification[5] ={1,1,1,0,1};
    const uint8_t Header[2]={'S',':'};
    uint8_t *ptrDataSave;
    
    /************************************************/ 
    
    //SdFatSdio SD;
    //SdFatSdioEX SD;
    SdFat SD;
    File myFile;
    
    // SD chip select pin
    const uint8_t SD_CS_PIN = 4;
    
    
    uint32_t lastSyncTime;
    const uint16_t MAX_TIME_BEFORE_SYNC_MSEC = 2000;
    //#define MAX_TIME_BEFORE_SYNC_MSEC 5000
    
    #define FILE_BASE_NAME "Data"
    char fileName[13] = FILE_BASE_NAME "00.lho";
    
    
    
    // The folder track depth is used by "cd .." and "pwd"
    // This looks like an ugly hack but the sdfatlib is not supporting going back to previous folder yet.
    // The current handling of "cd .." should be removed when it's available in the sdfat library.
    #define FOLDER_TRACK_DEPTH 2
    
    char folderTree[FOLDER_TRACK_DEPTH][12];
    
    #define CFG_FILENAME "config2.txt" //This is the name of the file that contains the unit settings
    
    #define MAX_CFG "115200,115200,103,214,0,1,1,0,4000,120,0,0\0" //= 115200 bps, escape char of ASCII(103), 214 times, new log mode, verbose on, echo on, ignore RX false. 
    #define CFG_LENGTH (strlen(MAX_CFG) + 1) //Length of text found in config file. strlen ignores \0 so we have to add it back 
    #define SEQ_FILENAME "SEQLOG00.TXT" //This is the name for the file when you're in sequential mode
    
    //Internal EEPROM locations for the user settings
    #define LOCATION_SYSTEM_SETTING    0x02
    
    #define LOCATION_ESCAPE_CHAR    0x05
    #define LOCATION_MAX_ESCAPE_CHAR  0x06
    #define LOCATION_VERBOSE                0x07
    #define LOCATION_ECHO                   0x08
    #define LOCATION_IGNORE_RX    0x09
    
    #define LOCATION_ERR_FLG    0x0A
    #define LOCATION_RESET_EE   0x0B
    #define LOCATION_ERR_FILE_RENAME        0x0C
    
    
    #define LOCATION_FILE_NUMBER_LSB  0x10
    #define LOCATION_FILE_NUMBER_MID        0x11
    #define LOCATION_FILE_NUMBER_MSB  0x12
    
    #define LOCATION_RX_BAUD_SETTING_HIGH 0x20
    #define LOCATION_RX_BAUD_SETTING_MID  0x21
    #define LOCATION_RX_BAUD_SETTING_LOW  0x22
    
    #define LOCATION_LIN_BAUD_SETTING_HIGH  0x30
    #define LOCATION_LIN_BAUD_SETTING_MID 0x31
    #define LOCATION_LIN_BAUD_SETTING_LOW 0x32
    
    
    
    #define LOCATION_RX_NUMBER_LSB          0x40
    #define LOCATION_RX_NUMBER_MSB          0x41
    
    #define LOCATION_RX_FRAME_COUNT_LSB     0x42
    #define LOCATION_RX_FRAME_COUNT_MSB     0x43
    
    
    
    
    
    #define BAUD_MIN  1200
    #define BAUD_MAX  1000000
    
    #define MODE_NEWLOG 0
    #define MODE_SEQLOG     1
    #define MODE_COMMAND    2
    
    
    /*****************  Error codes ****************************************/
    
    
    
    //Blinking LED error codes
    #define ERROR_SD_INIT    3
    #define ERROR_NEW_BAUD    5
    #define ERROR_CARD_INIT   6
    #define ERROR_VOLUME_INIT 7
    #define ERROR_ROOT_INIT   8
    #define ERROR_FILE_OPEN   9
    
    
    //These are bit locations used when testing for simple embedded commands.
    #define ECHO      0x01
    #define EXTENDED_INFO   0x02
    #define OFF  0x00
    #define ON   0x01
    
    #define LIN_SYNCH_BYTE_POS      0x00
    #define LIN_ID_BYTE_POS         0x01
    
    //Used for wild card delete and search
    struct command_arg
    {
      char* arg; //Points to first character in command line argument
      byte arg_length; //Length of command line argument
    };
    
    //The number of command line arguments
    //Increase to support more arguments but be aware of the memory restrictions
    //command <arg1> <arg2> <arg3> <arg4> <arg5>
    #define MAX_COUNT_COMMAND_LINE_ARGS 5
    
    static struct command_arg cmd_arg[MAX_COUNT_COMMAND_LINE_ARGS];
    byte feedback_mode = (ECHO | EXTENDED_INFO);
    
    
    
    
    const uint8_t SdChipSelect = 4;
    
    #define error(msg) SD.errorHalt(F(msg))
    /*******************/
    
    uint8_t Monitormode = 1;
    
    const int ledPin = 13;
    
    char new_file_name[13];
    
    //uint32_t lastSyncTime = 0;
    //byte Monitormode = 0;
    long setting_uart_speed_LIN,setting_uart_speed_RX; //This is the baud rate that the system runs at, default is 9600. Can be 1,200 to 1,000,000
    byte setting_system_mode; //This is the mode the system runs in, default is MODE_NEWLOG
    byte setting_escape_character; //This is the ASCII character we look for to break logging, default is ctrl+z
    byte setting_max_escape_character; //Number of escape chars before break logging, default is 3
    byte setting_verbose; //This controls the whether we get extended or simple responses.
    byte setting_echo; //This turns on/off echoing at the command prompt
    byte setting_ignore_RX; //This flag, when set to 1 will make OpenLog ignore the state of the RX pin when powering up
    int setting_RX_NUMBER,setting_RX_FRAME_COUNT;
    byte setting_RESET_EE;
    byte setting_ERR_FILE_RENAME;
    byte setting_ERR_FLG;
    
    
    
    int RX_LINE_ANZAHL = 200; // Size limit trigger of RX buffer -   if bigger then readout Rxbuffer;
    int RX_FRAME_COUNT = 140; // gibt an wieviel zeichen eine Zeile mindestens hatn
    const int ANZAHL = 2048; // größe der Pakete die vom Rx Buffer in den lokalen Puffer kopiert werden sollen;
    const int LOCAL_RX_TEST_BUFF_SIZE = 4096; //This is the 1. Test Buffer. 
    const int LOCAL_BUFF_SIZE = 8192; //This is the 2nd buffer. It pulls from the larger NewSerial buffer as quickly as possible.
    byte localBuffer[LOCAL_BUFF_SIZE];
    byte localRXBuffer[LOCAL_BUFF_SIZE];
    int localRXBuffer_index, localBuffer_index = 0;
    
    byte RX_Trigger;
    byte checkedSpot;
    byte escape_chars_received = 0;
    
    const uint16_t MAX_IDLE_TIME_MSEC = 500; //The number of milliseconds before unit goes to sleep
    //const uint16_t MAX_TIME_BEFORE_SYNC_MSEC = 2000;
    
    //LIN_global
    int n_LIN_C,LIN_BYTE_COUNTER;
    char ch_LIN;
    #define LIN_DATA_SIZE 640
    char LIN_DATA[LIN_DATA_SIZE]; // normally Array should have only a size of 10 - but because i want so see possible data packet corruption 
    
    
    
    unsigned long ul_LIN_PACKET_TIME =0,ul_RX_PACKET_TIME = 0;
    long l_LIN_TIME = 0,l_RX_TIME = 0;;
    char ch_LIN_TIME[4], ch_RX_TIME[4];
    
    
    //SBUS_global
    unsigned int n_SBUS_C,n_SBUS_C_last,SBUS_BYTE_COUNTER;
    char ch_SBUS;
    #define SBUS_DATA_SIZE 640
    char SBUS_DATA[SBUS_DATA_SIZE]; // normally Array should have only a size of 10 - but because i want so see possible data packet corruption 
    uint8_t invalidFrame = 0;
    
    unsigned long ul_SBUS_PACKET_TIME =0;
    long l_SBUS_TIME = 0;
    char ch_SBUS_TIME[4];
    
    char SBUS_initialised = 0;
    char SBUS_Broadcast_Data = 0;
    char SBUS_synchronised = 0;
    
    extern uint16_t num_framing_errors_last;
    extern uint16_t num_framing_errors;
    extern uint16_t num_frame_posistion[3000+ (3000/3)];
    extern uint16_t num_frame_posistion_write_counter,num_frame_posistion_read_counter,num_frame_posistion_counter_max,num_frame_packets_to_read;
    extern uint32_t num_frame_posistion_time[3000 + (3000/3)];
    extern uint32_t last_reception_time_micros;
    extern uint32_t sum_elapsed_milliseconds;
    uint16_t  loc_num_frame_packets_to_read;
    
    extern uint32_t  time_since_last_reception;
    
    extern uint8_t FrameLED_value;
    uint8_t End_of_Data_LED_state = 0;
    
    extern uint32_t head_pos_external;
    extern uint32_t tail_pos_external ;
    
    
    unsigned int pos_Endmarker,pos_SBUS_Endmarker = 0;
    
    
    
      byte msb, lsb, mib;
      uint32_t new_file_number;
    
    
    
    //The number of command line arguments
    //Increase to support more arguments but be aware of the memory restrictions
    //command <arg1> <arg2> <arg3> <arg4> <arg5>
    #define MAX_COUNT_COMMAND_LINE_ARGS 5
    
     
     
    //The following are system functions needed for basic operation
    //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    
    //Blinks the status LEDs to indicate a type of error
    void blink_error(byte ERROR_TYPE) {
      while(1) {
        for(int x = 0 ; x < ERROR_TYPE ; x++) {
          digitalWrite(ledPin, HIGH);
          delay(200);
          digitalWrite(ledPin, LOW);
          delay(200);
        }
    
        delay(2000);
      }
    }
    
    
    //Handle errors by printing the error type and blinking LEDs in certain way
    //The function will never exit - it loops forever inside blink_error
    void systemError(byte error_type)
    {
      if (Monitormode) Serial.print(F("Error "));
      switch(error_type)
      {
      case ERROR_CARD_INIT:
        if (Monitormode) Serial.print(F("card.init")); 
        blink_error(ERROR_SD_INIT);
        break;
      case ERROR_VOLUME_INIT:
        if (Monitormode) Serial.print(F("volume.init")); 
        blink_error(ERROR_SD_INIT);
        break;
      case ERROR_ROOT_INIT:
        if (Monitormode) Serial.print(F("root.init")); 
        blink_error(ERROR_SD_INIT);
        break;
      case ERROR_FILE_OPEN:
        if (Monitormode) Serial.print(F("file.open")); 
        blink_error(ERROR_SD_INIT);
        break;
      }
    }
    
    void setup_SD_card()
    {
     
    }
    
    unsigned long read_last_SD_file_number_from_EEPROM()
    {
    
      byte msb, lsb, mib;
      uint32_t new_file_number;  
    
      
        //Combine two 8-bit EEPROM spots into one 16-bit number
      lsb = EEPROM.read(LOCATION_FILE_NUMBER_LSB);
      mib = EEPROM.read(LOCATION_FILE_NUMBER_MID);
      msb = EEPROM.read(LOCATION_FILE_NUMBER_MSB);
    
    
      new_file_number = msb;
      new_file_number = new_file_number << 8;
      new_file_number |= mib;
      new_file_number = new_file_number << 8;
      new_file_number |= lsb;
      return (new_file_number); 
    
     //If both EEPROM spots are 255 (0xFF), that means they are un-initialized (first time OpenLog has been turned on)
      //Let's init them both to 0
      if((lsb == 255) && (mib == 255) && (msb == 255))
      {
        new_file_number = 0; //By default, unit will start at file number zero
        EEPROM.write(LOCATION_FILE_NUMBER_LSB, 0x00);
        EEPROM.write(LOCATION_FILE_NUMBER_MID, 0x00);
        EEPROM.write(LOCATION_FILE_NUMBER_MSB, 0x00);
      }
      if (Monitormode) 
        {
          Serial.print("Newlog_routine FileNumber: ");
          Serial.println(new_file_number,DEC);
        }
        //The above code looks like it will forever loop if we ever create 65535 logs
      //Let's quit if we ever get to 65534
      //9876543 logs is quite possible if you have a system with lots of power on/off cycles
      if(new_file_number == 9876543)
      {
        //Gracefully drop out to command prompt with some error
        if (Monitormode) Serial.print(F("!Too many logs:1!"));
        return(0); //Bail!
      }
      
    }
    
    
    
    
    
    void initialise_buffer()
    {
       activeBufIndex = 0;
       activeBuf = buf1;
       activeWritebuffer =   buffer2;
       inactiveWritebuffer = buffer1;
       ptrDataSave = buffer1;
       DataToWriteCounter  = 0;
       DataReadCounter = 0;
     
    }
    
    void setup() 
    {
    // const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
    //  char fileName[13] = FILE_BASE_NAME "00.loh";
    
      
      // put your setup code here, to run once:
    
     pinMode(3, OUTPUT);
     pinMode(19, OUTPUT);
     pinMode(20, OUTPUT);
      delay(2000);  // Instead of while (!Serial), doesn't seem to work on Teensy
      pinMode(21, OUTPUT);
      pinMode(22, OUTPUT);
      pinMode(23, OUTPUT);
      initialise_buffer();
      set_datawrite_flag = 0;
    
      Serial.begin(115200);
      delay(2000);  // Instead of while (!Serial), doesn't seem to work on Teensy
      Serial.println("Starting.");
      read_system_settings(); //Load all system settings from EEPROM
    
    
    //  HWSERIAL1.begin(setting_uart_speed_LIN);
      if (Monitormode) {
        Serial.print("LIN_baud : ");
        Serial.println(setting_uart_speed_LIN, DEC);
      }
    
    //  //Setup  RXin UART
    //
    //  HWSERIAL2.begin(setting_uart_speed_RX);
    //  if (Monitormode) 
    //    {
    //      Serial.print("UART_Baud : ");
    //      Serial.println(setting_uart_speed_RX, DEC);
    //    }
      //Setup SD & FAT
      if (!SD.begin(SdChipSelect, SD_SCK_MHZ(50))) systemError(ERROR_CARD_INIT);
    //  if (!volume.init(&card)) systemError(ERROR_VOLUME_INIT);
    //  currentDirectory.close(); //We close the cD before opening root. This comes from QuickStart example. Saves 4 bytes.
    //  if (!currentDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT);
    
      if (Monitormode) Serial.print(F("2"));
    
    //  printRam(); //Print the available RAM
    
      //Search for a config file and load any settings found. This will over-ride previous EEPROM settings if found.
      read_config_file();
    
    
    
    
      SdFile newFile; //This will contain the file for SD writing
    
      //Combine two 8-bit EEPROM spots into one 16-bit number
      lsb = EEPROM.read(LOCATION_FILE_NUMBER_LSB);
      mib = EEPROM.read(LOCATION_FILE_NUMBER_MID);
      msb = EEPROM.read(LOCATION_FILE_NUMBER_MSB);
    
      new_file_number = msb;
      new_file_number = new_file_number << 8;
      new_file_number |= mib;
      new_file_number = new_file_number << 8;
      new_file_number |= lsb;
    
      //If both EEPROM spots are 255 (0xFF), that means they are un-initialized (first time OpenLog has been turned on)
      //Let's init them both to 0
      if((lsb == 255) && (mib == 255) && (msb == 255))
      {
        new_file_number = 0; //By default, unit will start at file number zero
        EEPROM.write(LOCATION_FILE_NUMBER_LSB, 0x00);
        EEPROM.write(LOCATION_FILE_NUMBER_MID, 0x00);
        EEPROM.write(LOCATION_FILE_NUMBER_MSB, 0x00);
      }
      if (Monitormode) {
        Serial.print("Newlog_routine FileNumber: ");
        Serial.println(new_file_number,DEC);
      }
    
      //The above code looks like it will forever loop if we ever create 65535 logs
      //Let's quit if we ever get to 65534
      //65534 logs is quite possible if you have a system with lots of power on/off cycles
      if(new_file_number == 9876543)
      {
        //Gracefully drop out to command prompt with some error
        if (Monitormode) Serial.print(F("!Too many logs:1!"));
      }
    
      //If we made it this far, everything looks good - let's start testing to see if our file number is the next available
    
      //Search for next available log spot
      //char new_file_name[] = "LOG00000.TXT";
      setting_ERR_FLG = EEPROM.read(LOCATION_ERR_FLG);
      
      if (Monitormode) 
         {
           Serial.println("test if (setting_ERR_FLG & setting_ERR_FILE_RENAME)");
           Serial.print("setting_ERR_FLG: ");
           Serial.println(setting_ERR_FLG,DEC);
           Serial.print("setting_ERR_FILE_RENAME: ");
           Serial.println(setting_ERR_FILE_RENAME,DEC);
         }
         
        if (setting_ERR_FLG & setting_ERR_FILE_RENAME)  // logging LIN_ID error occur & Renaming option active?
        {
          sprintf_P(new_file_name, PSTR("L%07d.TXT"), (new_file_number - 1)); //Splice the old file number into this file name
          if (Monitormode) 
          {
            Serial.print("old_file_name with Error: ");
            Serial.println(new_file_name);
          }
    uint8_t test = 5;
    
    while(test)
    {
          if (!newFile.open(new_file_name, O_CREAT | O_WRITE )) 
              {
                Serial.print("not possible to open file : ");
                Serial.println(new_file_name);
                error(" 2 file.open");
                test--;
                delay(200);
                
              }
          else   
             {
              test = 0;
             }
              
              Serial.print("writeFile: "); 
             // Serial.printf("%s\n",filename[13]);
    }
    
     if (Monitormode) 
              {
                Serial.print("S02: ");
                //Serial.println(new_file_name);
              }
     
      //  if (!newFile.open(&currentDirectory, new_file_name,  O_CREAT | O_RDWR))break;
          
          
              sprintf_P(new_file_name, PSTR("E%07d.TXT"), (new_file_number -1)); //Splice the old file number into this file name
              if (Monitormode) 
              {
                Serial.print("Error file_name : ");
                Serial.println(new_file_name);
              }
       
    
       //       if (!newFile.rename(&currentDirectory, new_file_name)) 
              if (!newFile.rename(SD.vwd(), new_file_name)) 
              {
                if (Monitormode) Serial.println("error renaming last File with ERROR");
              }
              newFile.close();
        
              setting_ERR_FLG = 0;
              EEPROM.write(LOCATION_ERR_FLG,setting_ERR_FLG);
              if (Monitormode) 
              {
                Serial.print("S04 : ");
              
              }
        }
    
        sprintf_P(new_file_name, PSTR("L%07d.TXT"), new_file_number); //Splice the new file number into this file name
    
        if (Monitormode) 
        {
          Serial.print("new_file_name 0: ");
          Serial.println(new_file_name);
        }
     
       
       
    //While(1)
    //{
    //    sprintf_P(new_file_name, PSTR("L%07d.TXT"), new_file_number); //Splice the new file number into this file name
    //
    //    if (Monitormode) 
    //    {
    //      Serial.print("new_file_name 0: ");
    //      Serial.println(new_file_name);
    //    }
    //
    //
    //    //Try to open file, if fail (file doesn't exist), then break
    //    if (newFile.open(new_file_name, O_CREAT | O_EXCL | O_WRITE)) 
    //    {
    //      if (Monitormode) Serial.print("//Try to open file, if fail (file doesn't exist), then break");
    //      
    //    }
    //        //Try to open file and see if it is empty. If so, use it.
    //    if (newFile.open(new_file_name, O_READ)) 
    //    {
    //      if (Monitormode) Serial.println("//Try to open file and see if it is empty. If so, use it.");
    //      if (newFile.fileSize() == 0)
    //      {
    //        newFile.close();        // Close this existing file we just opened.
    //        
    //        if (Monitormode) 
    //         {
    //          Serial.print("new_file_name_file size == 0: ");
    //          Serial.println(new_file_name);
    //          }
    //        //return(new_file_name);  // Use existing empty file.
    //
    //      }
    //      newFile.close(); // Close this existing file we just opened.
    //    }
    //
    //    //Try the next number
    //    new_file_number++;
    //    if(new_file_number > 9876542) //There is a max of 9876542 logs
    //    {
    //      if (Monitormode) Serial.print(F("!Too many logs:2!"));
    //     
    //    }
    //
    //      newFile.close(); //Close this new file we just opened
    //  }
    
    //if (!newFile.open(new_file_name, O_CREAT | O_WRITE | O_EXCL)) {
    //     if (Monitormode) 
    //          {
    //            
    //            Serial.print("S05");
    //            Serial.print(" failed open File: "); 
    //    //        Serial.printf("%s\n",filename[13]);
    //          } 
    //    error("file.open");
    //  }
    //else   
    //   {
    //    Serial.print("writeFile: "); 
    //   // Serial.printf("%s\n",filename[13]);
    //   }
    //
    
      
      new_file_number++; //Increment so the next power up uses the next file #
    
      //Record new_file number to EEPROM
      lsb = (byte)(new_file_number & 0x0000FF);
      mib = (byte)((new_file_number & 0x00FF00) >> 8);
      msb = (byte)((new_file_number & 0xFF0000) >> 16);
    
      EEPROM.write(LOCATION_FILE_NUMBER_LSB, lsb); // LSB
      if (EEPROM.read(LOCATION_FILE_NUMBER_MSB) != mib)
        EEPROM.write(LOCATION_FILE_NUMBER_MID, mib); // MIB
      if (EEPROM.read(LOCATION_FILE_NUMBER_MSB) != msb)
        EEPROM.write(LOCATION_FILE_NUMBER_MSB, msb); // MSB
    
    #if DEBUG
      if (Monitormode) 
      {
        Serial.print(F("\nNewLog Mode : Created new file: "));
        Serial.println(new_file_name);
      }
    #endif
    
      
    
    
        
    
    
    
    
      
    //
    // //  read_system_settings(); //Load all system settings from EEPROM
    //
    //  Serial.print("Initializing SD card...");
    // // Initialize at the highest speed supported by the board that is
    //  // not over 50 MHz. Try a lower speed if SPI errors occur.
    //  if (!SD.begin(SdChipSelect, SD_SCK_MHZ(50))) {
    //    SD.initErrorHalt();
    //  }
     // Find an unused file name.
    //  if (BASE_NAME_SIZE > 6) {
    //    error("FILE_BASE_NAME too long");
    //  }
    //  while (SD.exists(fileName)) {
    //    if (fileName[BASE_NAME_SIZE + 1] != '9') {
    //      fileName[BASE_NAME_SIZE + 1]++;
    //    } else if (fileName[BASE_NAME_SIZE] != '9') {
    //      fileName[BASE_NAME_SIZE + 1] = '0';
    //      fileName[BASE_NAME_SIZE]++;
    //    } else {
    //      error("Can't create file name");
    //    }
    //  }
    //if (!myFile.open(fileName, O_CREAT | O_WRITE | O_EXCL)) {
    //    error("file.open");
    //  }
    //else   
    //   {
    //    Serial.print("writeFile: "); 
    //   // Serial.printf("%s\n",filename[13]);
    //   }
     
    
      
     
    //  DataReadCounter
       // init Buffer
    
    }
    
    void loop() {
    
      int z;
      uint8_t Synch_activate = 0;
     uint8_t write_LED_state = 0;
      uint8_t read_buffer;
      
    
    
      
       if (!myFile.open(new_file_name, O_CREAT | O_WRITE | O_EXCL)) {
         if (Monitormode) 
              {
                
                Serial.print("S05");
                Serial.print(" failed open File: "); 
        //        Serial.printf("%s\n",filename[13]);
              } 
        error("file.open");
      }
    else   
       {
        Serial.print("writeFile: "); 
       // Serial.printf("%s\n",filename[13]);
       }
    
    
      
    //  
    //   if (!SD.begin(SD_CS_PIN, SD_SCK_MHZ(50))) {
    //    Serial.println("initialization failed!");
    //    return;
    //  }
    
    //
    //  if (!SD.begin(SD_CS_PIN)) 
    //  {
    //    Serial.println("initialization failed!");
    //    return;
    //  }
      Serial.print("initialization done, filestat: ");
    
    
      lastSyncTime = millis();
                digitalWrite(3, 0);
              delay(100);
              digitalWrite(3, 1);
              delay(10);
              digitalWrite(3, 0);
              delay(100);
               digitalWrite(3, 1);
      SBUS_begin();
      while(1)
      {
        //delay(1);
     // if the file opened okay, write to it:
              if ((myFile) && (set_datawrite_flag == 1))
              {
               //Serial.printn("Writing Data...");
    //           Serial.println(" ");
    //           Serial.print("Writing Data.., from Adress");
    //            z= (unsigned int)activeWritebuffer;
    //           Serial.println(z,HEX);
    //           Serial.print(" Data to Write : ");
    //           Serial.println(DataToWriteCounter);
    //    
    //          for ( uint16_t i = 0; i<DataToWriteCounter;i++ )
    //             {
    //              Serial.print(" 0x");
    //              read_buffer = *(activeWritebuffer+i);
    //              Serial.print(read_buffer,HEX);
    //              //Serial.print((*(inactiveWritebuffer+i),HEX);
    //              
    //             }
    //             Serial.println(""); 
        
               
              // myFile.println("testing 1, 2, 3.");
              digitalWriteFast(20, 1);
              myFile.write(activeWritebuffer, DataToWriteCounter-1) ;
            //  digitalWrite(ledPin, 1);
              digitalWriteFast(20, 0);
    
              
               
               set_datawrite_flag = 0; 
               if (!Synch_activate) Synch_activate= 1;
              
              }
    
           
    
    
            if(((millis() - lastSyncTime) > MAX_TIME_BEFORE_SYNC_MSEC)&&(Synch_activate ==1))//This will force a sync approximately every 5 seconds
            { 
              digitalWrite(3, 0);
              delayMicroseconds(10);
              digitalWrite(3, 1);
              delayMicroseconds(10);
              digitalWrite(3, 0);
              myFile.sync(); //Sync the card
              Serial.println("Synch");
              lastSyncTime = millis();
            }
         
      }
    }
    
    
    
    void SBUS_begin(void)
    {
      SBUS_Serial.begin(SBUS_Baudrate,SERIAL_8N1);
         // Enable receive-only
          UART0_C2 = UART0_C2_RX_ENABLE;
    
          attachInterruptVector(IRQ_UART0_STATUS, uart0_rx_status_isr);
          attachInterruptVector(IRQ_UART0_ERROR, uart0_rx_error_isr);
    
          // We fill bytes from the buffer in the framing error ISR, so we
          // can set to the same priority.
          NVIC_SET_PRIORITY(IRQ_UART0_ERROR, NVIC_GET_PRIORITY(IRQ_UART0_STATUS));
    
          // Enable UART0 interrupt on frame error
          UART0_C3 |= UART_C3_FEIE;
          NVIC_ENABLE_IRQ(IRQ_UART0_ERROR);
        //  break;
      
    }
    
    
    
    
    void SBUS_end(void)
    {
     //ed
          // Disable UART0 interrupt on frame error
          UART0_C3 &= ~UART_C3_FEIE;
          NVIC_DISABLE_IRQ(IRQ_UART0_ERROR);
    }
    
    
    
    int SBUS_readFrameData(uint8_t *buf,uint16_t len)
    {
      int z;
      bool Errorflag = 0;
      uint8_t read_buffer;
        int retval = -1;
       if (len <= 0 ) 
       {
        return 0;
       }
       // Pointer fr sicherung der Daten ausgeben
       z= (unsigned int)ptrDataSave;
       Serial.print("Adress ptrDataSave readFrame= 0x");
       Serial.println(z,HEX);
       Serial.println("");
       Serial.print(" Datareadcounter S: ");
       Serial.print(DataReadCounter);
       
    //   for ( uint16_t i = 0; i<len;i++ )
    //   {
    //    Serial.print(" B:0x");
    //    Serial.print(inactiveBuf[i],HEX);
    //   }
    
        Serial.println("");
       if (((sizeof(ErrorFrame))<len) && (len < (sizeof(ErrorFrame)+10)))
       {
        Errorflag = 1;
        for ( uint16_t i = 0; i<(sizeof(ErrorFrame));i++ )
             {
                if ((ErrorFrameVerification[i])&& (ErrorFrame[i]!=inactiveBuf[i]))
                {
                  Errorflag = 0;
                  break;
                }
    
             }
          if (Errorflag) 
          {
                  if (!setting_ERR_FLG)
                   {
    #if DEBUG
                     Serial.print("setting_ERR_FLG = 1");
                     Serial.println (" *** ");
                     Serial.println ("  !!! Errorframe detect"); 
                     //delay(10000);
                     Serial.println (" *** ");
    #endif                                          
    
                     setting_ERR_FLG = 1;
                     EEPROM.write(LOCATION_ERR_FLG,1);
                   }
    
            
            
    //# if Debug
    //            Serial.println (" ************************************************************* ");
    //            Serial.println ("  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Errorframe detect"); 
    //            delay(10000);
    //            Serial.println (" ************************************************************* ");
    //            
    //# endif            
          }
                
       }
           
    
       __disable_irq();
       if (  (DataReadCounter+256) < writebuffer_size  )
         {
       
        writeDataToInactiveBuffer(ptrDataSave,len);
    
      //     buf = buf+len;    
      __enable_irq();
         }
       else
       { 
        __disable_irq();
        Serial.printf("Swap Buffer write %d Bytes \n",DataReadCounter);
    
          if (activeWritebuffer == buffer1) 
          {
            activeWritebuffer = buffer2;
            inactiveWritebuffer = buffer1;
            ptrDataSave = buffer1;
            z= (unsigned int)ptrDataSave;
            Serial.print("Adress ptrDataSave Buffer 1= 0x");
            Serial.println(z,HEX);
            DataToWriteCounter  =DataReadCounter;
            DataReadCounter = 0;
            
          } 
          else 
          {
            activeWritebuffer = buffer1;
            inactiveWritebuffer = buffer2;
            ptrDataSave = buffer2;
             z= (unsigned int)ptrDataSave;
             Serial.print("Adress ptrDataSave Buffer 2= 0x");
             Serial.println(z,HEX);
            DataToWriteCounter  = DataReadCounter;
            DataReadCounter = 0;
          }
    
    # if Debug   
                //DataReadCounter = 0;
           
           Serial.printf("print date in write buffer, data to write: %u\n",DataToWriteCounter);
           
           for ( uint16_t i = 0; i<DataToWriteCounter;i++ )
             {
              Serial.print(" 0x");
              read_buffer = *(activeWritebuffer+i);
              Serial.print(read_buffer,HEX);
              //Serial.print((*(inactiveWritebuffer+i),HEX);
              
             }          
    # endif
               
    //      for ( uint16_t i = 0; i<DataToWriteCounter;i++ )
    //         {
    //          Serial.print(" D[");
    //          Serial.print(i,DEC);
    //          Serial.print("]:0x");
    //          Serial.println(activeWritebuffer[i],HEX);
    //         }
              Serial.println("");
              // for test only
         
         writeDataToInactiveBuffer(ptrDataSave,len);
         //  buf = buf+len; 
        __enable_irq();
        set_datawrite_flag = 1;
         Serial.println(" status writeflag");
         Serial.println((myFile) && (set_datawrite_flag == 1));
      }
        
      
       return DataReadCounter;
       
    }
    
    void writeDataToInactiveBuffer(uint8_t *buf,uint16_t len)
    {
      int z;
      uint8_t read_buffer;
    
      # if Debug  
           z= (unsigned int)ptrDataSave;
           Serial.print("Adress ptrDataSave= 0x");
           Serial.println(z,HEX);
           Serial.println("");
           Serial.print(" Datareadcounter S: ");
           Serial.print(DataReadCounter);
          
           Serial.printf("Data Read Counter before:%d \n",DataReadCounter);
      # endif
    
           // Data structure:
           // (Header 2Byte = M:) (Time in Millis as 4 byte =  0xXX 0xXX 0xXX 0xXX) (Tab Char = 0x09) (SBUS Data Frame)
           
           //write  Header  ( M: )
           memcpy(buf,Header,sizeof(Header));
           DataReadCounter += sizeof(Header);
           buf += sizeof(Header); // new Added
           
           
           //convert ulong to byte write Time in millis 
           *buf ++= (uint8_t)(packetTimestamp & 0x000000ff);
           *buf ++= (uint8_t)((packetTimestamp>>8) & 0x000000ff);
           *buf ++= (uint8_t)((packetTimestamp>>16) & 0x000000ff);
           *buf ++= (uint8_t)((packetTimestamp>>24) & 0x000000ff);
             DataReadCounter += sizeof(packetTimestamp);
                  
           // write Tab  
           *buf ++= 0x09;
    
           // write M-Dataframe 
           memcpy(buf,inactiveBuf,len);
           DataReadCounter = DataReadCounter+len+1;
           ptrDataSave = ptrDataSave+len+7;
    # if Debug       
           Serial.printf("\nData Read Counter@SBUS_readFrameData:%d \n",DataReadCounter);
           Serial.print(" Data im BufferB:");
           for ( uint16_t i = 0; i<DataReadCounter;i++ )
             {
              Serial.print(" 0x");
              read_buffer = *(inactiveWritebuffer+i);
              Serial.print(read_buffer,HEX);
              //Serial.print((*(inactiveWritebuffer+i),HEX);
              
             }
             Serial.println(""); 
    # endif
    }  
    
    
    
    void completePacket() {
      // An empty packet isn't valid
      
     int z;
      if (first) {
        first = false;
      } else {
        // Swap the buffers
        if (activeBuf == buf1) {
          activeBuf = buf2;
          inactiveBuf = buf1;
          
        } 
        else {
          activeBuf = buf1;
          inactiveBuf = buf2;
          
        }
    
        packetCount++;
        packetSize = activeBufIndex;
        packetTimestamp = millis();
      }
      activeBufIndex = 0;
       Serial.print(" Datareadcounter CompletePacket: ");
       Serial.println(DataReadCounter);
    //   z= (unsigned int)ptrDataSave;
    //   Serial.print("Adress ptrDataSave= 0x");
    //   Serial.println(z,HEX);
       //Serial.println((uint16_t)&ptrDataSave);
       SBUS_readFrameData((ptrDataSave), packetSize);
    }
    
    
    void resetPacket() {
      activeBufIndex = 0;
    }
    
    void receiveByte(uint8_t b) {
      if (activeBufIndex <  max_SBUS_Datasize) {
        activeBuf[activeBufIndex++] = b;
      }
    // Serial.print(b,HEX);
    // Serial.print(" ");
    }
    
    
    
    // ---------------------------------------------------------------------------
    //  UART0 RX ISRs
    // ---------------------------------------------------------------------------
    
    void uart0_rx_status_isr() {
      uint8_t b;
     // Receiver *instance = rxInstances[0];
    
      uint8_t status = UART0_S1;
    
    #ifdef HAS_KINETISK_UART0_FIFO
      // If the receive buffer is full or there's an idle condition
      if ((status & (UART_S1_RDRF | UART_S1_IDLE)) != 0) {
        __disable_irq();
        uint8_t avail = UART0_RCFIFO;
        if (avail == 0) {
          // Read the register to clear the interrupt, but since it's empty,
          // this causes the FIFO to become misaligned, so send RXFLUSH to
          // reinitialize its pointers.
          // Do this inside no interrupts to avoid a potential race condition
          // between reading RCFIFO and flushing the FIFO.
          b = UART0_D;
          UART0_CFIFO = UART_CFIFO_RXFLUSH;
          __enable_irq();
          return;
        } else {
          __enable_irq();
          // Read all but the last available, then read S1 and the final value
          // So says the chip docs,
          // Section 47.3.5 UART Status Register 1 (UART_S1)
          // In the NOTE part.
          digitalWriteFast(23, 0); 
    
        while (--avail > 0) {
            b = UART0_D;
            receiveByte(b);
          }
          digitalWriteFast(23, 1); 
    
        status = UART0_S1;
          b = UART0_D;
          receiveByte(b);
        }
      }
    #else
      // If the receive buffer is full
      if ((status & UART_S1_RDRF) != 0) {
        b = UART0_D;
        receiveByte(b);
      }
    #endif  // HAS_KINETISK_UART0_FIFO
    }
    
    
    //************************************* isr
    void uart0_rx_error_isr() {
      uint8_t b;
     // Receiver *instance = rxInstances[0];
    
      // A framing error indicates a break
      if ((UART0_S1 & UART_S1_FE) != 0) {
        digitalWriteFast(19, 0); 
        // Only allow a packet whose framing error actually indicates a break.
        // A value of zero indicates a true break and not some other
        // framing error.
        // Note: Reading a byte clears interrupt flags
    
    #ifdef HAS_KINETISK_UART0_FIFO
        // Flush anything in the buffer
        uint8_t avail = UART0_RCFIFO;
        if (avail > 1) {
          while (--avail > 0) {
            b = UART0_D;
            receiveByte(b);
          }
        }
    #endif  // HAS_KINETISK_UART0_FIFO
    
        b = UART0_D;
        if (b == 0) {
    
          completePacket();
        } 
        else {
    
     
          // Not a break
          //instance->resetPacket();
        }
      digitalWriteFast(19, 1); 
      }
    }
    
    /*******************************************************************************************************************************************/
    
    
    
    
    
    //Reads the current system settings from EEPROM
    //If anything looks weird, reset setting to default value
    void read_system_settings(void)
    {
      //Read what the current UART speed is from EEPROM memory
      //Default is 19200
      setting_uart_speed_RX = readBaud_RX(); //Combine the three bytes
      if(setting_uart_speed_RX < BAUD_MIN || setting_uart_speed_RX > BAUD_MAX) 
      {
        setting_uart_speed_RX = 57600; //Reset UART to 9600 if there is no speed stored
        writeBaud_RX(setting_uart_speed_RX); //Record to EEPROM
      }
    
      //Read what the current UART speed is from EEPROM memory
      //Default is 19200
      setting_uart_speed_LIN = readBaud_LIN(); //Combine the three bytes
      if(setting_uart_speed_LIN < BAUD_MIN || setting_uart_speed_LIN > BAUD_MAX) 
      {
        setting_uart_speed_LIN = 57600; //Reset UART to 9600 if there is no speed stored
        writeBaud_LIN(setting_uart_speed_LIN); //Record to EEPROM
      }
    
      //Determine the system mode we should be in
      //Default is NEWLOG mode
      setting_system_mode = EEPROM.read(LOCATION_SYSTEM_SETTING);
      if(setting_system_mode > 5) 
      {
        setting_system_mode = MODE_NEWLOG; //By default, unit will turn on and go to new file logging
        EEPROM.write(LOCATION_SYSTEM_SETTING, setting_system_mode);
      }
    
      //Read the escape_character
      //ASCII(26) is ctrl+z
      setting_escape_character = EEPROM.read(LOCATION_ESCAPE_CHAR);
      if(setting_escape_character == 0 || setting_escape_character == 255) 
      {
        setting_escape_character = 36; //Reset escape character to ctrl+z
        EEPROM.write(LOCATION_ESCAPE_CHAR, setting_escape_character);
      }
    
      //Read the number of escape_characters to look for
      //Default is 3
      setting_max_escape_character = EEPROM.read(LOCATION_MAX_ESCAPE_CHAR);
      if(setting_max_escape_character > 5) 
      {
        setting_max_escape_character = 0; //Reset number of escape characters to 3
        EEPROM.write(LOCATION_MAX_ESCAPE_CHAR, setting_max_escape_character);
      }
    
      //Read whether we should use verbose responses or not
      //Default is true
      setting_verbose = EEPROM.read(LOCATION_VERBOSE);
      if(setting_verbose != ON || setting_verbose != OFF) 
      {
        setting_verbose = ON; //Reset verbose to true
        EEPROM.write(LOCATION_VERBOSE, setting_verbose);
      }
    
      //Read whether we should echo characters or not
      //Default is true
      setting_echo = EEPROM.read(LOCATION_ECHO);
      if(setting_echo != ON || setting_echo != OFF) 
      {
        setting_echo = ON; //Reset to echo on
        EEPROM.write(LOCATION_ECHO, setting_echo);
      }
    
      //Set flags for extended mode options  
      if (setting_verbose == ON)
        feedback_mode |= EXTENDED_INFO;
      else
        feedback_mode &= ((byte)~EXTENDED_INFO);
    
      if (setting_echo == ON)
        feedback_mode |= ECHO;
      else
        feedback_mode &= ((byte)~ECHO);
    
    
    
    
      //Read whether we should ignore RX at power up
      //Some users need OpenLog to ignore the RX pin during power up
      //Default is false or ignore
      setting_ignore_RX = EEPROM.read(LOCATION_IGNORE_RX);
      if(setting_ignore_RX > 1) 
      {
        setting_ignore_RX = OFF; //By default we DO NOT ignore RX
        EEPROM.write(LOCATION_IGNORE_RX, setting_ignore_RX);
      }
    
    
    
      ////Read what the current UART speed is from EEPROM memory
      //  //Default is 19200
      setting_RX_NUMBER = readRX_NUMBER(); //Combine the three bytes
      RX_LINE_ANZAHL = setting_RX_NUMBER;
      if(setting_RX_NUMBER == 0 || setting_RX_NUMBER > 1024) 
      {
        setting_RX_NUMBER = 220; //Reset UART to 9600 if there is no speed stored
        writeRX_NUMBER(setting_RX_NUMBER); //Record to EEPROM
      }
    
      ////Read what the current UART speed is from EEPROM memory
      //  //Default is 19200
      setting_RX_FRAME_COUNT = readRX_FRAME_COUNT(); //Combine the three bytes
      RX_FRAME_COUNT = setting_RX_FRAME_COUNT;
      if(setting_RX_FRAME_COUNT == 0 || setting_RX_FRAME_COUNT > (setting_RX_NUMBER-1)) 
      {
        setting_RX_FRAME_COUNT = (setting_RX_NUMBER/2); //Reset UART to 9600 if there is no speed stored
        writeRX_FRAME_COUNT(setting_RX_FRAME_COUNT); //Record to EEPROM
      }
    
      //    //Read whether we should ignore RX at power up
      //  //Some users need OpenLog to ignore the RX pin during power up
      //  //Default is false or ignore
      setting_RESET_EE = EEPROM.read(LOCATION_RESET_EE);
    
      if(setting_RESET_EE > 1) 
      {
        setting_RESET_EE = OFF; //By default we DO NOT ignore RX
        EEPROM.write(LOCATION_RESET_EE, setting_RESET_EE);
      }
    
    
      //    //Read whether we should ignore RX at power up
      //  //Some users need OpenLog to ignore the RX pin during power up
      //  //Default is false or ignore
      setting_ERR_FILE_RENAME = EEPROM.read(LOCATION_ERR_FILE_RENAME);
      if(setting_ERR_FILE_RENAME > 1) 
      {
        setting_ERR_FILE_RENAME = ON; //By default we DO NOT ignore RX
        EEPROM.write(LOCATION_ERR_FILE_RENAME, setting_ERR_FILE_RENAME);
      }
    
      setting_ERR_FLG = EEPROM.read(LOCATION_ERR_FLG);
      if(setting_ERR_FLG > 1) 
      {
        setting_ERR_FLG = OFF; //By default we DO NOT ignore RX
        EEPROM.write(LOCATION_ERR_FLG, setting_ERR_FLG);
      }
    
    
    
    }
    
    
    //A rudimentary way to convert a string to a long 32 bit integer
    //Used by the read command, in command shell and baud from the system menu
    uint32_t strtolong(const char* str)
    {
      uint32_t l = 0;
      while(*str >= '0' && *str <= '9')
        l = l * 10 + (*str++ - '0');
    
      return l;
    }
    
    void read_config_file(void)
    {
    //  SdFile rootDirectory;
      SdFile configFile;  
     // if (!rootDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT); // open the root directory
    
      char configFileName[strlen(CFG_FILENAME)]; //Limited to 8.3
      strcpy_P(configFileName, PSTR(CFG_FILENAME)); //This is the name of the config file. 'config.sys' is probably a bad idea.
    
      //Check to see if we have a config file
        if (!configFile.open(configFileName, O_READ)) {
     // if (!configFile.open(&rootDirectory, configFileName, O_READ)) {
        //If we don't have a config file already, then create config file and record the current system settings to the file
    #if DEBUG
        Serial.println(F("No config found - creating default:"));
    #endif
        configFile.close();
     //   rootDirectory.close(); //Close out the file system before we open a new one
    
          //Record the current eeprom settings to the config file
        record_config_file();
        //return;
      }
    
      //If we found the config file then load settings from file and push them into EEPROM
    #if DEBUG
      Serial.println(F("Found config file!"));
    #endif
    
      //Read up to 22 characters from the file. There may be a better way of doing this...
      char c;
      int len;
      byte settings_string[CFG_LENGTH]; //"115200,103,14,0,1,1,0\0" = 115200 bps, escape char of ASCII(103), 14 times, new log mode, verbose on, echo on, ignore RX false.
      for(len = 0 ; len < CFG_LENGTH ; len++) {
        if( ((c = configFile.read()) < 0)) break; //We've reached the end of the file
        if(c == '\0') break; //Bail if we hit the end of this string
        settings_string[len] = c;
      }
      configFile.close();
    //  rootDirectory.close();
    
    #if DEBUG
      //Print line for debugging
      Serial.print("Configfile_StringLength : "); 
      Serial.print(len, DEC); 
      Serial.print(F(" Text Settings: "));
      for(int i = 0; i < len; i++)
        Serial.write(settings_string[i]);
      Serial.println();
      Serial.print(F("Len: "));
      Serial.println(len);
    #endif
    
      //Default the system settings in case things go horribly wrong
      //115200,115200,103,214,0,1,1,0,4000,120,0,0\0
      long new_system_baud_LIN = 57600;
      long new_system_baud_RX  = 57600;
      byte new_system_escape = 26;
      byte new_system_max_escape = 0;
      byte new_system_mode = MODE_NEWLOG;
      byte new_system_verbose = ON;
      byte new_system_echo = ON;
      byte new_system_ignore_RX = OFF;
      long new_system_RX_NUMBER = 200;
      long new_system_RX_FRAME_COUNT = 140;
      byte new_system_RESET_EE = OFF;
      byte new_system_ERR_FILE_RENAME = ON;
    
      //Parse the settings out
      byte i = 0, j = 0, setting_number = 0;
      char new_setting[7]; //Max length of a setting is 7, the bps setting = '1000000' plus '\0'
      byte new_setting_int = 0;
    
      for(i = 0 ; i < len; i++)
      {
        //Pick out one setting from the line of text
        for(j = 0 ; settings_string[i] != ',' && i < len && j < 6 ; )
        {
          new_setting[j] = settings_string[i];
          i++;
          j++;
        }
    
        new_setting[j] = '\0'; //Terminate the string for array compare
        new_setting_int = atoi(new_setting); //Convert string to int
        Serial.print("setting_number: ");
        Serial.print(setting_number ,DEC);
        Serial.print(" - ");
    
        switch (setting_number)
        {
        case 0: //baud_LIN
          new_system_baud_LIN = strtolong(new_setting);
          Serial.println(new_system_baud_LIN,DEC);
          //Basic error checking
          if(new_system_baud_LIN < BAUD_MIN || new_system_baud_LIN > BAUD_MAX) new_system_baud_LIN = 57600; //Default to 19200
          break;
    
        case 1: //baud_RX
          new_system_baud_RX = strtolong(new_setting);
          Serial.println(new_system_baud_RX,DEC);
          //Basic error checking
          if(new_system_baud_RX < BAUD_MIN || new_system_baud_RX > BAUD_MAX) new_system_baud_RX = 57600; //Default to 19200
          break;
    
        case 2: //system_escape //Escape character 
          new_system_escape = new_setting_int;
          Serial.println(new_system_escape,DEC);
          if(new_system_escape == 0 || new_system_escape > 127) new_system_escape = 36; //Default is ctrl+z
    
          break;
    
        case 3: //system_max_escape 
          new_system_max_escape = new_setting_int;
          Serial.println( new_system_max_escape,DEC);
          if(new_system_max_escape > 254) new_system_max_escape = 0; //Default is 3         
    
            break;
    
        case 4: //system_mode
          new_system_mode = new_setting_int;
          Serial.println(new_system_mode,DEC);
          if(new_system_mode == 0 || new_system_mode > MODE_COMMAND) new_system_mode = MODE_NEWLOG; //Default is NEWLOG         
    
            break;
    
        case 5: //system_verbose
          new_system_verbose = new_setting_int;
          Serial.println(new_system_verbose,DEC);
          if(new_system_verbose != ON && new_system_verbose != OFF) new_system_verbose = ON; //Default is on         
          break;
    
        case 6: //system_echo
          new_system_echo = new_setting_int;
          Serial.println(new_system_echo,DEC);
          if(new_system_echo != ON && new_system_echo != OFF) new_system_echo = ON; //Default is on
          break;
    
        case 7: //system_ignore_RX
          new_system_ignore_RX = new_setting_int;
          Serial.println(new_system_ignore_RX,DEC);
          if(new_system_ignore_RX != ON && new_system_ignore_RX != OFF) new_system_ignore_RX = OFF; //Default is to listen to RX
          break;
    
        case 8: //system_RX_ANZAHL
          new_system_RX_NUMBER = strtolong(new_setting);
          Serial.print(new_system_RX_NUMBER,DEC);
          Serial.print(" - ");
          if(new_system_RX_NUMBER == 0 || new_system_RX_NUMBER > 1024) new_system_RX_NUMBER = 220; //Default is to listen to RX
          Serial.println(new_system_RX_NUMBER,DEC);
          break;
    
        case 9: // RX_FRAME_COUNT
          new_system_RX_FRAME_COUNT = strtolong(new_setting);
          Serial.print(new_system_RX_FRAME_COUNT,DEC);
          Serial.print(" - ");
          if(new_system_RX_FRAME_COUNT == 0 || new_system_RX_FRAME_COUNT > (new_system_RX_NUMBER)) new_system_RX_FRAME_COUNT = (new_system_RX_NUMBER / 2 ); //Default is to listen to RX
          Serial.println(new_system_RX_FRAME_COUNT,DEC);
          break;
    
        case 10:  //system_RESET_EE
          new_system_RESET_EE = new_setting_int;
          Serial.println(new_system_RESET_EE,DEC);
          if(new_system_RESET_EE != ON && new_system_RESET_EE != OFF) new_system_RESET_EE = OFF; //Default is to listen to RX
    
          break;
    
        case 11:  // system_ERR_FILE_RENAME
          new_system_ERR_FILE_RENAME = new_setting_int;
          Serial.println(new_system_ERR_FILE_RENAME,DEC);
          if(new_system_ERR_FILE_RENAME != ON && new_system_ERR_FILE_RENAME != OFF) new_system_ERR_FILE_RENAME = ON; //Default is to listen to RX
          break;
    
    
        default:
    
          break;
        }
    
        setting_number++;
      }
    
      //We now have the settings loaded into the global variables. Now check if they're different from EEPROM settings
      boolean recordNewSettings = false;
    
      if(new_system_baud_LIN != setting_uart_speed_LIN) {
        //If the baud rate from the file is different from the current setting,
        //Then update the setting to the file setting
        //And re-init the UART
    
        writeBaud_LIN(new_system_baud_LIN); //Write this baudrate to EEPROM
        setting_uart_speed_LIN = new_system_baud_LIN;
        SBUS_Serial.begin(setting_uart_speed_LIN);
        Serial.print("Set LIN Baudrate: ");
        Serial.println(setting_uart_speed_LIN,DEC);
        recordNewSettings = true;
      }
    
      if(new_system_baud_RX != setting_uart_speed_RX) {
        //If the baud rate from the file is different from the current setting,
        //Then update the setting to the file setting
        //And re-init the UART
    
        writeBaud_RX(new_system_baud_RX); //Write this baudrate to EEPROM
        setting_uart_speed_RX = new_system_baud_RX;
       // HWSERIAL2.begin(setting_uart_speed_RX);
        Serial.print("Set Uart Baudrate: ");
        Serial.println(setting_uart_speed_RX,DEC);
        recordNewSettings = true;
      }
    
      if(new_system_mode != setting_system_mode) {
        //Goto new system mode
        setting_system_mode = new_system_mode;
        EEPROM.write(LOCATION_SYSTEM_SETTING, setting_system_mode);
    
        recordNewSettings = true;
      }
    
      if(new_system_escape != setting_escape_character) {
        //Goto new system escape char
        setting_escape_character = new_system_escape;
        EEPROM.write(LOCATION_ESCAPE_CHAR, setting_escape_character); 
    
        recordNewSettings = true;
      }
    
      if(new_system_max_escape != setting_max_escape_character) {
        //Goto new max escape
        setting_max_escape_character = new_system_max_escape;
        EEPROM.write(LOCATION_MAX_ESCAPE_CHAR, setting_max_escape_character);
    
        recordNewSettings = true;
      }
    
      if(new_system_verbose != setting_verbose) {
        //Goto new verbose setting
        setting_verbose = new_system_verbose;
        EEPROM.write(LOCATION_VERBOSE, setting_verbose);
    
        recordNewSettings = true;
      }
    
      if(new_system_echo != setting_echo) {
        //Goto new echo setting
        setting_echo = new_system_echo;
        EEPROM.write(LOCATION_ECHO, setting_echo);
    
        recordNewSettings = true;
      }
    
      if(new_system_ignore_RX != setting_ignore_RX) {
        //Goto new ignore setting
        setting_ignore_RX = new_system_ignore_RX;
        EEPROM.write(LOCATION_IGNORE_RX, setting_ignore_RX);
    
        recordNewSettings = true;
      }
    
      if(new_system_RX_NUMBER != setting_RX_NUMBER) {
        //If the baud rate from the file is different from the current setting,
        //Then update the setting to the file setting
        //And re-init the UART
        Serial.print("DiFFer detected new_system_RX_NUMBER fehlt: ");
        Serial.print(new_system_RX_NUMBER,DEC);
    
        Serial.print(" / setting_RX_NUMBER: ");
        Serial.println(setting_RX_NUMBER,DEC);    
    
    
        writeRX_NUMBER(new_system_RX_NUMBER); //Write this baudrate to EEPROM
        setting_RX_NUMBER = new_system_RX_NUMBER;
        RX_LINE_ANZAHL = new_system_RX_NUMBER; // definiere neuen Wert zum festlegen der max Zeichen...
        //    Serial.print("Code für set new_system_RX_NUMBER fehlt: ");
        //    Serial.println(new_system_RX_NUMBER,DEC);
        recordNewSettings = true;
      }
    
    
    
      if(new_system_RX_FRAME_COUNT != setting_RX_FRAME_COUNT) {
        //If the baud rate from the file is different from the current setting,
        //Then update the setting to the file setting
        //And re-init the UART
        Serial.print("Differ detect -  new_system_RX_FRAME_COUNT : ");
        Serial.print(new_system_RX_FRAME_COUNT,DEC);
    
        Serial.print(" / setting_RX_FRAME_COUNT: ");
        Serial.println(setting_RX_FRAME_COUNT,DEC);    
    
    
    
        writeRX_FRAME_COUNT(new_system_RX_FRAME_COUNT); //Write this baudrate to EEPROM
        setting_RX_FRAME_COUNT = new_system_RX_FRAME_COUNT;
        RX_FRAME_COUNT = new_system_RX_FRAME_COUNT; // definiere neuen Wert zum festlegen der max Zeichen...
        Serial.print("Differ detect -  new_system_RX_FRAME_COUNT : ");
        Serial.print(new_system_RX_FRAME_COUNT,DEC);
    
        Serial.print(" / setting_RX_FRAME_COUNT: ");
        Serial.println(setting_RX_FRAME_COUNT,DEC);    
    
        recordNewSettings = true;
      }
    
    
      // Code für RESET_EE FEHLt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
      if(new_system_RESET_EE != setting_RESET_EE) {
        //If the baud rate from the file is different from the current setting,
        //Then update the setting to the file setting
        //And re-init the UART
        if (new_system_RESET_EE ==1 )
        {
          // RESET_EEPROM
          EEPROM.write(LOCATION_SYSTEM_SETTING, 0xFF);
    
          EEPROM.write(LOCATION_ESCAPE_CHAR, 0xFF);
          EEPROM.write(LOCATION_MAX_ESCAPE_CHAR, 0xFF);
    
    
          EEPROM.write(LOCATION_VERBOSE, 0xFF);
          EEPROM.write(LOCATION_ECHO, 0xFF);
          EEPROM.write(LOCATION_IGNORE_RX, 0xFF);
    
    
          EEPROM.write(LOCATION_ERR_FLG, 0x0);
          EEPROM.write(LOCATION_RESET_EE, 0x0);
          EEPROM.write(LOCATION_ERR_FILE_RENAME, 0x1);
    
          EEPROM.write(LOCATION_FILE_NUMBER_LSB, 0xFF);
          EEPROM.write(LOCATION_FILE_NUMBER_MID, 0xFF);
          EEPROM.write(LOCATION_FILE_NUMBER_MSB, 0xFF);
    
          EEPROM.write(LOCATION_RX_BAUD_SETTING_HIGH,0xFF);
          EEPROM.write(LOCATION_RX_BAUD_SETTING_MID, 0xFF);
          EEPROM.write(LOCATION_RX_BAUD_SETTING_LOW, 0xFF);
          EEPROM.write(LOCATION_LIN_BAUD_SETTING_HIGH,0xFF);
          EEPROM.write(LOCATION_LIN_BAUD_SETTING_MID, 0xFF);
          EEPROM.write(LOCATION_LIN_BAUD_SETTING_LOW, 0xFF); 
    
    
    
          //Remove the config file if it is there
          SdFile rootDirectory;
     //     if (!rootDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT); // open the root directory
    
          char configFileName[strlen(CFG_FILENAME)];
          strcpy_P(configFileName, PSTR(CFG_FILENAME)); //This is the name of the config file. 'config.sys' is probably a bad idea.
    
          //If there is currently a config file, trash it _reset EE
    //      if (myFile.open(&rootDirectory, configFileName, O_WRITE)) {
    //        Serial.println(F("Deleting config"));
    //        if (!myFile.remove()){
    //          Serial.println(F("Remove config failed")); 
    //          return;
    //        }
    //      }
    
          Serial.println(F("Unit has been reset. Please power cycle"));
          while(1)
          {
            for(int time_d = 0;time_d < 20;time_d++)
            {
              pinMode(13, OUTPUT);
              digitalWrite(13, HIGH);
              delay(100 + (2*time_d*time_d));
              digitalWrite(13, LOW);
              delay(time_d*time_d + 200);
              Serial.println(F("Unit has been reset. Please power cycle"));
            }        
    
          };
    
    
    
    
        }
        // write back to File  so that it could be done only once....
    
        writeBaud_RX(new_system_baud_RX); //Write this baudrate to EEPROM
        setting_uart_speed_RX = new_system_baud_RX;
    
        // HWSERIAL2.begin(setting_uart_speed_RX);
        Serial.print("Set Uart Baudrate: ");
        Serial.println(setting_uart_speed_RX,DEC);
        recordNewSettings = true;
      }
      //  
    
      // Code für ERR_FILE_RENAME FEHLt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    
      //  if(new_system_baud_RX != setting_uart_speed_RX) {
      //    //If the baud rate from the file is different from the current setting,
      //    //Then update the setting to the file setting
      //    //And re-init the UART
      //
      //    writeBaud_RX(new_system_baud_RX); //Write this baudrate to EEPROM
      //    setting_uart_speed_RX = new_system_baud_RX;
      //    HWSERIAL2.begin(setting_uart_speed_RX);
      //    Serial.print("Set Uart Baudrate: ");
      //    Serial.println(setting_uart_speed_RX,DEC);
      //      recordNewSettings = true;
      //  }
      //  
    
    
    
    
      //We don't want to constantly record a new config file on each power on. Only record when there is a change.
      if(recordNewSettings == true) record_config_file(); //If we corrected some values because the config file was corrupt, then overwrite any corruption
    
      else
    #if DEBUG
        Serial.println(F("Config file matches system settings"));
    #endif
    
      //All done! New settings are loaded. System will now operate off new config settings found in file.
    
      //Set flags for extended mode options  
      if (setting_verbose == ON)
        feedback_mode |= EXTENDED_INFO;
      else
        feedback_mode &= ((byte)~EXTENDED_INFO);
    
      if (setting_echo == ON)
        feedback_mode |= ECHO;
      else
        feedback_mode &= ((byte)~ECHO);
    
    }
    
    
    //Records the current EEPROM settings to the config file
    //If a config file exists, it is trashed and a new one is created
    void record_config_file(void)
    {
      //I'm worried that the user may not be in the root directory when modifying config settings. If that is the case,
      //config file will not be found and it will be created in some erroneus directory. The changes to user settings may be lost on the
      //next power cycles. To prevent this, we will open another instance of the file system, then close it down when we are done.
      SdFile rootDirectory;
      SdFile myFile;
      Serial.println("Record new ConfigFile");
     // if (!rootDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT); // open the root directory
    
      char configFileName[strlen(CFG_FILENAME)];
      strcpy_P(configFileName, PSTR(CFG_FILENAME)); //This is the name of the config file. 'config.sys' is probably a bad idea.
    
      //If there is currently a config file, trash it
      if (myFile.open(configFileName, O_WRITE)) {
        if (!myFile.remove()){
          Serial.println(F("Remove config failed"));
          myFile.close(); //Close this file
      //    rootDirectory.close(); //Close this file structure instance
          //return;
        }
      }
      
    
     // myFile.close(); //Not sure if we need to close the file before we try to reopen it
    
      //Create config file
      if (myFile.open(configFileName, O_CREAT | O_APPEND | O_WRITE) == 0) {
        Serial.println(F("Create config failed"));
        myFile.close(); //Close this file
    //
    //rootDirectory.close(); //Close this file structure instance
        //return;
      }
      Serial.println(F("Config was successfully created, now record current system settings to the config file"));
      //Config was successfully created, now record current system settings to the config file
    
      char settings_string[CFG_LENGTH]; //"115200,103,14,0,1,1,0\0" = 115200 bps, escape char of ASCII(103), 14 times, new log mode, verbose on, echo on, ignore RX false.
    
      //Before we read the EEPROM values, they've already been tested and defaulted in the read_system_settings function
      long current_system_baud_RX = readBaud_RX();
      long current_system_baud_LIN = readBaud_LIN();
      byte current_system_escape = EEPROM.read(LOCATION_ESCAPE_CHAR);
      byte current_system_max_escape = EEPROM.read(LOCATION_MAX_ESCAPE_CHAR);
      byte current_system_mode = EEPROM.read(LOCATION_SYSTEM_SETTING);
      byte current_system_verbose = EEPROM.read(LOCATION_VERBOSE);
      byte current_system_echo = EEPROM.read(LOCATION_ECHO);
      byte current_system_ignore_RX = EEPROM.read(LOCATION_IGNORE_RX);
      int current_system_RX_Anzahl = readRX_NUMBER();
      int current_system_RX_FRAME_COUNT = readRX_FRAME_COUNT();
      byte current_system_RESET_EE = EEPROM.read(LOCATION_RESET_EE);
      byte current_system_ERR_FILE_RENAME = EEPROM.read(LOCATION_ERR_FILE_RENAME);
    
    
    
    
    
      //Convert system settings to visible ASCII characters
      sprintf_P(settings_string, PSTR("%ld,%ld,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\0"), current_system_baud_LIN,current_system_baud_RX, current_system_escape, current_system_max_escape, current_system_mode, current_system_verbose, current_system_echo, current_system_ignore_RX,current_system_RX_Anzahl,current_system_RX_FRAME_COUNT,current_system_RESET_EE,current_system_ERR_FILE_RENAME);
    
      //Record current system settings to the config file
      if(myFile.write(settings_string, strlen(settings_string)) != strlen(settings_string))
        Serial.println(F("error writing to file"));
      myFile.print('\0'); //Add a End of String
      myFile.println(); //Add a break between lines
    
      //Add a decoder line to the file
    #define HELP_STR "baud_LIN,baud_RX,escape,esc#,mode,verb,echo,ignoreRX,RX_Anzahl,RX_FRAME_COUNT,RESET_EE,ERR_FILE_RENAME\0"
      char helperString[strlen(HELP_STR) + 1]; //strlen is preprocessed but returns one less because it ignores the \0
      strcpy_P(helperString, PSTR(HELP_STR));
      myFile.write(helperString); //Add this string to the file
    
      myFile.sync(); //Sync all newly written data to card
      myFile.close(); //Close this file
    //  rootDirectory.close(); //Close this file structure instance
      //Now that the new config file has the current system settings, nothing else to do!
      Serial.println(F("current system settings recorded to the config file"));
    }
    
    //Given a baud rate (long number = four bytes but we only use three), record to EEPROM
    void writeBaud_LIN(long uartRate)
    {
      EEPROM.write(LOCATION_LIN_BAUD_SETTING_HIGH, (byte)((uartRate & 0x00FF0000) >> 16));
      EEPROM.write(LOCATION_LIN_BAUD_SETTING_MID, (byte)(uartRate >> 8));
      EEPROM.write(LOCATION_LIN_BAUD_SETTING_LOW, (byte)uartRate);
    }
    
    void writeBaud_RX(long uartRate)
    {
      EEPROM.write(LOCATION_RX_BAUD_SETTING_HIGH, (byte)((uartRate & 0x00FF0000) >> 16));
      EEPROM.write(LOCATION_RX_BAUD_SETTING_MID, (byte)(uartRate >> 8));
      EEPROM.write(LOCATION_RX_BAUD_SETTING_LOW, (byte)uartRate);
    }
    
    void writeRX_FRAME_COUNT(long FRAME_COUNT)
    {
      EEPROM.write(LOCATION_RX_FRAME_COUNT_MSB, highByte(FRAME_COUNT));
      EEPROM.write(LOCATION_RX_FRAME_COUNT_LSB, lowByte(FRAME_COUNT));
    }
    
    void writeRX_NUMBER(int RX_NUMBER)
    {
      EEPROM.write(LOCATION_RX_NUMBER_MSB, highByte(RX_NUMBER));
      EEPROM.write(LOCATION_RX_NUMBER_LSB, lowByte(RX_NUMBER));
    }
    
    
    
    //Look up the baud rate. This requires three bytes be combined into one long
    long readBaud_RX(void)
    {
      byte uartSpeedHigh = EEPROM.read(LOCATION_RX_BAUD_SETTING_HIGH);
      byte uartSpeedMid =  EEPROM.read(LOCATION_RX_BAUD_SETTING_MID);
      byte uartSpeedLow =  EEPROM.read(LOCATION_RX_BAUD_SETTING_LOW);
    
      long uartSpeed_RX = 0x00FF0000 & ((long)uartSpeedHigh << 16) | ((long)uartSpeedMid << 8) | uartSpeedLow; //Combine the three bytes
    
      return(uartSpeed_RX); 
    }
    
    long readBaud_LIN(void)
    {
      byte uartSpeedHigh = EEPROM.read(LOCATION_LIN_BAUD_SETTING_HIGH);
      byte uartSpeedMid =  EEPROM.read(LOCATION_LIN_BAUD_SETTING_MID);
      byte uartSpeedLow =  EEPROM.read(LOCATION_LIN_BAUD_SETTING_LOW);
    
      long uartSpeed_LIN = 0x00FF0000 & ((long)uartSpeedHigh << 16) | ((long)uartSpeedMid << 8) | uartSpeedLow; //Combine the three bytes
    
      return(uartSpeed_LIN); 
    }
    
    int readRX_FRAME_COUNT(void)
    {
      byte RXFrameCountHigh = EEPROM.read(LOCATION_RX_FRAME_COUNT_MSB);
      byte RXFrameCountLow =  EEPROM.read(LOCATION_RX_FRAME_COUNT_LSB);
    
      int RXFrameCount = (RXFrameCountHigh << 8) | RXFrameCountLow; //Combine the three bytes
    
      return(RXFrameCount); 
    }
    
    int readRX_NUMBER(void)
    {
      byte RXNumberHigh = EEPROM.read(LOCATION_RX_NUMBER_MSB);
      byte RXNumberLow =  EEPROM.read(LOCATION_RX_NUMBER_LSB);
    
      int RXNumber = (RXNumberHigh << 8) | RXNumberLow; //Combine the three bytes
    
      return(RXNumber); 
    }

  2. #2
    Senior Member
    Join Date
    Jan 2013
    Posts
    184
    Do a google search of 'break detection'. You should get at least 5 hits. I seem to recall break detection being discussed in the context of DMX. It might be useful here too.

  3. #3

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •