Electronics Software Development

Using The Arduino Serial Plotter To Visualize Real Time Data

Arduino Real Time Waveforms
Written by John Woolsey

Skill Level: Intermediate

Introduction

This tutorial will teach you how to display waveforms and real time data using the Arduino Serial Plotter. A basic understanding of electronics and programming is expected along with some familiarity with the Arduino platform. If you are new to the Arduino platform or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On An Arduino Uno tutorial before proceeding with this one.

The resources created for this tutorial are available on GitHub for your reference.

What Is Needed

  • Linux, macOS, Or Windows Based Computer With A USB Port
  • Arduino IDE
  • Arduino Uno WiFi R2 (available on Arduino and SparkFun) With Compatible USB Cable

Background Information

Although I have worked with the Arduino IDE for a while now, I only recently came across a really cool feature called the Serial Plotter. I had previously seen it in the Tools pulldown of the main menu, but had assumed that since I did not have a physical plotter, it did not apply to me. I only realized recently that it is actually used for plotting values on a graph and can be a valuable tool for visualizing data along with debugging code. You know what they say about assumptions.

My development system consists of the Arduino Uno WiFi Rev2 development board connected to a macOS based computer running the desktop Arduino IDE. If you are using a different Arduino board or computer setup, the vast majority of this tutorial should still apply, however, some minor changes may be necessary. I am using the Uno WiFi R2 in this tutorial to take advantage of the on-board inertial measurement unit (IMU) so that I do not have to connect additional hardware.

If you need assistance with your particular setup, post a question in the comments section below and I, or someone else, can try to help you.

Displaying Generated Waveforms

This section will describe how to generate and display waveforms using the Serial Plotter.

Open the Arduino IDE and create a new sketch named FunctionGenerator with the code shown below.

void setup() {
   Serial.begin(9600);  // initialize serial bus (Serial Plotter)
}

void loop() {
   // Uncomment one of the wave types below to display in Serial Plotter.
   // Serial Plotter window may need to be closed and reopened between runs
   // to remove old plot data.
   // plotCombinedWaves();
   // plotSawtoothWave();
   plotSineWave();
   // plotSquareWave();
   // plotTriangleWave();
}

void plotCombinedWaves() {
   for (float i = 0.0; i <= 2 * PI; i += 0.1) {
      Serial.print(cos(i));  Serial.print(" ");  // cosine wave
      Serial.print(sin(i));  Serial.print(" ");  // sine wave
      Serial.println(i <= PI ? -1.5 : 1.5);      // square wave
   }
}

void plotSawtoothWave() {
   for (int i = 0; i <= 100; i++) {
      Serial.println(i);
   }
}

void plotSineWave() {
   for (float i = 0.0; i <= 2 * PI; i += 0.1) {
      Serial.println(sin(i));
   }
}

void plotSquareWave() {
   for (int i = 0; i <= 100; i++) {
      Serial.println(0);
   }
   for (int i = 0; i <= 100; i++) {
      Serial.println(100);
   }
}

void plotTriangleWave() {
   for (int i = 0; i <= 100; i++) {
      Serial.println(i);
   }
   for (int i = 100; i >= 0; i--) {
      Serial.println(i);
   }
}

The code should be fairly straightforward, but if there is something that needs further explanation, please let me know in the comment section and I will try to answer your question.

Open the Serial Plotter window (Tools > Serial Plotter) and make sure the baud rate is set to 9600. This is where the generated waveforms will be displayed.

Upload (Sketch > Upload) the sketch to the board and you should see a sine wave being displayed in the Serial Plotter window as shown below.

Arduino Serial Plotter Sine Wave
Sine Wave In Serial Plotter Window

If we take a look at the sketch, we see that the plotSineWave() function is being called from within the loop() function. Display one of the other waveforms by commenting out the plotSineWave() function, uncommenting one of the other waveforms, and rerunning your sketch. Note, if you see data left over from the previous plot, you will need to close and re-open the Serial Plotter window to clear the screen.

Reviewing the plotSineWave() function, we see the data is simply being sent using the Serial.println() function that you are probably already familiar with for printing text and data to the Serial Monitor. As long as only numbers and whitespace are sent over the serial port in a particular format, the Serial Plotter can interpret that data to graph it visually. This format requires that a new line character be sent in between x-axis tick marks and that y-axis values are separated by whitespace such as a space or tab.

For instance, we would use the following general format to plot single variable data

Serial.println(data);

and the following for multivariable data.

Serial.print(dataA);  Serial.print(“ “);  Serial.println(dataB);

Notice that only the last statement, println(), actually sends a new line. You can add more variables as long as you add the appropriate whitespace in between the print() statements for each of the variables. You may even choose to use a tab, print(“\t”), in between your variables to make the data easier to read while viewing the data directly within the Serial Monitor window.

Whereas all other wave functions display only a single variable plot, the plotCombinedWaves() function displays three different waveforms simultaneously. View this function for a better understanding of how to plot a multivariable graph. The plot for this is shown below.

Arduino Serial Plotter Combined Waveforms
Combined Waveforms In Serial Plotter Window

Displaying Real Time Data

Until now, we have only plotted data for waveforms we generated ourselves. Now let’s use the on-board IMU of the Arduino Uno WiFi R2 to plot actual real time motion data.

Create a new sketch named LSM6DS3_SerialPlotter with the code shown below. I won’t go into the details of how to access the IMU data, but if you are interested, please see our Accessing The IMU On The New Arduino Uno WiFi Rev2 tutorial for more information.

// Includes
#include <SparkFunLSM6DS3.h>
#include <SPI.h>

// Defines
#define PLOT_INTERVAL 100

// Global Variables
unsigned long previousTime = 0;

// Constructors
LSM6DS3 imu(SPI_MODE, SPIIMU_SS);  // set SPI mode and chip select for on-board IMU

void setup() {
   Serial.begin(9600);  // initialize serial bus (Serial Plotter)
   delay(1000);         // wait one second for IMU reset to complete
   imu.begin();         // initialize IMU
}

void loop() {
   unsigned long currentTime = millis();
   if (currentTime - previousTime >= PLOT_INTERVAL) {
      Serial.print(imu.readFloatAccelX());  Serial.print(" ");  // x-axis
      Serial.print(imu.readFloatAccelY());  Serial.print(" ");  // y-axis
      Serial.println(imu.readFloatAccelZ());                    // z-axis
      previousTime = currentTime;
   }
}

Within the loop() function, we are accessing and displaying all three axes of the IMU motion data every 100 ms. The plot of this data is shown below.

Arduino Serial Plotter IMU
IMU Sensor Data In Serial Plotter Window

The blue squiggles at the beginning of the graph represent moving the board in the x direction. The red and green ones represent the y and z directions respectively. The mass of movement in all directions at the end of the graph represents moving and rotating the board in all kinds of directions.

Summary

In this tutorial, we learned how to generate and display various types of waveforms using the Arduino IDE’s Serial Plotter. We also learned how to graph real time motion data from the Arduino Uno WiFi R2’s on-board IMU.

The Serial Plotter may be a simple tool, but it can be a powerful one allowing you to visualize and debug your program’s data and sensor measurements. As they say, “a picture is worth a thousand words”.

The final source code used for this tutorial is available on GitHub.

Thank you for joining me in this journey and I hope you enjoyed the experience. Please feel free to share your thoughts in the comments section below.

About the author

John Woolsey

John is an electrical engineer who loves science, math, and technology and teaching it to others even more.
 
He knew he wanted to work with electronics from an early age, building his first robot when he was in 8th grade. His first computer was a Timex/Sinclair 2068 followed by the Tandy 1000 TL (aka really old stuff).
 
He put himself through college (The University of Texas at Austin) by working at Motorola where he worked for many years afterward in the Semiconductor Products Sector in Research and Development.
 
John started developing mobile app software in 2010 for himself and for other companies. He has also taught programming to kids for summer school and enjoyed years of judging kids science projects at the Austin Energy Regional Science Festival.
 
Electronics, software, and teaching all culminate in his new venture to learn, make, and teach others via the Woolsey Workshop website.

12 Comments

  • can you help me
    i want to make combine waves, but from square wave and triangle wave
    i have no idea how to do that
    thank you

    • This can be done by creating a new plotSquareAndTriangeWaves() function using the plotTriangleWave() function as the base, adding a couple of lines to include the square wave, and then call the new function from the loop() function. The complete function is shown below.

      void plotSquareAndTriangeWaves() {
         for (int i = 0; i <= 100; i++) {
            Serial.print(0);  Serial.print(" ");    // square wave
            Serial.println(i);                      // trianagle wave
         }
         for (int i = 100; i >= 0; i--) {
            Serial.print(100);  Serial.print(" ");  // square wave
            Serial.println(i);                      // trianagle wave
         }
      }
  • HI John, thank You for your information above plotter. i am a new guy on arduino, but i have a question. How can make work a old plotter whit arduino. i have a vinyl plotter but i do o have a sofware any more>

    • Hi Juan,
      The Serial Plotter referred to in this tutorial is a software feature of the Arduino IDE for plotting values on a graph. I believe you are asking for help on a hardware based plotter of which I do not have any experience.

    • I’m sorry, but I don’t quite understand your question. If you are referring to the values of 0 and 100 I used, they are just arbitrary numbers I picked for the Y-axis. You could use any two numbers to represent the bottom and top values of the square wave. For instance, the plotCombinedWaves() function uses values of -1.5 and 1.5 for the square wave values.

    • Hi John, the aim is to permutate the number of square waves.. I have achieved the square wave but to permutate the square wave along the Y-axis at same time has got be stacked. Your help would be very much appreciated

    • Are you referring to something like the following?

      void plotSquareWaves() {
         for (int i = 0; i < 10; i++) {
            Serial.print(0);  Serial.print(" ");  Serial.print(2);  Serial.print(" ");  Serial.println(4);
         }
         for (int i = 0; i < 10; i++) {
            Serial.print(1);  Serial.print(" ");  Serial.print(2);  Serial.print(" ");  Serial.println(4);
         }
         for (int i = 0; i < 10; i++) {
            Serial.print(0);  Serial.print(" ");  Serial.print(3);  Serial.print(" ");  Serial.println(4);
         }
         for (int i = 0; i < 10; i++) {
            Serial.print(1);  Serial.print(" ");  Serial.print(3);  Serial.print(" ");  Serial.println(4);
         }
         for (int i = 0; i < 10; i++) {
            Serial.print(0);  Serial.print(" ");  Serial.print(2);  Serial.print(" ");  Serial.println(5);
         }
         for (int i = 0; i < 10; i++) {
            Serial.print(1);  Serial.print(" ");  Serial.print(2);  Serial.print(" ");  Serial.println(5);
         }
         for (int i = 0; i < 10; i++) {
            Serial.print(0);  Serial.print(" ");  Serial.print(3);  Serial.print(" ");  Serial.println(5);
         }
         for (int i = 0; i < 10; i++) {
            Serial.print(1);  Serial.print(" ");  Serial.print(3);  Serial.print(" ");  Serial.println(5);
         }
      }

      This function provides three square waves with each of the eight for loops providing a 12.5% (100/8 = 12.5%) slice of the total time. Each square wave also has different amplitudes so that they are separated within the Serial Plotter window.

    • Great question. Something like the following should work for you.

      const unsigned long SamplePeriod = 1000;  // sampling period of 1 second
      void plotExternalSignal() {
         static unsigned long previousTime = 0;
         unsigned long currentTime = millis();
         if (currentTime - previousTime >= SamplePeriod) {
            float signal = ...;  // get signal from external source
            Serial.println(signal);  // send value to the Serial Plotter
            previousTime = currentTime;
         }
      }

      The above code will read the signal from the external source and send it to the Serial Plotter every second (1000 ms). Update the SamplePeriod constant to the appropriate value for your project. You also need to update the float signal line to actually read the external signal.

  • hi thanks , but can you help me with plotting the dht11’s temperature and humidity on the serial plotter as 2 different graphs please.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.