to many speed / to many deviations on time everything
-
2012年4月14日 12:47
Hello,
For my thesis (last year high school now), I build a laser projector. I am building a program in VB2010 what sends constant data (coordinates) to the laser projector. It’s important that the moments of data sending ore correctly. The program simulates the pictures who the laser projector must send in a picture box. The pictures can also make some effects like zoom-in, zoom-out, scroll and x, y and z rotations.
The problem is now that the program works very slow if the program must make all the calculations of the effects, must draw many lines between the coordinates in the picturebox for the simulation and send data to the laser projector. All these things are based on different timers. How more I ask from the PC (complicated pictures with many coordinates, many effects at the same time) how slower he works.
Now, the graphics in the picturebox are half-drawn and the PC sends the coordinates to slow to the laser projector. Mainly the time between the data transfer of different pictures is to slow. Now, I send always buffers who describes al whole picture to the laser projector. I use a serial port (virtual COM port) at a speed of 256000bps for data transfer.
How can I make the speed of the timers higher whit a greater tolerance? It must be the first priority from the PC that the coordinates to send, are at the right time.
I know just a little bit of computers. I know only how to program in VB after years of self-learning.
Program: (Forum1 calculate the graphics, form2 send the data)
Calculations for effects (called from a timer)
Private Sub teken_afbeelding(ByVal tekening_nummer As Integer, ByVal schaal As Integer, ByVal H_verplaatsing As Integer, ByVal V_verplaatsing As Integer, ByVal X_hoek As Integer, ByVal Y_hoek As Integer, ByVal Z_hoek As Integer, ByVal blanking As Integer)
Dim X_buff, Y_buff, X_buff_2, Y_buff_2 As Integer
Dim penseel As New System.Drawing.Pen(System.Drawing.Color.FromArgb(Rood_data(color_co(tekening_nummer, 1) - 1), groen_data(color_co(tekening_nummer, 1) - 1), blauw_data(color_co(tekening_nummer, 1) - 1)))
Dim buffer_teller As Integer
aantal_co_doorgeefluik = 0
PictureBox1.CreateGraphics.Clear(Color.Black)
For teller As Integer = 0 To aantal_co(tekening_nummer) - 1
If teller - blanking >= 0 Then
penseel.Color = System.Drawing.Color.FromArgb(Rood_data(color_co(tekening_nummer, teller)), groen_data(color_co(tekening_nummer, teller)), blauw_data(color_co(tekening_nummer, teller)))
Else
penseel.Color = System.Drawing.Color.FromArgb(0, 0, 0)
End If
X_buff = (((((X_co(tekening_nummer, teller) - 2048) * Math.Cos(Z_hoek * 0.0246) - (Y_co(tekening_nummer, teller) - 2048) * Math.Sin(Z_hoek * 0.0246)) * Math.Cos(Y_hoek * 0.0246)) * (schaal / 100)) + H_verplaatsing) / (4096 / PictureBox1.Width) + PictureBox1.Width / 2
Y_buff = (((((X_co(tekening_nummer, teller) - 2048) * Math.Sin(Z_hoek * 0.0246) + (Y_co(tekening_nummer, teller) - 2048) * Math.Cos(Z_hoek * 0.0246)) * Math.Cos(X_hoek * 0.0246)) * (schaal / 100)) + V_verplaatsing) / (4096 / PictureBox1.Height) + PictureBox1.Height / 2
If X_buff >= 0 And X_buff < PictureBox1.Width And Y_buff >= 0 And Y_buff < PictureBox1.Height Then
master_buffer(buffer_teller) = CByte(255 - X_buff * (256 / PictureBox1.Width))
master_buffer(buffer_teller + 1) = CByte(255 - Y_buff * (256 / PictureBox1.Height))
master_buffer(buffer_teller + 2) = 0
If teller - blanking >= 0 Then
master_buffer(buffer_teller + 3) = color_co(tekening_nummer, teller)
Else
master_buffer(buffer_teller + 3) = 0
End If
aantal_co_doorgeefluik = aantal_co_doorgeefluik + 1
End If
buffer_teller = buffer_teller + 4
If aantal_co(tekening_nummer) - 1 <> teller Then
X_buff_2 = (((((X_co(tekening_nummer, teller + 1) - 2048) * Math.Cos(Z_hoek * 0.0246) - (Y_co(tekening_nummer, teller + 1) - 2048) * Math.Sin(Z_hoek * 0.0246)) * Math.Cos(Y_hoek * 0.0246)) * (schaal / 100)) + H_verplaatsing) / (4096 / PictureBox1.Width) + PictureBox1.Width / 2
Y_buff_2 = (((((X_co(tekening_nummer, teller + 1) - 2048) * Math.Sin(Z_hoek * 0.0246) + (Y_co(tekening_nummer, teller + 1) - 2048) * Math.Cos(Z_hoek * 0.0246)) * Math.Cos(X_hoek * 0.0246)) * (schaal / 100)) + V_verplaatsing) / (4096 / PictureBox1.Height) + PictureBox1.Height / 2
End If
PictureBox1.CreateGraphics.DrawLine(penseel, X_buff, Y_buff, X_buff_2, Y_buff_2)
Next
End Sub
Form2:
Public Class Form2
Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Dim buffer() As Byte = {0, 0, 0, 0}
SerialPort1.Write(buffer, 0, 4)
SerialPort1.Close()
End Sub
Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Timer1.Enabled = True
SerialPort1.Open()
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim buffer(Form1.aantal_co_doorgeefluik * 4 + 4) As Byte
For teller2 As Integer = 0 To (Form1.aantal_co_doorgeefluik * 4) Step 4
buffer(teller2) = Form1.master_buffer(teller2)
buffer(teller2 + 1) = Form1.master_buffer(teller2 + 1)
buffer(teller2 + 2) = 0
buffer(teller2 + 3) = Form1.master_buffer(teller2 + 3)
Next
Try
SerialPort1.Write(buffer, 0, Form1.aantal_co_doorgeefluik * 4)
Catch
Timer1.Enabled = False
End Try
If Form1.projectie_teller >= Form1.aantal_co(Form1.loop_effect_nummer) Then
Form1.projectie_teller = 0
End If
End Sub
End Class
Thank you for helping,
Ruben Hollevoet
全部回复
-
2012年4月16日 7:26版主
Hi Ruben,
We will try to involve some senior engineers in this case.
Thanks,
Shanks Zen
MSDN Community Support | Feedback to us
-
2012年4月16日 14:18
I can't really help - but I'm curious, and I will try to give some hints:
- A VB application is running in user mode. High system load can always cause delays. Possiby, for highest reliability, you need to write a driver. But for now...:
- A Winforms timer (Timer1) has the lowest precision. Alternative: System.Timers.Timer. If that's not enough, start a new Thread and synchronize execution to Stopwatch.GetTimeStamp. You can increase the thread priority for this purpose to Highest.
- The code is not compilable as many declarations are missing.
- I've accustomed myself to using English identifiers only, in case I'll have to discuss something in an international context. As an ambitious student, your future work will probably also be found there.
- For painting, use the Graphics object you receive in the paint event or in OnPaint (parameter e.Graphics). A different approach is drawing on a Bitmap instead and display that one.
- Dispose disposable objects, like Pens. See the Using statement.
- Use picturebox1.clientsize.width instead of picturebox1.width (same for height). A picturebox might have a border.
- Switch Option Strict On (if you didn't already)
- If possible, avoid very long lines. Split them. For example, the first line can be:
Dim index As Integer = color_co(tekening_nummer, 1) - 1 Dim color = System.Drawing.Color.FromArgb(Rood_data(index), groen_data(index), blauw_data(index)) Using penseel As New System.Drawing.Pen(Color) End Using- Put equal calculations into a parameterized function.
- Replace And by AndAlso where applicable.
- Precalculate unchanging values outside the loop. For example, Math.Cos(Z_hoek * 0.0246) can be calculated once before the loop.
- Use constants wherever possible.
Armin
- 已编辑 Armin Zingler 2012年4月16日 14:21 item added
-
2012年4月16日 14:42
As the X and Y values are function values of your scientific calculation, I suggest calculating them only once per "teller" (whatever it is). Currently you calculate them twice, one time as the start of the line, and one time as the end of the line. If you put them into an array of points, you can call Graphics.DrawLines.
I don't know what exactly your code is doing, but after redesign, this is an optimized version. Of course, keep your own code also :-) because I'm not sure if it's free of faults.
Private Sub teken_afbeelding( _ ByVal g As Graphics, ByVal Rect As Rectangle, _ ByVal tekening_nummer As Integer, ByVal schaal As Integer, _ ByVal H_verplaatsing As Integer, ByVal V_verplaatsing As Integer, _ ByVal X_hoek As Integer, ByVal Y_hoek As Integer, ByVal Z_hoek As Integer, _ ByVal blanking As Integer) Dim X_buff, Y_buff As Integer Dim index As Integer = color_co(tekening_nummer, 1) - 1 Dim color = System.Drawing.Color.FromArgb(Rood_data(index), groen_data(index), blauw_data(index)) Using penseel As New System.Drawing.Pen(color) Const Scale As Double = 0.0246 Dim buffer_teller As Integer aantal_co_doorgeefluik = 0 g.Clear(color.Black) Dim Cos_Y_hoek_Scaled = Math.Cos(Y_hoek * Scale) Dim Cos_X_hoek_Scaled = Math.Cos(X_hoek * Scale) Dim Cos_Z_hoek_Scaled = Math.Cos(Z_hoek * Scale) Dim Sin_Z_hoek_Scaled = Math.Sin(Z_hoek * Scale) Dim schaal_Scaled = schaal / 100 Dim Inv_Pic_Width = 4096 / Rect.Width Dim Inv_Pic_Height = 4096 / Rect.Height Dim Inv2_Rect_Width = 256 / Rect.Width Dim Inv2_Rect_Height = 256 / Rect.Height Dim Half_Pic_width = Rect.Width / 2 Dim Half_Pic_Height = Rect.Height / 2 Dim points(aantal_co(tekening_nummer) - 1) As Point For teller As Integer = 0 To aantal_co(tekening_nummer) - 1 If teller - blanking >= 0 Then index = color_co(tekening_nummer, teller) penseel.Color = System.Drawing.Color.FromArgb(Rood_data(index), groen_data(index), blauw_data(index)) Else penseel.Color = System.Drawing.Color.FromArgb(0, 0, 0) End If X_buff = CInt((((((X_co(tekening_nummer, teller) - 2048) * Cos_Z_hoek_Scaled - (Y_co(tekening_nummer, teller) - 2048) * Sin_Z_hoek_Scaled) * Cos_Y_hoek_Scaled) * schaal_Scaled) + H_verplaatsing) / Inv_Pic_Width + Half_Pic_width) Y_buff = CInt((((((X_co(tekening_nummer, teller) - 2048) * Sin_Z_hoek_Scaled + (Y_co(tekening_nummer, teller) - 2048) * Cos_Z_hoek_Scaled) * Cos_X_hoek_Scaled) * schaal_Scaled) + V_verplaatsing) / Inv_Pic_Height + Half_Pic_Height) points(teller).X = X_buff points(teller).Y = Y_buff If X_buff >= 0 AndAlso X_buff < Rect.Width AndAlso Y_buff >= 0 AndAlso Y_buff < Rect.Height Then master_buffer(buffer_teller) = CByte(255 - X_buff * Inv2_Rect_Width) master_buffer(buffer_teller + 1) = CByte(255 - Y_buff * Inv2_Rect_Height) master_buffer(buffer_teller + 2) = 0 If teller - blanking >= 0 Then master_buffer(buffer_teller + 3) = color_co(tekening_nummer, teller) Else master_buffer(buffer_teller + 3) = 0 End If aantal_co_doorgeefluik = aantal_co_doorgeefluik + 1 End If buffer_teller = buffer_teller + 4 Next g.DrawLines(penseel, points) End Using End SubYou pass an additional graphics object and a rectangle, which can be the ClientRectangle property of the control.
- 已编辑 Armin Zingler 2012年4月16日 14:53
- 已建议为答案 Heslacher 2012年4月16日 15:58
- 已标记为答案 Shanks ZenMicrosoft Contingent Staff, Moderator 2012年4月25日 9:35
-
2012年4月17日 20:21
Thanks a lot for al that information!
You told me a lot of things I didn't know about Visual basic until now.
Yesterday I was busy to remake my software and put in al the new things you told my. I hope I can finish my work now and that it works a lot faster.
Now, I'm busy to find more information about the new way of timing.

