2 Replies Latest reply on Jun 9, 2017 1:02 PM by jason.greenberg17

    Flush/Clear Incoming Buffer with MRAA Uart Lib in C++

    jason.greenberg17

      I am currently using the c++ mraa uart library to program the serial/uart functionality of the Intel Edison Board with Arduino Expansion.  The Edison Board is mounted on a rover and receives Inertial Measurements over serial from an Inertial Measurement Unit (IMU).

       

      I have come across an issue with using the code where I found out that the input buffer is getting filled faster than the program can retrieve the data.  The IMU sensor continuously transmits data on the Tx line, I am using a baud rate of 9600.  This over filling of the input buffer too fast has resulted in the program reading old/outdated sensor data and thus my program is unable to respond in sufficient time to movements experienced by the IMU.   I know the input buffer is storing excess data because I have ran a test program (which just reads the incoming serial data and prints it to the screen) where after a few minutes of running the code I turn off the power source of the IMU (the IMU is powered separately from the Edison Board) and the Intel Edison is still reporting that it is receiving data for at least 5 minutes (roughly 1,000 characters) after I disconnect the power from the IMU.  By receiving data I mean, the mraa function dataAvailable() is true and full packets of legitimate values (not random garbage characters) are being printed to the screen.

       

      My ideal solution to the problem, would be to empty (flush) this input buffer so to that when the program is ready to read from the port it is getting the most recent data from the IMU.  However according to the mraa uart library files I could find (in my system), the only flush function  [mraa_uart_flush()] only clears the out-going buffer and not the in-coming buffer.

       

      Is there another cpp uart library that I can use on the Intel Edison board that has this flush feature ?  Or is there a way to write a function for flushing the in-coming buffer, similar to the way that mraa_uart_flush() is written.

       

      Any suggestions would be appreciated. 

      Thank You

        • 1. Re: Flush/Clear Incoming Buffer with MRAA Uart Lib in C++
          SpiderKenny

          I use UART via CPP a lot in my product.

          I don't use the mraa library, but just normal system calls. There is a methods called tcflush(..) which will do it, but you'll need the file descriptor - not sure if mraa will give you that.

           

          Alternatively, you could just write a tight loop that reads and discard data until there is nothing more to read. Use a large buffer (say 1 KB) and you'll soon flush that data. If as you say this is in cache, then you could flush the buffer in mere milliseconds that way.

           

          At 9600 bps, 1000 Characters over five minutes means your sensor is only sending less then 3 bytes per second. Assuming they are all sent in one packet, then thats only 30 bits at 9600 bps that would only take 3 milliseconds to trasnmit, leaving 997 milliseconds free every second.  In other words, a tight loop will clear the cache AND hit an empty buffer with certainty. In other-other words, the cache can be cleared quicker than your device is filling it up.

          • 2. Re: Flush/Clear Incoming Buffer with MRAA Uart Lib in C++
            jason.greenberg17

            Thank You SpiderKenny for your suggestions.

             

            I was able to remedy the issue by doing something similar to what you had described.

             

            I essentially just created a temp char array of size 1000, and force the program to fill the whole array using the mraa read function before going to reading the incoming data for real.

             

            For those who are facing similar problems and find this post useful, the code for this is something like:

             

            /* start of get_Serial_Data code */
            char imuData_buffer[75];
            for(int i=0; i<75; i++)
                 imuData_buff[i] =0; //zero out array
            
            char temp[1000];
            dev->read(temp, 1000); //dump 1000 characters from the in-coming buffer/cache
            
            /* poll for data to be available (probably not needed) */
            while(!dev->dataAvailable())
            {
                 usleep(1) ;
            }
            
            int len = dev->read(imuData_buffer, 75); //get data from IMU (serial port) to be processed elsewhere in the program
            /* end of get_Serial_Data code*/