1 Attachment(s)
[RESOLVED] Plotting Real Time Graph
Hello. I would like to seek guidance on to do a real time graph.
Currently, my circuit is connected to a power supply and is connected to the computer via a RS232 cable. Voltage level is extracted and the real-time voltage level is plotted (see attached image) and it will keep moving.
But you will realise that there isnt any time shown on the X-axis. I would like to display time in such a way:
Each long marker will represent 1 second and there are 4 long marker, which will represent up to 4 seconds.
When the (5th second) voltage is sense and the real-time voltage is drawn, i would like the new time (5th second) to replace into the 1st marker postion, the (6th second) to replace the 2nd marker position, so on and so forth. The replacement will continue.. ..
As in i would want to have a moving real time. I am currently still doing research on how to do that.
But in the mean time, if anyone of you have any suggestions / guidance on how to do that, i would really appreciate if you can post it.
Thanks in advance! :)
Attached is also the code on plotting the real-time voltage graph on a picturebox and also the timer coding for reference, if needed.
Code:
'Details of the graph layout
Dim Origin As New Point(50, 220)
Dim xAxisLength As Integer = 210
Dim yAxisLength As Integer = -250
If voltsQ.Count > 2 Then
'Turn the queue into an array:
Dim voltsQarray As Single() = voltsQ.ToArray
'Define an array of data points:
Dim DataPoints(voltsQ.Count - 1) As Point
Dim x, y As Integer
'Fill in the array using the voltage readings:
For i As Integer = 0 To voltsQ.Count - 1
'Get the volts value from the queue:
Dim v As Single = voltsQarray(i)
'Find the distance along the x axis:
x = Origin.X + CInt(i * xAxisLength / 40)
'find the height of the data point on the Y axis:
y = Origin.Y + CInt(v * yAxisLength / maxVolts)
'Put the point in the array
DataPoints(i) = New Point(x, y)
Next
'Draw the waveform:
e.Graphics.DrawCurve(Pens.Green, DataPoints)
End If
Timer coding:
Code:
'read the voltage and get value from RS232 interface
Call OpenPORT1()
Single.TryParse(TextBoxVoltage.Text, volts1)
'add the new reading to the end of the queue
voltsQ.Enqueue(volts1)
'remove the old reading at the head of the queue, to keep max. 40 data points
If voltsQ.Count > 40 Then voltsQ.Dequeue()
'update the display with the new data
Me.Refresh()
Re: Plotting Real Time Graph
Kindly refer to this thread too, if necessary.
This post is related to the url as shown below.
http://www.vbforums.com/showthread.php?t=593254&page=2
Re: Plotting Real Time Graph
OK, to do this you'll need another Timer and five Labels. You position the labels under the second positions of your graph's x axis. Set the Timer interval to 1000 ms. You'll need a form-level variable for the starting time, and you set it to the current time when you start recording the voltages. At the same time, clear any previous times from the labels (which I'll assume are called Label1 to Label5):
vb.net Code:
'at form level:
Private StartTime as DateTime
'when you start recording:
StartTime = DateTime.Now
Label1.Clear
'... and so on for the other labels.
I'll assume the labels are called Label1 to Label5 positioned from left to right. In the Tick sub of the 1-second timer, you can provide their texts working from right to left like this:
vb.net Code:
Dim dt As DateTime = DateTime.Now
Dim ts As TimeSpan = dt - StartTime
Label5.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
Label4.Text &= " ; " & ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
'...and so on until you reach Label1.
If there's a more elegant way to turn the TimeSpan into a string, perhaps someone can suggest it.
bye, BB
Re: Plotting Real Time Graph
Code:
ts.ToString("hh:mm:ss")
Re: Plotting Real Time Graph
@MaximilianMayrhofer
Thanks for the suggestion. Will take note of it and try out. :)
@boops boops
Thanks for your help once again. But i'm not clear regarding the following and need your help to clarify my doubts:
Code:
'at form level:
Private StartTime as DateTime
'when you start recording:
StartTime = DateTime.Now
Label1.Clear'
... and so on for the other labels.
I understand where to declare Private StartTime as DateTime ,
but as for
StartTime = DateTime.Now
Label1.Clear.. ..', i'm kinda lost on where to declare those. =x :confused:
Re: Plotting Real Time Graph
@Catherine. Put it wherever you start recording. If you start recording as soon as you start the program, it could go in the form's Load sub. If you use a button to start and stop recording, it would belong in the button's Click sub.
If you start by connecting the hardware, then there's a problem. I thought I would be able to figure it out from the code you posted but it leaves me mystified. You are reading the voltage value from the text box, and you are getting a plausible-looking output graph. But you do not show anywhere how you get data from the serial port into the text box. How does it get there? That OpenPort1 sub certainly doesn't do anything with volts or TextBox1.Text. Maybe we should go back to the other thread again!
BB
Re: Plotting Real Time Graph
Code:
Put it wherever you start recording. If you start recording as soon as you start the program, it could go in the form's Load sub. If you use a button to start and stop recording, it would belong in the button's Click sub.
Yesterday afternoon , I think i tried putting at the Form1_Load, but it when i included the Label1.Clear() in it, but it has an error (wriggly green light) under it, something like it is not a member of .. .. i cant rmb, have to go back to school and check later. :o
Code:
If you start by connecting the hardware, then there's a problem. I thought I would be able to figure it out from the code you posted but it leaves me mystified. You are reading the voltage value from the text box, and you are getting a plausible-looking output graph. But you do not show anywhere how you get data from the serial port into the text box. How does it get there? That OpenPort1 sub certainly doesn't do anything with volts or TextBox1.Text. Maybe we should go back to the other thread again!
Anyway, once i connect the hardware and debug the program,
1) the voltage level will be automatically sense
2) and display on the "Voltage Level in Volts" textbox. (It will be a varying voltage).
>> The "Graphical Display" (waveform) is following the voltage shown from the Voltage Level in Volts.(Varying Voltage)
I also have a textbox showing the average voltage[to stabilize the moving needle - the one you help me on].
(But I didnt use your method of Enqueue and dequeue , my supervisor ask me do another method). I stored the voltage levels in seperate textboxes and average it.
The moving needle will actually follow the Average Voltage.
As for the OpenPort1, if i tried replacing it with the suggestion you gave on the another thread: volts = CSng(SerialPort1.ReadByte / 255), or if i change it to Call ReadSerialPort1, it will not work and it also states that this port is close. ><
I hope the explanation for the above is clear. =) If not please inform me and i'll explain it again. :)
2 Attachment(s)
Re: Plotting Real Time Graph
@MaximilianMayrhofer :
I used your method, but it states that "Overload resolution failed because no accessible 'ToString' accepts this number of arguments".
@ BB :
I've added everything as shown below. But the timer didnt work the correct way i wanted it to be? Or is it suppose to be this way(but i doubt so). :confused:
Im really sorry to trouble you in dealing with my list of questions.
Timer 4 code:
Code:
Private Sub Timer4_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer4.Tick
Dim dt As DateTime = DateTime.Now
Dim ts As TimeSpan = dt - StartTime
Label1.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
Label2.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
Label3.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
Label4.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
Label5.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
End Sub
Code:
Private StartTime As DateTime
Form1_Load Code:
Code:
StartTime = DateTime.Now
Label1.Text = ""
Label2.Text = ""
Label3.Text = ""
Label4.Text = ""
Label5.Text = ""
(I changed the label1.clear() to Label1.text = "" as the method you gave couldnt work.)
When the very first data comes it, (See first image : Solar Cell - Starting)
1) Label1 will start with 0:0:0
2) Label2 , Label3, Label4, Label5 will start with (0:0:1) together at the same time. Is it suppose to work in this way?
Then the next moment: (See attached image - Solar Cell 1 Sec)
1) Label1 will become 0:0:1
2) Label2 , Label3, Label4, Label5 will become (0:0:2) together at the same time.
The next moment:
1) Label 1 will be replaced and become 0:0:2
But I thought label 1 will be 0:0:0, label2 will become 0:0:1, label3 becomes 0:0:2, label4 becomes 0:0:3 , label5 becomes 0:0:4, and label1 will become 0:0:5.. and so forth..Oh dear.. :confused:
But in the mean time, i'll try my best to figure out another way to solve this problem. =)
Re: Plotting Real Time Graph
Quote:
Originally Posted by
catherine0136
@MaximilianMayrhofer :
I used your method, but it states that "Overload resolution failed because no accessible 'ToString' accepts this number of arguments".
I get that too. What a pity, it looked so plausible. Apparently it works for DateTime variables but not for TimeSpans.
Quote:
Code:
Label2.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
1) Label1 will start with 0:0:0
2)
Label2 , Label3, Label4, Label5 will start with (0:0:1) together at the same time. Is it suppose to work in this way?
My mistake, it should be AddSeconds(1) for Label1, AddSeconds(2) for Label2 and so on. Something to do with Reference Types, I believe:rolleyes:.
Quote:
But I thought label 1 will be 0:0:0, label2 will become 0:0:1, label3 becomes 0:0:2, label4 becomes 0:0:3 , label5 becomes 0:0:4, and label1 will become 0:0:5.. and so forth..Oh dear.. :confused:
You're right again. I thought your graph moved from Right to Left, which would mean the new data comes in on the right and the left hand end is the "oldest" data. But I see you have it the other way round.
I think I'll give up trying to discover how the measured voltage gets into your textbox. Clearly it's a state secret. You're not making a nuclear bomb are you? That may be against the forum rules:D.
bye, BB
Re: Plotting Real Time Graph
Quote:
Originally Posted by
boops boops
I get that too. What a pity, it looked so plausible. Apparently it works for DateTime variables but not for TimeSpans.
You can always make a DateTime from a TimeSpan:
vb.net Code:
Dim time As New TimeSpan(3, 24, 47)
Dim [date] As Date = Date.Today + time
MessageBox.Show([date].ToString("HH:mm:ss"))
Just note that that is only going to work for TimeSpans of less than 24 hours, which is why the TimeSpan type doesn't support that type of formatting in the first place.
Re: Plotting Real Time Graph
Hey, I'm not making it a secret, i already tried my best from the beginning till now to explain as clearly as possible how the measured voltage gets into the textbox. =)
I shall explain it again step by step with attached image, but if after the explanation its still isnt clear, then.. .. .. .. .haha.. :)
1) [ See 1st attached image ] As seen on the image, the circuit is connected to a power supply and is connected to the computer via a RS232 cable.
2) Voltage level is extracted and displayed on the "Voltage Level in Volts".The voltage level extracted is a varying voltage.
3) In order to stabilize the moving needle, i added 50 textboxes and the when the voltage is sense, it will be displayed into this 50 textboxes. I average the voltages by 50 to make the moving needle stabilize ( i did not follow your method of enqueue and dequeue as my supervisor ask him to do his method).
This average voltage is displayed in the textbox : Average Voltage
4) The moving needle diagram will follow the voltage shown on the "Average Voltage" as it is more stable.
5) The (Graphical Display) moving waveform will follow the voltage shown the "Voltage level in Volts". If i choose to follow the Average Voltage, the waveform will become a straight line.
Hope to the above is clear enough. Haha.. :)
[attached image removed]
Re: Plotting Real Time Graph
@jmcilhinney,
I think i understand what u mean.
But as for the code:
Code:
MessageBox.Show([date].ToString("HH:mm:ss"))
Hmm.. It will mean that a message box will pop out right? But i believe thats not the way i wanted it to be? But thanks for your suggestion anyway, at least i get to learn something :thumb:
@BB,
The timer works the way i wanted it to be already :D
Thank you!!!
Re: [RESOLVED] Plotting Real Time Graph
Re: [RESOLVED] Plotting Real Time Graph
Quote:
Originally Posted by
catherine0136
vb.net Code:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Call OpenPORT1()
'stuff...
TextBoxVoltage.Text = Math.Round(Voltage232Index_Dec / 100, 2)
'more stuff...
Thanks, that's heart of what I wanted to know. It's nice to see your lab setup too. Now it's clear how the value is read from the serial port in Timer1.Tick. Maybe you realize that those 50 TextBoxes are actually being used as a queue, so in theory you could tidy up the code by putting the readings straight into VoltsQ. Never mind, if it works..
bye, BB
Re: [RESOLVED] Plotting Real Time Graph
@BB
If possible, i'll try to use the VoltsQ, as it'll be much neater and nicer than the way my supervisor suggestions. :D
Re: [RESOLVED] Plotting Real Time Graph
Hey BB,
Sorry to trouble you again. But i would like you to explain to me regarding the coding shown below, the one regarding the timer that you posted for me. Because i still couldnt understand how to coding works. Especially the coding indicated in (purple).
Once again, sorry to trouble you and thanks for your time. :)
Code:
Private StartTime As DateTime
____________________________________________________
Private Sub Timer4_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer4.Tick
Dim dt As DateTime = DateTime.Now
Dim ts As TimeSpan = dt - StartTime
Label1.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
Label2.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(2) - StartTime
Label3.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(3) - StartTime
Label4.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(4) - StartTime
Label5.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(5) - StartTime
End Sub
End Class
And also for the following:
Code:
(Dim dt As DateTime = DateTime.Now)
It will mean that (Dim dt) as the actual date and time of the very moment shown on our computer itself?
.
Re: [RESOLVED] Plotting Real Time Graph
Re: [RESOLVED] Plotting Real Time Graph
Thanks MaximilianMayrhofer! =)
But i still dont really understanding the following, please forgive me as i may be poor in understanding.
For example:
Code:
Dim dt As DateTime = DateTime.Now
Dim ts As TimeSpan = dt - StartTime
Label1.Text = ts.Hours.ToString & ":" & ts.Minutes.ToString & ":" & CInt(ts.Seconds).ToString
ts = dt.AddSeconds(1) - StartTime
So for example, the time now is 4:01:35PM.
Since dt is (DateTime.Now), which is 4:01:35PM,
and ts is (dt-StartTime), so it will mean [ ts = (4:01:35) - StartTime ] correct?
But the StartTime, as in the beginning, 00:00:00 ?
Then for, ts = dt.AddSeconds(1) - StartTime, it will be :
>> ts = 4:01:35.AddSeconds(1) - 00:00:00
which will be:= 4:01:36 - 00:00:00
The above doesnt make sense to me, so I believe my concept towards the above is wrong, therefore i would appreciate if someone could explain to me how it works. :)
Apologies if the above is unclear. Because i cant really understand how the above subtraction will allow my timer to start from 00:00:00 , 00:00:01, 00:00:02, so on and so forth.. :confused:
Thanks in advance for the help!
.
Re: [RESOLVED] Plotting Real Time Graph
Quote:
Originally Posted by
catherine0136
But the StartTime, as in the beginning, 00:00:00 ?
If I remember correctly, there was a point earlier in the program where you had:
Code:
StartTime = DateTime.Now
So StartTime contains a snapshot of whatever the system time was at that particular moment. (Hint: if you don't know about using BreakPoints yet, it's a good time to learn it.)
DateTimes and TimeSpans are confusing because they are not like ordinary numbers. If you subtract two Integers you get another Integer as you'd expect:
Code:
Dim Lots As Integer = 1000
Dim NotSoMuch As Integer = Lots - 250
TextBox1.Text = NotSoMuch.ToString
and TextBox1 will obligingly show 750. It's exactly like you learned it in algebra. But if you try to subtract two DateTimes, you don't get another DateTime but a TimeSpan instead. You are allowed to use a minus sign for two DateTimes but it has a different meaning to the minus sign used for arithmetic. It's just the way people at Microsoft designed it. And you can't write:
Code:
Dim dt As DateTime = DateTime.Now
dt = dt + 5
Instead you have to use AddSeconds or SubtractSeconds. What is more dt.AddSeconds(5) doesn't change the value of dt the way + does with integers. Instead it produces a new DateTime with the required value.
Things like DateTime and TimeSpan are called Reference Types, as opposed to Value Types (like Integers). A String is another example of a reference type, and similarly it has rules of its own for "adding" strings together. You'll get used to them, I hope:).
BB
Re: [RESOLVED] Plotting Real Time Graph
@ BB,
Arh, i understand what you meant already!! :D
Thanks! =)