SerialPlot – Realtime Plotting Software for UART/Serial Port

SerialPlot is my new open source adventure. It allows you to plot data coming through your computers serial port. To be honest, nowadays it’s most likely this will be a USB port, emulating serial port.

It supports binary and ASCII data formats. Binary formats include uint8, int8, uint16, int8, uint32, int32 and float. There is also multi channel support. SerialPlot doesn’t require a sophisticated package format. It just assumes each channels data is sent consecutively. That means all channels should be synchronized. In case of ASCII it’s different. ASCII input actually can be in CSV (comma separated values) format. Each channel is sent as a column.

Below is a screenshot of the SerialPlot:

 

Currently there is installation package for debian/ubuntu only. I hope to add windows support soon, and some other linux distributions as well. You can download debian package from here.

Source code is released under GPLv3 license. You can obtain code from my mercurial repository over at bitbucket. I also have created a project page at hackaday.io.

If you have any trouble installing/building, please let me know.

40 thoughts on “SerialPlot – Realtime Plotting Software for UART/Serial Port

  1. Hi, Your SerialPlot is very interesting. Can I ask you a question? I would like to transfer a data package to computer by SerialPlot, what format of the data package could be? I’m just using ADC to convert and DMA, then transfer through UART and STM32F4 microcontroller. Thanks in advance!

    1. Hey Jack, I’m glad you are interested.

      SerialPlot supports binary and ASCII (text basically) formats. Simplest to implement in my opinion is the ASCII format. You just print the data in seperate lines. Like this;

      printf("%d,%d\r\n",chan0,chan1)

      But this can be slow and insufficient depending on your sampling speed and uart speed. In this case you should use one of the binary formats. Let me know if you want to know about binary formats.

      1. Thanks for replying! I just use DMA to collect data from a single channel ADC. So there are 3 options: binary, acsii, and custom frame. I’m going to select the third option for this purpose of sending, for example, 10 bytes from memory (DMA-UART). So how does the frame look like?

        1. Okay, so you want to package your data in a binary frame. The reason third option is called ‘Custom Frame’ is that it allows you to define your own custom frame format. Let me give you an example frame format. First we should determine our sample type and how many channels are there. Lets say sample type is 16-bit signed integer, which is defined as int16_t in standard C. And lets say we have 2 channels to send. We also decide that every frame contains 5 sample of each channel. That means our payload size will be 2 (bytes per sample) x 2 (channels) x 5 (samples) = 20 bytes. We also need to select some kind of “frame start indicator”, let say this should be 0x7E. An example frame would be like this:

          I hope this image explains things. Let me know if it doesn’t.

          Now we should set these options in serialplot “data format” tab.

          Frame Start: 0x7E
          Channels: 2
          Frame Size: Fixed and ’20’
          Number Type: int16
          Endianness: Little (STM32 is little endian)
          Checksum: not checked

          Rest is implementing the code to send data in this format. I think you can pull that off. If you need any help or want to know about other features (flexible frame size, checksum) just let me know.

          1. I just have 1 channel, and 10 float data samples. Here is my code but it does not work. What’s wrong here?
            HAL_ADC_Start_DMA(&hadc1,(uint32_t*)ADC_Value,10);
            for (int i=0;i<10;i++)
            {
            temp[i] = (float)(3.3*ADC_Value[i]/256);
            }
            printf("%d",0xFF); // Frame Start = 0xff
            printf("%d",0x01); // Number of channels = 1
            printf("%d",0x28); // Fixed size of data = 40
            for (int i=0;i<10;i++)
            {
            printf("%f",temp[i]); // float data
            }

            1. First, when in custom frame mode, you shouldn’t use printf function. Printf converts numbers to text, in binary mode you should send them directly. I don’t know what library you are using but you should have a function to send data byte by byte. Let’s say we have a function named uart_send(uint8_t data) that sends 1 byte from uart. In this case you would send the frame start with this:

              uart_send(0xFF);

              Second, you don’t send number of channels as part of the frame. Maybe I should add this as an option. But it is not supported at the moment.

              Third, if you select the ‘Fixed Size’ option you don’t send the payload size as part of the frame, you should set it in the SerialPlot interface only.

              Here is a complete example (I’m assuming you have a function named `uart_send`):


              float temp[10];
              uint8_t* data = (uint8_t*) temp; // type casting for ease of access

              uart_send(0xFF); // send frame start

              uart_send(40); // payload size, remove this line if 'fixed size' option is selected

              // send samples array byte by byte
              for (int i = 0; i < 40; i++) { uart_send(data[i]); }

              I hope this is helpful.

  2. Hi
    Your tool is Amazing! it helped me alot.
    I’d like to know if it’s capable of logging streaming data into a txt file or a spreadsheet?\

    thanks

    1. Hi Isra, thanks a lot for your compliments! I’m very glad to be helpful.

      I’m guessing you have created this issue? SerialPlot does export what you see on the screen. If you change the plot width from the “Plot” tab, it will plot more data that you can export. But to be honest, above 10000 points it starts to get really slow. I think this is not enough for you. I will try implement an interface to log everything to a file. This shouldn’t be hard…

      1. Hi again
        I’ve tried it with my Arduino Pro Micro and it seems to not capture anything. Is there a reason for that?
        Note that Arduino Pro Micro and Leonardo use virtual serial communication, could that be the reason?
        thanks

        1. SerialPlot should work fine with virtual serial ports. If you can open that ‘port’ with a generic terminal application, serialplot should be able to open it as well. I suggest you to check your data with a terminal application. What data format are you using? Are you seeing any errors in “Log” tab?

          1. No I’ve tried it with the serial monitor and RealTerm (captured the data to a txt file too). The readings were as expected, this only happens when I try it with serialPlot.

  3. Hi,

    I just want to say thank you for your efforts on creating SerialPlot. It works very well and has every feature that I expect from a serial plotter.

    Cheers.

  4. Hi hyOzderya, thanks so much for SerialPlot, very easy to use. I have a PSOC 5 spitting out thermistor temperature data.

    Greg

  5. Hi, hyOzderya.

    I want to thank you for SerialPlot. I needed a serial plotter that was a bit more configurable than the one in the Arduino IDE. Having looked at lots of plotters that were either too simple or horribly complicated to set up, I found SerialPlot, and I had it doing everything I wanted in 5 minutes flat. It’s beautifully designed. You’ve done a great job.

  6. Thanks for a useful tool, I’m currently making a tool for graphs on stm32, sd card and TFT display for data acquisition. A very useful function is to scale the graph both horizontally and vertically.

        1. I’m sorry. I still don’t get it. Do you mean zoom with the scroll wheel?

          By the way if you haven’t noticed, you can press and drag the mouse over the X and Y axes for horizontal/vertical zoom in a precise manner.

    1. Robert, thanks for sharing this 🙂 I’m always happy to see SerialPlot being used. I personally prefer 1px lines because it allows more detail but I agree that this should be an option. I will add it to my TODO list.

  7. Hey Hasan, thank You for creating this amazing UART data plot and save program. It is perfect suitable for my paper! But when Im trying to catch data over your program, it seems to do over sampling with constant 44Hz. Im 100% sure that desired frequency has to be 100Hz, but 92 is shown on FFT. Do You have any idea how to fix this?

    1. Juraj, I don’t understand your problem. Serialplot may not be able to keep up with the incmoning data rate sometimes and drop data. But it’s usually very good up to 10-20 kilo samples per second. I don’t know what your sample rate is, but I wouldn’t expect it to have a problem with 44Hz signal. I’m just guessing; maybe your baud rate is too small and you are missing data?

      1. Baud rate is sufficient. My samole rate is 500Hz, Im sampling microphone. Imput accoustic (audio) signal is 100Hz. I collect 1024 samples with Serialplot, put it into Matlab, make FFT and it shows fundamental frequency at 92Hz insptead of 100Hz.

        1. Juraj my signal processing skills aren’t very good but I think that; altough 500Hz sample rate for a 100Hz signal is enough in theory, in practice if you want accurate FFT results I recommend at least 10 times the frequency of your input signal or even higher as your sampling rate. 500Hz is too slow. I doubt that serialplot is missing any data. If it does you can usually notice it from the shape of the signal. In such case, there would be spikes in the signal (up or down).

          1. For 100Hz signal 200Hz sampling is sufficient (Nyquist theorem) I had confirmed that by my previous data logger. Your Serialplot is showing accurate sample rate 500SPS in right down corner. But when I make FFT with respect of sampling f 500Hz it is showing as I said 92Hz. When I calculate FFT with respect of sampling frequency 540Hz it shows fundamental right at 100Hz. From this implies, that program is doing some kind of over sampling.

            1. But serialplot doesn’t do sampling. It just gets the data from serial port, displays it and writes it to file. Unless some data is missing (unlikely at these speeds) it shouldn’t change the input signal at all. Maybe data is duplicated, or read twice? What is your data format? Have you tried capturing the data with another program and look at it? If you can provide me your SerialPlot settings file and the raw data from serialport I might try to reproduce the issue..

    1. Well simple binary mode is pretty simple. I don’t think it needs explaining.

      In custom frame mode, format depends a lot on your settings. I will make up a simple example from my mind here.

      Frame start: AA BB
      Number of Channels: 2
      Frame size: Fixed = 4
      Number type: uint8
      Little endian, No checksum

      Example data: ch1=[0x10, 0x20, 0x30, 0x40] ch2=[0x15, 0x25, 0x35, 0x45]

      Corresponding binary frame: 0xAA 0xBB 0x10 0x15 0x20 0x25 0x30 0x35 0x40 0x45

      Notice that samples from different channels are interleaved. If there was a 3rd channels its samples would be in between not added to the end!

      If your frame isn’t a fixed size, number of bytes should be a byte right after the start bytes. It only includes number of bytes after itself not including checksum (if it’s enabled). For example above frame with payload size as a byte (0x08):

      0xAA 0xBB 0x08 0x10 0x15 0x20 0x25 0x30 0x35 0x40 0x45

      Hope this is helpful.

      1. Thank you so much!
        By reading your posts, I have the understanding in custom frame format.
        My question is if I use simple binary, I can not plot multi-channels.
        So, the simple binary frame is simple fill: 0x10 0x15 0x20 0x35 0x40…
        Ma I right?

        1. You can still use multiple channels in simple binary mode. Different channel’s samples follow each other. For example (number format is uint8):

          Channel 1’s samples: 0x10 0x11 0x12 …
          Channel 2’s samples: 0x20 0x21 0x22 …

          Sent data: 0x10 0x20 0x11 0x21 0x12 0x22

          As you may guess synchronization is going to be a problem. If a byte is missed while reading, everything will shift. You will either have broken data or wrong channel data. You have to manually fix the synchronization using “Skip Byte/Sample” buttons. In my experience if you have a serial port that is always open you don’t lose synchronization, things just work out. But if you are going to collect data for a long time you should be careful. Using custom frame is always the safer choice.

      1. One port is enough for me, but I do have more than one data sream coming over the port. I’m experimenting with splitting the port and running two instances of serialplot.

  8. Again, this is a great tool. I use the multiple plot feature a lot. It would be nice if I could have multiple plots on each pane.
    I have dutycycle, current, and speed data from four motors. So, for example, I would like to plot all four currents in one pane and all four speeds in another.
    It would be so intuitive if I could just select a pane and then bring up the plot options.
    Thanks again for all your work.

Leave a Reply

Your email address will not be published.