Controlling Devices over the Internet

Keywords: Internet control, remote monitoring, remote control, TCP/IP, Winsock, Visual Basic, VB, relay, digital-to-analog, DAC, DC motor, stepper, keypad

In the figure above, the Internet allows one PC (called a client) to control hardware (like motors and relays) installed on another PC (called a server). In other words, you can remotely control or monitor devices. Since the Internet is just a medium for computers to "talk" to each other, it enables you to perform applications like automating your home (e.g. turn on/off air-conditioning) and data acquisition (e.g. measure temperatures). This tutorial shows you how to get started.

The photos depict what will be used for on/off control of an LED over the Internet. An 8255 PC interface card will be installed in the Server PC's ISA bus. The card is interfaced to eight LEDs (a 9V battery is just shown for scale) via a 34-pin cable and Terminal Expansion Board (TEB). The Client PC then connects to the server via the Internet. Through the client, you can turn on/off the LEDs. The LEDs could be replaced with motors, relays or other types of peripherals you'd like to control or monitor. The 8255 PC interface card could be replaced with other interface circuitry like a parallel port.


Motivation and Audience

Visual Basic (VB) is a powerful, high-level Windows-based programming language with a quick learning curve. High-level means that the programmer can avoid tedious coding, one example being, Internet-related functions; Winsock is Microsoft's high-level component that allows a VB programmer to quickly develop Internet-based programs like Chat, FTP and Browsers. This tutorial will show how to (1) write a chat-style client/server program and (2) add the code necessary to control server-installed hardware (LEDs in this case) over the Internet.

Readers of this tutorial would be motivated by ideas like:

The tutorial's scope is focused mainly on Visual Basic (VB) and Winsock programming. As such, the reader is assumed to:
  • Have some VB programming experience
  • Have a PC-interfaced hardware device (like LEDs, motor, DAC and relays) to be controlled.
  • The above PC is connected to the Internet and has an IP address (static or dynamic)
  • The hardware device can be controlled by VB.

The following links are Boondog tutorials that may be useful if the above is overly assumed:

Simple LEDs are controlled just to illustrate the programming concepts. Other devices like relays, DC and stepper motors and keypads can also be controlled over the Internet. Links to these are given below, in the Final Words section. The rest of the tutorial is presented as follows:

Writing A Simple Client/Server Internet Chat Program

A client PC requests a server PC to perform actions. You can write a simple chat program in VB to exchange text messages between a client and server. You might be familiar with such programs as they are often used in on-line chat rooms. You will write two programs (one running on the client PC, the other on the server PC) resulting in a teletype-like application; you and a friend can type messages to each other over the Internet. Understanding how these two programs work will help you develop programs to control hardware devices over the Internet.

The Client Program

This is one of two programs you'll write for a Chat application. It is called tcpClientDemo.exe and uses Microsoft's Winsock component. This example uses Visual Basic Version 6.0, but probably works with 5.0 as well. Running tcpClientDemo.exe will prompt you to enter an IP address. If you have a corresponding server program (discussed later), you'll be able to chat, by typing messages in the txtSend box and hitting the cmdSend button. Messages from the server will be displayed in the txtOutput box.

Client GUI Programming Step

Below is a screen shot of the VB GUI (Graphical User Interface) along with the component variable names used. The Form is saved as frmTCPClient.frm and the Project is saved as tcpClientDemo.vbp

The Winsock component shown in the lower left corner (named tcpClient isn't part of the standard VB toolbox. Rather it is added using the following steps:

Click Project then Components and select Microsoft Winsock Control 6.0. You should be seeing the following screen shot

Clicking OK will then export the Winsock Component to the VB toolbox as shown below. You can click and drag the component into your VB form like any other VB component.

The components and relevant properties are highlighted in the following table:

TABLE 1: tcpClientDemo GUI Properties
ComponentPropertyValue
FormNamefrmTCPClient
BackColorYellow
CaptionSimple TCP Client
ButtonNamecmdSend
CaptionSend Text
Text BoxNametxtSend
Text BoxNametxtOutput
WinsockNametcpClient
Protocol0 - sckTCPProtocol

Client Code Programming Step

Below is the code for tcpClientDemo.exe. The associated code namely: frmTCPClient.frm, tcpClientDemo.vbp and tcpClientDemo.vbw can be downloaded if you wish.


VB 6.0 Code for frmTCPClient.frm
Note: download frmTCPClient.frm rather than cutting and pasting from below.

   ' FILE: tcpClientDemo.frm
   ' DATE: 01/15/00 12:45
   ' AUTH: P.Oh Boondog Automation
   ' DESC: A Simple TCP Client
   ' REFS: Deitel p. 829 Fig. 19.12
   Option Explicit
	
   Private Sub cmdSend_Click()
      ' Send data to server
      Call tcpClient.SendData("Client >>> " & txtSend.Text)
      txtOutput.Text = txtOutput.Text & _
          "Client >>> " & txtSend.Text & vbCrLf & vbCrLf
      txtOutput.SelStart = Len(txtOutput.Text)
      txtSend.Text = ""
   End Sub

   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", "localhost")
    
      If tcpClient.RemoteHost = "" Then
          tcpClient.RemoteHost = "localhost"
      End If
    
      tcpClient.RemotePort = 5000 ' server port
      Call tcpClient.Connect ' connect to RemoteHost address
    
   End Sub

   Private Sub Form_Resize()
      On Error Resume Next
      Call cmdSend.Move(ScaleWidth - cmdSend.Width, 0)
      Call txtSend.Move(0, 0, ScaleWidth - cmdSend.Width)
      Call txtOutput.Move(0, txtSend.Height, ScaleWidth, _
        ScaleHeight - txtSend.Height)
   End Sub

   Private Sub Form_Terminate()
      Call tcpClient.Close
   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


Client Code Description

Note: You must execute tcpServerDemo.exe before running tcpClientDemo.exe since it requires the server's IP address. More details are explained in Running the Programs Section. The following explains how the code works.

When tcpClientDemo.exe first executes, Form_Load is launched; an input box prompts the user to enter the server's IP address. By default it uses localhost which will be explained later. Next, tcpClient.RemotePort uses the value 5000 and is called a port number. This number can range from 1024 to 65535 (typically port numbers less than 1024 are reserved for system services). However, the port numbers of the client and server must match. The corresponding server code will also use 5000 as you'll see later. Clicking OK after entering an IP address will attempt a client-server connection by calling tcpClient_Connect() which then enables the Send Text command button.

If the connection succeeds, the user can then type a message in the txtSend text box. Clicking the Send Text, command button, will then execute the procedure cmdSend_Click() which calls tcpClient_SendData.

tcpClient_SendData sends the string Client >>> " plus whatever message you typed in the txtSend text box. It also prints whatever you typed into the txtOutput text box, along with some carriage returns and line feeds (vbCrLf).

Any messages sent from the server are handled by the tcpClient_DataArrival() procedure. GetData is a property of the Winsock control. Recall that you named this control tcpClient in your VB form. As such tcpClient.GetData collects any text messages sent from the server into the string variable message. The string is then printed in the txtOutput text box.

Killing the program will execute the tcpClient_Close() procedure. It greys out the Send Data button, shuts down the client and prints out the message Server closed connection. Form_Terminate also closes the client's Winsock control using a tcpClient.Close call.

tcpClient_Error() handles any errors. A common error might be a mistyped IP address. Form_Resize handles any attempts to resize the GUI.

The Server Program

tcpClientDemo.exe works in conjunction with this code called tcpServerDemo.exe, a server code also using Microsoft's Winsock component. Executing tcpServerDemo.exe on a PC connected to the Internet will listen to connection attempts made by the client.

Server GUI Programming Step

A screen shot and variable names used are shown the following figure. Dragging the Winsock component into your form is the same as previously described in the Client Program.

The components and relevant properties are highlighted in the following table:

TABLE 2: tcpServerDemo GUI Properties
ComponentPropertyValue
FormNamefrmTCPServer
BackColorBlue
CaptionSimple TCP Server
ButtonNamecmdSend
CaptionSend Text
Text BoxNametxtSend
Text BoxNametxtOutput
WinsockNametcpClient
Protocol0 - sckTCPProtocol

Server Code Programming Step

Below is the code for tcpServerDemo.exe. The associated code namely: frmTCPServer.frm, tcpServerDemo.vbp and tcpServerDemo.vbw can be downloaded if you wish.


VB 6.0 Code for frmTCPServer.frm
Note: download frmTCPServer.frm rather than cutting and pasting from below.

  ' FILE: tcpServer
  ' DATE: 01/15/00 12:30
  ' AUTH: P.Oh (Boondog Automation)
  ' DESC: A Simple TCP Server
  ' REFS: Deitel p. 826 Fig. 19.10
  Option Explicit

  Private Sub cmdSend_Click()
    ' Send following text data to the client
    Call tcpServer.SendData("Server >>> " & txtSend.Text)
    ' Repeat text data in server's txtOutput.Text window
    txtOutput.Text = txtOutput.Text & "Server >>>" & txtSend.Text & _
        vbCrLf & vbCrLf
    ' Clear the txtSend.Text window"
    txtSend.Text = ""
    txtOutput.SelStart = Len(txtOutput.Text)
  End Sub

  Private Sub Form_Load()
    cmdSend.Enabled = False
    
    ' Set up local port and wait for connection
    tcpServer.LocalPort = 5000
    Call tcpServer.Listen
  End Sub

  Private Sub Form_Resize()
    On Error Resume Next
    Call cmdSend.Move(ScaleWidth - cmdSend.Width, 0)
    Call txtSend.Move(0, 0, ScaleWidth - cmdSend.Width)
    Call txtOutput.Move(0, txtSend.Height, ScaleWidth, _
        ScaleHeight - txtSend.Height)
  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_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 tcpServer_DataArrival(ByVal bytesTotal As Long)
    Dim message As String
    Call tcpServer.GetData(message) ' get data from client
    txtOutput.Text = txtOutput.Text & message & vbCrLf & vbCrLf
    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


Server Code Description

Form_Load launches when tcpServerDemo.exe is first executed. As mentioned in the Client Program section, tcpServer.LocalPort = 5000 sets up the port number. Your server will sit quietly and wait for clients logging in with the server's IP address and using a 5000 port number.

Messages from the client are handled by tcpServer_DataArrival and are displayed in the txtOutput text box. If someone on the server types a message in the txtSend text box and hits the Send Text command button, then the subroutine cmdSend_Click() is executed. Here, the typed message is appended to Server >>> and is also displayed in the txtOutput text box. Error handling and form resizing are handled in the same way as described in the Client Program.

Running the Client and Server Chat Program

tcpClientDemo.exe and tcpServerDemo.exe work together as a chat program. First, run the server program on a PC connected to the Internet. This can be any kind of Internet connection like by modem, DSL or T1. Once it runs, determine the server's IP address. In Win95, this is easily found by clicking Start - Run from your Desktop and typing winipcfg. You should see a screen like:

where 216.178.66.74 is the server's IP address. Of course your PC will have different numbers separated by three decimal points. If your server PC is running WinNT, then type ipconfig in a DOS prompt for getting the IP address.

On another Internet-connected PC running tcpClientDemo.exe will prompt a pop-up input box where you can type the server's IP address as shown below. Although the address 216.178.67.154 is shown in the figure, you should type the IP address you found using winipcfg.

Once you click OK, you can chat by typing messages and click Send Text on the Server or Client. If you don't have two PC's available, you can run both programs on the same PC. If you do you'll get a screen shot shown below. You'll observe that messages you type are exchanged between client and server.

Turning On/Off an LED over the Internet

The Chat program demoed with tcpClientDemo.exe and tcpServerDemo.exe can be expanded to control devices over the Internet. Here, turning on/off an LED is illustrated as an example in sending commands. It serves as a good example before you attempt turning on/off relays or motors; LED control is the most simple but fundamental concept in enabling devices.

Hardware and LED circuit

The photo above shows the 8255 PC Interface Card installed in the server PC. This card has 24 digital I/O lines (three 8-bit ports).

The photo above features the LED circuit. It is connected to the 8255 with a 34-pin cable tethered to a Terminal Expansion Board (TEB). The LED circuit has eight LEDs which will be turned on/off from the client via the Internet.

Turning on/off LEDs with the 8255 card is rather simple. You just need to set the 8255's control word for output and then issue 8-bit data (in decimal) to turn on/off LEDs. The hyperlink above gives a full tutorial on building your own 8255 card and programming it to turn on/off LEDs and reading switches. Programming the 8255 in Visual Basic requires a DLL (dynamically linked library) to mimic Quick Basic's (DOS) OUT and IN or Turbo C's outportb() and inportb() functions. The hyperlink gives a full tutorial on writing DLL's. The compiled version, 8255.dll can be freely downloaded if you rather not write your own DLL.

The LED Client Program

A screen shot of the LED control program running on the client PC called ledClient.exe is shown above. You can download ledClient.exe or the VB source: frmLEDClient.frm, ledClient.vbp and ledClient.vbw if you wish.

Rather than show the VB code explicitly, view frmLEDClient.frm. It resembles the Client Chat program tcpClientDemo.exe. The key changes made are (1) the Send Text command button is replaced with eight command buttons. Each button represents the decimal number to light up the LEDs in binary (2) the txtSend text box has been removed.

Clicking a button in tcpClientDemo.exe will issue an ASCII string to the server. For example, the subroutine associated with clicking the 6 button is:


    Private Sub cmdSix_Click()
      ' Send six to server
      Call tcpClient.SendData("6")
      txtOutput.Text = txtOutput.Text & _
        "Client clicked 6" & vbCrLf
      txtOutput.SelStart = Len(txtOutput.Text)
   End Sub

As you can see, tcpClient.SendData issues the ASCII character 6. The txtOutput text box prints Client clicked 6 and then a carriage return and linefeed. Subroutines for the other seven command buttons are very similiar.

The LED Server Program

A screen shot of the LED control program running on the server PC called ledServer2_0.exe is shown above. You can download ledServer2_0.exe or the VB source: frmLEDServer2_0.frm, ledServer2_0.vbp and ledServer2_0.vbw if you wish.

The 8255 PC Interface card is installed in the Server PC's ISA bus. The 8255 is a common digital I/O card. If you aren't familiar with it, read the 8255 Tutorial which gives complete information on building your own 8255 Card.

Recall that VB doesn't provide input/output functions like the DOS QBasic's IN and OUT or Turbo C's inportb() and outportb. However using a DLL, one can perform read/write to an address. The complete tutorial on DLL's should be read if you don't know how to implement DLLs for such purposes.

The complete code for frmLEDServer2_0.frm is not listed here, but can be viewed and downloaded. The key points are described as follows.

First, in the form's General Declarations are the lines


   Private Declare Function Out8255 Lib "8255.dll" (ByVal PortAddress As Integer,_
       ByVal PortData As Integer) As Integer
   Private Declare Function In8255 Lib "8255.dll" (ByVal PortAddress As Integer)_
       As Integer

which load the DLL for reading (In8255()) and writing (Out8255()) to addresses in VB.

Form_Load, in addition to setting up the server PC's localhost, also assigns the 8255's base address (608 in this case) and the addresses for Ports A, B, C and Control Word (Cntrl). The 8255 is configured for digital output on all three ports. The LEDs are interfaced on Port A.

The rest of the ledServer2_0.exe looks and operates like tcpServerDemo.exe. The server PC waits for connection requests from the client. Once a connection is established, it awaits for messages from the client. Recall that ledClient.exe described above, you clicked on 6 to light up 6 in binary on the LEDs. tcpServer_DataArrival handles string messages. The string "6", sent by the client, is converted into a numerical value using


   numericValue = Val(messageFromClient)

Next, this numeric value is written to the 8255 using


   Dummy = Out8255(PortA, numericValue)

The net result is that 6 lights up (in binary) the LEDs and status text messages are displayed in the client and server's txtOutput text boxes

mpegLedClientServer.mpg (352KB) is an MPEG showing the client controlling the LEDs. The client and server PC's happen to be in the same room, but they are each connected to the Internet on a ethernet hub.

Final Words

This tutorial's objective was to give you building blocks to control and/or monitor peripherals over the Internet. Complete source code and program descriptions for a client/server chat program was given. Once the concepts were conveyed, a hardware example was attempted; an 8255 PC Interface card was installed in the server and interfaced to eight LEDs. A client program would be able to turn on/off LEDs over the Internet. This example required adding some code to the client/server chat program. The MPEG video demonstrates the success of Internet-control.

I'm a robotics/mechatronics professor at Drexel University (Philadelphia USA) in the Mechanical Engineering Deparment. Along with my research I developed a GUI-Based Control course. A complete 10 week (30 hours) notes and syllabi are freely available to view. Teaching notes are available to other educators. If interested, please email me. My students applied the tutorial's concepts to control relays, motors, keypads and digital-to-analog converters. Links are available from the above course's web page. Their successes can be mimicked using their comprehensive tutorials and code. If you find them useful, please email and let me know!

Future potential work derived from this tutorial includes using a web server to display data acquired from sensors interfaced to the server PC. Clients would be thus able to monitor data remotely over the Internet. Webcams can also be attached to the server so that Clients can get visual feedback on whether the remote server indeed actuate your peripheral. Some of these concepts are cited in the Course's web page. In the big picture, the building blocks for controlling and monitor hardware over the Internet can be used for home or industrial automation, robotics and data acquisition. In turning on/off an LED you really can light up the world!

Click here to email me