In this blog, we will see how to plot a rolling graph on an OLED display. For this tutorial, we will use a 0.96" OLED display with an SSD1306 driver. We will use Arduino, but the algorithm is the same for other controllers.
|
Watch video tutorial on YouTube
Basics
Now let's start from the basics. 0.96" OLED has 128x64 pixels. It has one special feature, which is a rolling display content from left to right and right to left. This feature of the display is very useful for plotting the rolling graph. Because of this, we need to plot only one point on the rightmost pixel column, and then that point is rolled by the display driver from right to left without using a controller.
So the controller's task is to put point on right most column of pixel and display driver will take care of rolling that point from right to left.
Calculating time interval
In the OLED display, we can set the rolling speed to 8 levels of speed from 0 to 7. Consider we want to draw a rolling sine wave on display, as shown in the above image. First, we will plot a single pixel on the right-most pixel column. Then this pixel column will be shifted left by the display controller. Then we need to plot the next point on the same rightmost pixel column. But for that, we need to know how much it takes to shift by one pixel for all 8 levels of speed. Once all pixels on the screen are shifted by one pixel to the left, we need to put the next pixel in the rightmost pixel column, as shown in the above animation.
The following code is used to measure the time taken by a single pixel to shift by a single pixel to the left. The output of the following code is shown below the code.
Output:
In the above image, a single pixel is traveling from right to left, and we want to calculate the time interval between pixel shifting to the adjacent column. To calculate this we will measure the time required to travel whole display from right to left. Then we will get Time taken by single pixel to travel 128 columns or pixels. By dividing this time by 128, we will get the time required for a single pixel to travel left by one pixel. To measure the time required for a single pixel to travel the whole width(128 pixels) accurately, we will measure the time required for the single pixel to travel the whole width 10 times and then divide that time by 10 to get the time for single-width travel with less error.
Speed | Time for 10 time width travel (T1) sec | Time for single width travel (T2=T1/10) sec | Time for single pixel shift (∆T = T2/128) millisec |
7 | 23 | 2.3 | 18 |
4 | 35 | 3.5 | 27.3 |
5 | 46 | 4.6 | 36 |
6 | 57.5 | 5.75 | 45 |
0 | 70 | 7 | 54.7 |
1 | 370 | 37 | 289 |
2 | 740 | 74 | 586 |
3 | 1480 | 148 | 1156 |
Now we got the time interval between two adjacent pixel shift for different speeds. In the following code, select_speed[] store the number with used for speed level in ascending order. sampling_period[] store the ∆T values from above table. In the below code. the sampling period is not taken as it is from the above table. It is adjusted to get smooth rolling plot. TimeScale[] array has the time scale of full display width. This array is used to print the timescale on display.
Another important function we need is set_pixal which is used for lighting the individual pixel. Our rolling plot will be made from a such a single pixel.
Timer Interrupt
We need to put pixel on the rightmost pixel column at a specific intervals of time. This interval must be followed accurately. If a new pixel is put into the rightmost column before the previous data in that column is shifted to left, there will be pixel overlap. OR if a new pixel is put into the rightmost column after a given interval of time, there will be a blank column, and therefore our graph will not be continuous. This mismatch in the sampling time causes the display of one more out-of-phase sine wave along with the wave we want to display as shown in the following image. To resolve this, just adjust the sampling time to get clear single sine wave.
To achieve this sampling time accurately, we need to use a Timer interrupt. We are going to use MsTimer2 interrupt. Timer1 interrupt can not be used when we are using I2C bus for the display.
Code flow
We can plot the graph of sensor data on the display. Just to keep things simple, sine wave is generated in the controller(Arduino) itself. In the following code count variable is used for sign wave. This variable is sampled at sampling period by a timer interrupt. Then these sampled points are plotted using set_pixal() function.
The following image shows the output of above code
we can add multiple waves as show in in following code
After adding one more wave using above code, output will be as shown in the following image
In above image Time = 4.6 SEC is a time scale for full display width.
In this way we can display an signal on the OLED display. Please let me know your thoughts in the comment section.
good