Arduino and Python Real Time Plot Animation | Lesson 1 Getting Started | PySerial MatPlotLib

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to this video we're going to use the python matte plot lib library to create a real-time plot as we can see the sensor data is updating in real time the sensor in use is a light dependent resistor which changes its value based upon the light that's hitting its surface we're going to use the Arduino Uno to collect the data then we'll use the matpot lib python module to plot the data in real time here's a look at the actual circuit I used to collect this data in this system level diagram we see that we have input data which in this case is sensor data going into the Arduino and the way that we get the Arduino data to the python GUI the real-time plot is through Pi serial the Imports required for this video include time serial which is the pi serial module and matplotlib we import matplotlib dot Pi plot as PLT and matplotlib.animation as animation and these are standard conventions you'll see across many sets of code let's first take a look at how we can get this data from the sensor we have the input data going into the Arduino in this case we're going to use this Loop to collect these analog to digital converter values from the Arduino the Arduino waits for the data request once it's received it collects the analog to digital converter data on analog pin 3 and does a Serial print with a new line character so the function of the Arduino is to Simply wait for request for a data point and once it receives that request it formats the data and prints it on the serial bus in this case it's pretty simple we do an analog read built-in Arduino function and a Serial dot print this python code writes the character G this is the signal to get the point so does a sear dot write in the byte prefix is to get the character transferred so the Arduino provides a data point and then we use a Seer read line and decode it all at the same time using Arduino data string we reviewed how we get the data point we request it from the Arduino and then the Arduino provides it on the python side let's dive a little deeper we use an animate function call in order to create a real-time plot this animation function call will be responsible for grabbing The Frame data our animation is a series of consecutive new frames which then replots the data creating the illusion of a real-time plot that's separated by a time interval so in this diagram the green blocks represents the animate function call which then provides the Frame data the matpot lib library takes care of all the background work in order to create the plot each frame is separated by a time interval and you can see that noted on the lower Arrow time interval will determine the distance between two frames which will influence the smoothness of the plot and the rate at which it updates here's a look at the python animate function it's really the central component to the real-time plot it requests the data point takes care of the plotting and has the formatting for the plot we'll focus in on the data request portion first which then also applies to data formatting from the Arduino as we've seen we do a Serial write with the character G in order to request the data point the Arduino takes care of collecting that point and we simply read that back by assigning the variable Arduino data under bar string that's assigned seer.readline dot decode with the input parameter ASCII because we've done a Serial print on the Arduino side with a new line character the read line then understands that that data point followed by that return character is the data point that we're interested in the decode ASCII clears all the unnecessary formatting and gets our data point ready to be formatted in the following try accept statement in the try statement we got to make sure it's a number type so that we can plot the data so that's taken care of in the first line of code where we convert it to the float this float function is a built-in python function the next line datalist.append adds this value to the data list these are the values that we're going to plot on the y-axis the Arduino float data that was just collected is added to the last index of the list as data points come in they get appended to the end of the list the data list is really the plotting window it's all the y-axis values so as a new Point comes in an Old Point is shifted out and how we implement this is by the data list assignment below the try accept statement we use a technique called slicing in order to get this plot window the syntax within the brackets is minus 50 in a colon this is python shorthand for getting the slice of data that starts in reference to the last 50 points let's now move to the rest of the animate function these are the items that actually let us plot and Define values of our figure we first do an ax clear this is an axis clear because we're continuously calling this plot we first clear out one frame to add in the new one the new one is done by ax plot and that plots our data list the data list in this case is 50 points which is our plotting window to properly see the up and down values of the y-axis we need to set a reasonable y-axis limit and that's done by set underscore y Lim the first value is the bottom value and the second value is the top value if we were to for example say a million as the Top Value then you wouldn't really be able to see the details of the up and down swings of our Arduino data for our Arduino data it's a 10-bit value which is collected from the analog read function it displays values between 0 and 1023. so I set the max limit to 1200 so that we can see every data point within this range the next two lines of code set up the text labels on this plot you can see on the outer box of the plot on the top is Arduino data the way that we can present this string is through ax dot set underboard title then pass that method a string in this case Arduino data on the y-axis I simply called it value and that's done by ax dot set under bore y label so we looked at the Frame data and what we want to animate now let's look at the animation function using the matplotlib library we first have to define the figure that we're plotting to this figure is the window that contains our subplots remember we did the import mapotlib.pi plot as PLT the first line of code fig sets up that window and we assign that PLT dot figure once the main figure container is established we then can establish the subplot and this is done by assigning ax short for axis figure dot add subplot 111. on the right we have the matplotlib documentation and by default the value is one one one which indicates which subplot we're plotting to for this video we're only doing one subplot so it's the default but I wanted to make it explicit also note that these three numbers the three ones are not separated by commas that's an acceptable syntax and is noted in the documentation if you prefer to separate the three numbers by commas you can go ahead and do so but both syntaxes are acceptable the next argument we'll take a look at is animate and we're familiar with this this is the user defined function that's called at each frame in our case our function requested data point formats it and then puts it into a list to plot and takes care of the figure parameters the next argument is frames I kept it here for educational purposes and it's commonly used in coordination with the function animation as it's defined here it'll be the first parameter of the user-defined animate function in this context it's equivalent to passing that user-defined function animate a range of values I defined it as I as their standard index or iterator and I commented out the print but if you'd like to see what's going on and how it iterates based upon the frames value it's passed then you can uncomment that out the F args assignment or the input parameters to our user-defined animate function notice in the definition animate we have I which was our frames argument followed by datalist and Seer data list is our plotting window and Seer is the object that contains the information needed to communicate with the Arduino so this function arguments parameter in the function animation allows us to pass data to our user-defined animate function data list is assigned to an empty list by assigning it the NT brackets then that's used as our plotting window in the animation function Seer is the python serial object that's used so that we can connect from USB to Arduino serially using the pi serial module this initialization Seer equals serial dot serial establishes that connection we pass it the communication port in this case com7 and the baud rate this baud rate must match what we initialize the Arduino to Output if not you'll get garbage data and it won't be of much use last but not least we have interval which is the delay between frames in milliseconds so our animate function collects The Frame data that this interval specifies the time in between each updated frame I found 100 milliseconds to be an adequate update rate for our frames if you did something like one second you'd have a big delay and it wouldn't appear to be a real-time plot and I'll do a demonstration where sometimes faster isn't better in terms of your CPU usage and optimization for your application the last two lines of code are plt.cho and seer.close plt.chow makes sure that the figure is persistent so it continuously runs until the user closes it once the user closes that map plot lib GUI then we hit the seer.close which closes out the serial connection between the computer and the Arduino you can find this full set of code on my GitHub and the corresponding Arduino code now let's take a look at a live demo to see our real-time plot in action I'm displaying the real-time plot on the left and the CPU usage on the right as alluded to previously I'll show how the interval or the update rate between the frames impacts or CPU usage with the interval being 100 milliseconds I think it's a good balance between the smoothness of the update rate and the CPU usage we're between 18 or so and 24 to 26 percent CPU usage if I go ahead and update the interval to 30 we get a smoother faster plot but notice even here when I drag the GUI across the screen there's some latency and just by viewing the CPU data on the right you can see a noticeable increase in demand on our CPU we jump up to the mid 30s for CPU usage and depending on what you're doing and interacting with the screen it might even go much higher than that so you'll have to decide whether or not it's worth it to you to get this faster update rate for the demand on your computer and maybe you have a fast computer it's more negligible but it's good to know that this interval will have an impact whether you increase or decrease it and let's go ahead and update it to one second let's say you don't need a fast update rate you don't necessarily need that fast smooth real-time plot update rate here's one second which is actually pretty much what the CPU graphs on the right are displaying as well that's what they selected for their plots this significantly decreases the load on the CPU as you can see thank you for watching this video on real-time plot using map potlib and Pi serial we use the Arduino to collect our data and then python modules to display that data in a real-time plot thank you for watching and stay tuned for more on this real-time plot series
Info
Channel: WaveShapePlay
Views: 36,822
Rating: undefined out of 5
Keywords:
Id: z14l33paZGU
Channel Id: undefined
Length: 15min 39sec (939 seconds)
Published: Sat Jul 16 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.