GUI Based Control Project

 

  The use of the internet network is growing in our days. Applications like messengers and chatting are well known. Receiving and transmitting images are also possible even if the transmission is not really perfect. In fact webcams are really cheap CCD’s and offer a satisfactory image. Another direction is interfacing the cellular phones with internet. In our days it is a fact that you can read or write emails using cell phones. SMS message are as well present in our life. So, remotely control is possible. Attaching some electronic devices to the computer like an 8255 board, will offer the possibility to command some power devices; for example, turning on the air conditioning, the heat are possible application. For a security operator, for example, one useful application could be to receive images from outside surveillance cameras during his tour in the building. In some cases it might be desired to have the possibility to rotate and orient the cameras, zoom in and out, using his pocket PC. Such applications like receiving images on a PDA have been developed already. So, such application may be of particular interest. For the project I plan to rotate MEI Pan-Tilt Head with camera. An estimation of time needed for this project is shown below

Time Schedule

Stage Description Estimated Time
Develop VB GUI for client/server communication
2 hours
Write VB code for client server communication
2 hours
Write VB code to rotate the PTH
1.5 hours
Debug and test the programs
0 to 3 hours





2-DOF motorized pan-tilt head and video camera manufactured by Innovision.


  Utilizing a simple Visual Basic code, (click here for a brief VB tutorial) the client is able remotely control the boom camera and to receive images from it. To realize this I use a couple of components offered by Innovision - the pan tilt head manufacturer - and by Microsoft. The to ActivEx allow us to use the specific functions already defined to rotate the PTH an to send informations over the internet.

 The server application

 

 

To rotate the PTH a simple client server application was developed. A picture representing the GUI for this part is shown below



VB GUI for PTH.

  The Visual Basic Code is shown below:

Option Explicit
Dim ax As Integer

Private Sub Acceleration_GotFocus()
Acceleration.SelStart = 10000
Acceleration.SelLength = 250
End Sub

Private Sub ActualTimer_Timer()
Dim p As Double ' see 'Option Explicit'
CheckError (get_position(ax, p))
Actual.Caption = Format$(p)
End Sub

Private Sub Axis_GotFocus()
Axis.SelStart = 0
Axis.SelLength = 250
End

Private Sub Axis_LostFocus()
DisableRepeat
ax = val(Axis.Text)
End Sub

Private Sub CheckError(e%)
' This function is called after every call into
' the library. It is responsible for checking
' the returned error code.
Dim f%, s$ ' necessary because of Option Explicit
If (e% <> DSP_OK) Then
s$ = Space$(MAX_ERROR_LEN)
f% = error_msg(e%, s$)
f% = MsgBox(s$, 1, "DSP Error Encountered")
If (f% = 2) Then End
End If
End Sub

Private Sub DisableRepeat()
RepeatTimer.Interval = 0
Repeat.Caption = "Repeat"
End Sub

Private Sub EnableRepeat()
RepeatTimer.Interval = 10
Repeat.Caption = "End Repeat"
End Sub

Private Sub btnExit_Click()
End
End Sub

Private Sub Command1_Click()
Dim ret
ret = start_move(1, 10000#, 2000#, 500#)
End Sub

Private Sub Final1_GotFocus()
Final1.SelStart = 0
Final1.SelLength = 250
End Sub

Private Sub Final2_GotFocus()
Final2.SelStart = 0
Final2.SelLength = 250
End Sub

Private Sub Form_Load()
ax = 0
CheckError (do_dsp()) ' initialize the controller.
'the internet communication commands
'cmdSend.Enabled = False
' Set up local port and wait for connection
tcpServer.LocalPort = 5000
Call tcpServer.Listen
End Sub

Private Sub Go_Click()
If (motion_done(ax)) Then MotionGo
End Sub

Private Sub MotionGo()
Dim p#, q#, v#, a#, position#, d1#, d2#, final#
v = val(Velocity.Text)
a = val(Acceleration.Text)
p = val(Final1.Text)
q = val(Final2.Text)
CheckError (get_position(ax, position))
d1 = Abs(p - position)
d2 = Abs(q - position)
If (d1 > d2) Then
final = p
Else
final = q
End If
If motion_done(ax) Then cmdSend
CheckError (start_move(ax, final, v, a))
End Sub

Private Sub Repeat_Click()
If (RepeatTimer.Interval = 0) Then
' Timer was disabled.
EnableRepeat
Else
DisableRepeat
End If
End Sub

Private Sub RepeatTimer_Timer()
If (motion_done(ax)) Then
MotionGo
End If
End Sub

Private Sub Velocity_GotFocus()
Velocity.SelStart = 0
Velocity.SelLength = 250
End Sub


The program works and allow you to remotely move the PTH. The component I used here is called pcdsp and was provided by Innovision.

Another program for image grabbing was developed using Matrox ActiveMIL software. This program allows image grabbing using a MATROX METEOR II board. The program use some MATROX components. The GUI for this program is shown below



Image grabbing application

  The Visual Basic code for this application is shown below

Private Sub btnDisplayBuffer1_Click()
ImageBuffer1.Copy ImageBuffer, imAllBands
Digitizer.Free
Digitizer.Allocate
Digitizer.Image = ImageBuffer1
'ImageBuffer1.Put Imagine, imPlanar, imAllBands, 0, 0, ImageBuffer1.SizeX, ImageBuffer1.SizeY
'ImageBuffer1.Save ("c:\rares\MEM800_project\raresDoubleBuffering\image.jpg")
End Sub

Private Sub btnExit_Click()
End
End Sub

Private Sub btnGrab_Click()
Digitizer.Image = ImageBuffer
Digitizer.GrabContinuous
Timer1.Enabled = True
'ImageBuffer.Save ("c:\rares\MEM800_project\raresDoubleBuffering\image.jpg")
End Sub

Private Sub Form_Load()
pathname = "c:\rares\MEM800_project\raresDoubleBuffering\image.jpg"
Open pathname For Output As #1
Digitizer.GrabContinuous
ImageBuffer1.SizeX = ImageBuffer.SizeX
ImageBuffer1.SizeY = ImageBuffer.SizeY
ImageBuffer1.Allocate
End Sub

Private Sub Timer1_Timer()
txtDisplay.Text = Str(txtDisplay.Text) + 1
ImageBuffer.Save ("c:\rares\MEM800_project\raresDoubleBuffering\image.jpg")
End Sub

This code will save periodically an image (as a bitmap file) on the server's hard drive. A VB script code will be developed on a webpage to display this image using Savant.

 Putting all things together

  As you could see, I was developed two programs: one to rotate the PTH remotely and one to use Matrox board and to periodically save the image as a .bmp file. The next step was to put everythin together. So, the new program suppose to allow PTH control as well as display and save the image

In the figure above, there are the parameters of the PTH motion. The final position for the pan (Axis 0) and for the tilt (Axis 1) will be set remotely, by the "Client". There are also three timers. Two of them are used for the part of the program that takes care of PTH. The third one takes will update the image periodically. Every 250ms, the image will be saved in an .bmp file on the server hard drive. Using Savant, it is possible to view this image on a webpage. To grab and display the image, a Matrox Meteor II was used. As software I was using ActiveMIL library. On the form it can be seen the ActiveMIL objects, the digitize, two image buffers, a display and the system. These are the basic objects that need to be used to grab an image. Once I got the image, I was using the command

ImageBuffer1.Save ("c:\savant\root\image2.jpg")

As it can be seen, the name of the image is image2.jpg. This image has to be saved in the c:\savant\root\.

The complete code of server program can be seen below

Option Explicit

Dim ax As Integer

Private Sub Acceleration_GotFocus()

Acceleration.SelStart = 10000
Acceleration.SelLength = 250

End Sub

Private Sub ActualTimer_Timer()

Dim p As Double ' see 'Option Explicit'
CheckError (get_position(ax, p))
Actual.Caption = Format$(p)

End Sub

Private Sub Axis_GotFocus()

Axis.SelStart = 0
Axis.SelLength = 250

End Sub

Private Sub Axis_LostFocus()

DisableRepeat

ax = val(Axis.Text)

End Sub

Private Sub CheckError(e%)

' This function is called after every call into
' the library. It is responsible for checking
' the returned error code.

Dim f%, s$ ' necessary because of Option Explicit

If (e% <> DSP_OK) Then
s$ = Space$(MAX_ERROR_LEN)
f% = error_msg(e%, s$)

f% = MsgBox(s$, 1, "DSP Error Encountered")

If (f% = 2) Then End
End If

End Sub

Private Sub DisableRepeat()

RepeatTimer.Interval = 0
Repeat.Caption = "Repeat"

End Sub

Private Sub EnableRepeat()

RepeatTimer.Interval = 10
Repeat.Caption = "End Repeat"

End Sub

Private Sub btnExit_Click()
End
End Sub

Private Sub Command1_Click()
Dim ret
ret = start_move(1, 10000#, 2000#, 500#)
End Sub

Private Sub Final1_GotFocus()

Final1.SelStart = 0
Final1.SelLength = 250

End Sub

Private Sub Final2_GotFocus()

Final2.SelStart = 0
Final2.SelLength = 250

End Sub

Private Sub Form_Load()
Dim pathname As String
pathname = "C:\savant\Root\image2.jpg" 'opening the .bmp file
Open pathname For Output As #1

Digitizer.GrabContinuous ' set the frame grabber to grabb continuously
ImageBuffer1.SizeX = ImageBuffer.SizeX
ImageBuffer1.SizeY = ImageBuffer.SizeY
ImageBuffer1.Allocate
ax = 0
CheckError (do_dsp()) ' initialize the controller.

'the internet communication commands
'cmdSend.Enabled = False
' Set up local port and wait for connection
tcpServer.LocalPort = 5000
Call tcpServer.Listen

End Sub

Private Sub Frame1_DragDrop(source As Control, x As Single, y As Single)

Private Sub Go_Click()
Timer1.Enabled = True

If (motion_done(ax)) Then MotionGo

End Sub

Private Sub MotionGo()

Dim p#, q#, v#, a#, position#, d1#, d2#, final#
v = val(Velocity.Text)
a = val(Acceleration.Text)
p = val(Final1.Text)
q = val(Final2.Text)

CheckError (get_position(ax, position))
d1 = Abs(p - position)
d2 = Abs(q - position)
If (d1 > d2) Then
final = p
Else
final = q
End If
If motion_done(ax) Then cmdSend
CheckError (start_move(ax, final, v, a))

End Sub

Private Sub mnuAbout_Click()
frmAbout.Show
End Sub

Private Sub mnuExit_Click()
End
End Sub

Private Sub Repeat_Click()

If (RepeatTimer.Interval = 0) Then
' Timer was disabled.
EnableRepeat
Else
DisableRepeat
End If

End Sub

Private Sub RepeatTimer_Timer()

If (motion_done(ax)) Then
MotionGo
End If

End Sub

Private Sub Timer1_Timer()

txtDisplay.Text = Str(txtDisplay.Text) + 1
ImageBuffer1.Copy ImageBuffer, imAllBands
Digitizer.Free
Digitizer.Allocate
ImageBuffer1.Save ("C:\savant\Root\image2.jpg")
Digitizer.GrabContinuous

End Sub

Private Sub Velocity_GotFocus()

Velocity.SelStart = 0
Velocity.SelLength = 250

End Sub

Private Sub Form_Terminate()

Call tcpServer.Close

End Sub

Private Sub tcpServer_Close()

cmdSend.Enabled = False
Call tcpServer.Close ' client closed, server should too
txtOutput.Text = txtOutput.Text & "Client closed connection." & vbCrLf & vbCrLf
txtOutput.SelStart = Len(txtOutput.Text)
Call tcpServer.Listen ' listen for next connection

End Sub

Private Sub tcpServer_DataArrival(ByVal bytesTotal As Long)

Dim message As String
Dim MyWord1 As String
Dim MyWord2 As String
Dim WordPosition1 As Integer
Dim WordPosition2 As Integer
Dim message1 As String
Dim message2 As String
Dim message3 As String
' selecting the strings
MyWord1 = ","
MyWord2 = "."
Call tcpServer.GetData(message) ' get data from client
txtOutput.Text = txtOutput.Text & message & vbCrLf & vbCrLf

' here comes the code for extracting pan and tilt information from "message"
WordPosition1 = InStr(1, message, MyWord1, vbTextCompare)
WordPosition2 = InStr(1, message, MyWord2, vbTextCompare)
'MsgBox "the string is " & message, vbOKOnly, "String"
'MsgBox "the element , is" & WordPosition1, vbOKOnly, "comma"
'MsgBox "the element . is" & WordPos2, vbOKOnly, "dot"

message1 = Left(message, WordPosition1 - 1)
message2 = Mid(message, WordPosition1 + 1, WordPosition2 - WordPosition1)
message3 = Right(message, Len(message) - WordPosition2)

'MsgBox "the string is " & message, vbOKOnly, "String"
Final1.Text = Str(message1)
'Final2.Text = Str(message2)

If message3 = "Go" Then
CheckError (start_r_move(0, Str(message1), Velocity.Text, Acceleration.Text))
CheckError (start_r_move(1, Str(message2), Velocity.Text, Acceleration.Text))
End If

txtOutput.SelStart = Len(txtOutput.Text)
End Sub

Private Sub tcpServer_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)

Dim result As Integer
result = MsgBox(source & ": " & Description, vbOKOnly, "TCP/IP Error")
End

End Sub

Private Sub tcpServer_ConnectionRequest(ByVal requestID As Long)

' Ensure that tcpServer is closed
' before accepting a new connection
If tcpServer.state <> sckClosed Then
Call tcpServer.Close
End If
'cmdSend.Enabled = True
Call tcpServer.Accept(requestID) ' accept connection
' Display following message on server application:
txtOutput.Text = "The connection from IP Address: " & _tcpServer.RemoteHostIP & " is successful" & vbCrLf & _
"Port #: " & tcpServer.RemotePort & vbCrLf & vbCrLf

End Sub

Private Sub cmdSend()

txtOutput.SelStart = Len(txtOutput.Text)

End Sub

Dowload the code from here rather than copy and paste.

 The client application

 

  The client application is the program that will be used to control remotely the PTH. Basically, the number of counts that the motors needs to rotate with will be prescribed. After that, the human operator has to type Go in the send window. Then, when the button Send is hit, a string is send to the server. The string's structure can be seen below

pan_displacement,tilt_displacement.Go

The server program will receive this string and will subtract the pan displacement, the tilt displacement as well as third substring. If the third substring in not "Go", the PTH will not move. If the string is "Go" the PTH will move relatively to the previous position. The application is shown below

The client code is shown below:

' FILE: tcpClient
' DATE: 06/01/00 17:45
' AUTH: R Stanciu after a code from Dr. Oh
' DESC: A Simple TCP Client
' REFS: Prof Oh notes
Option Explicit

Private Sub Form_Load()

cmdSend.Enabled = False
' Set up local port and wait for connection
tcpClient.RemoteHost = InputBox("Enter the remote host IP Address", "IP Address", "129.25.9.131")
If tcpClient.RemoteHost = "" Then
tcpClient.RemoteHost = "129.25.9.131"
End If
tcpClient.RemotePort = 5000 ' server port
Call tcpClient.Connect ' connect to RemoteHost address

End Sub

Private Sub Form_Terminate()

Call tcpClient.Close
End Sub
Private Sub cmdSend_Click()
' Send data to server
Call tcpClient.SendData(txtPan.Text & "," & txtTilt.Text & "." & txtSend.Text)
'Call tcpClient.SendData(txtPan.Text & "," & txtTilt.Text & ",")
txtOutput.Text = txtOutput.Text & _
"Client >>> " & txtSend.Text & vbCrLf & vbCrLf
txtOutput.SelStart = Len(txtOutput.Text)
txtSend.Text = ""

End Sub

Private Sub mnuAbout_Click()

frmAbout.Show

End Sub

Private Sub mnuExit_Click()

End

End Sub

Private Sub tcpClient_Close()

cmdSend.Enabled = False
Call tcpClient.Close ' server closed, client should too
txtOutput.Text = txtOutput.Text & "Server closed connection." & vbCrLf
txtOutput.SelStart = Len(txtOutput.Text)

End Sub

Private Sub tcpClient_Connect()

' When connection occurs, display a message
cmdSend.Enabled = True
txtOutput.Text = "Connected to IP address: " & _
tcpClient.RemoteHostIP & vbCrLf & vbCrLf

End Sub

Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long)

Dim message As String
Call tcpClient.GetData(message) ' get data from server
txtOutput.Text = txtOutput.Text & message & vbCrLf & vbCrLf
txtOutput.SelStart = Len(txtOutput.Text)

End Sub

Private Sub tcpClient_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, _
ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
' If the client fails to connect to server, then this code executes
Dim result As Integer
result = MsgBox(Source & ": " & Description & vbCrLf & "Doh! Can't connect to server!", _
vbOKOnly, "TCP/IP Error")
' Source variable is the control (winsock in this case) causing the error
' Description variable cites the error message
' vbOKOnly is the control button
' TCP/IP Error is the MsgBox caption
End

End Sub



Dowload the code from here rather than copy and paste. Click on the image below to see the images from our lab.

Home