Tuesday, September 2, 2008

VISUAL BASIC FOR MICRO-CONTROLLERS

Basic Circuit Diagram for PC to Microcontroller CommunicationUsing the Serial Port
8051 provides a transmit channel and a receive channel of serial communication. The transmit data pin (TXD) is specified at P3.1, and the receive data pin (RXD) is at P3.0. The serial signals provided on these pins are TTL signal levels and must be boosted and inverted through a suitable converter(MAX232) to comply with RS232 standard.
All modes are controlled through SCON, the Serial CONtrol register. The SCON bits are defined as SM0, SM1, SM2, REN, TB8, RB8, TI, RI from MSB to LSB. The timers are controlled using TMOD, the Timer MODe register, and TCON, the Timer CONtrol register.


Properties of Communication Port Control

The Comm component is added to a form whenever serial communications are required. By default, the first created object is named MSComm1 (the second is named MSComm2, and so on). It can be seen that the main properties of the object are: CommPort, DTREnable, EOFEnable, Handshaking, InBufferSize, Index, InputLen, InputMode, Left, Name, NullDiscard, OutBufferSize, ParityReplace, RThreshold, RTSEnable, Settings, SThreshold, Tag and Top.

Settings
The Settings property sets and returns the RS-232 parameters, such as baud rate, parity, the number of data bit, and the number of stop bits. Its syntax is:

[form.]MSComm.Settings = setStr[$]

where the strStr is a string which contains the RS-232 settings. This string takes the form:
"BBBB,P,D,S"
where
BBBBdefines the baud rate,
P the parity,
D the number of data bits, and
S the number of stop bits.
The following lists the valid baud rates (default is 9600Baud):
110, 300, 600, 1200, 2400, 9600, 14400, 19200, 38400, 56000, 128000, 256000.
The valid parity values are (default is N): E (Even), M (Mark), N (None), O (Odd), S (Space).
The valid data bit values are (default is 8): 4, 5, 6, 7 or 8.
The valid stop bit values are (default is 1). 1, 1.5 or 2.
An example of setting a control port to 4800Baud, even parity, 7 data bits and 1 stop bit is:

Com1.Settings = "4800,E,7,1"

CommPort
The CommPort property sets and returns the communication port number. Its syntax is:

[form.]MSComm.CommPort = portNumber[%]

which defines the portNumber from a value between 1 and 99. A value of 68 is returnedif the port does not exist.

PortOpen
The PortOpen property sets and returns the state of the communications port. Its syntax is:

[form.]MSComm.PortOpen = [{True | False}]

A True setting opens the port, while a False closes the port and clears the receive andtransmit buffers (this automatically happens when an application is closed).
The following example opens communications port number 1 (COM1:) at 4800 Baud with even parity, 7 data bits and 1 stop bit:


Inputting data
The three main properties used to read data from the receive buffer are Input, InBuffer Count and InBufferSize.

Input
The Input property returns and removes a string of characters from the receive buffer. Its
syntax is:


[form.]MSComm.Input

To determine the number of characters in the buffer the InBufferCount property is tested (to be covered in the next section). Setting InputLen to 0 causes the Input property to read the entire contents of the receive buffer.


InBufferSize
The InBufferSize property sets and returns the maximum number of characters that can be received in the receive buffer (by default it is 1024 bytes). Its syntax is:

[form.]MSCommInBufferSize = [numBytes%]

The size of the buffer should be set so that it can store the maximum number of characters that will be received before the application program can read them from the buffer.

The InBufferCount property returns the number of characters in the receive buffer. It can also be used to clear the buffer by setting the number of characters to 0. Its syntax is:

[form.]MSCommInBufferCount= [count%]

Outputting data
The three main properties used to write data to the transmit buffer are Output, OutBufferCount and OutBufferSize.
The Output property writes a string of characters to the transmit buffer. Its syntax is:

[form.]MSComm. output= [outString$]

OutBufferSize
The OutBufferSize property sets and returns the number of characters in the transmit buffer (default size is 512 characters). Its syntax is:

[form.]MSCommOutBuffer size = [NumBytes%]

OutBufferCount
The OutBufferCount property returns the number of characters in the transmit buffer.The transmit buffer can also be cleared by setting it to 0. Its syntax is:

[form.]MSCommOutBufferCount. = [0]

Sending Data To A Microcontroller

In the last article we went a little more in depth into Advanced String Parsing. These skills will be needed when receiving data from a microcontroller. All of the data received will be in a buffer and you will have to separate the data, and use it accordingly.

In this article we are going to learn how to send data to a microcontroller and make the microcontroller respond to the data. For simplicity we are just going to send data to turn certain pins on and off.

So lets start off with designing a communications protocol. From VB we will send an ASCII 255, as a synch byte, the pin number (0 to 15), and the on/off state (0 or 1). The microcontroller will wait for three (3) bytes of data. After these three bytes of data are received, it will then either switch the pins to their High or Low state.

The VB Part

bulletTo get started open Visual Basic.
bulletStart a new Standard EXE.
bulletNext go to the Project | Components... menu
bulletCheck the MSComm Control.
bulletClick OK.
bulletNext double-click on the yellow phone in the toolbar to add the MSComm control to your form.

Your form should look like this...


Next we are going to add a Combo Box to our form and name it cboPinNumber. We are also going to add an Option Button to the form. Add the first one and name it optState. Select optState and press Ctrl-C to copy, and then Ctrl-V to paste. You will get a propmt like the one below...


Select Yes.

Now you should notice that the first option button that you created has a name of optState(0) and the second one has a name of optState(1). The number after the control name is the control array index. We will use this to our advantage later. Also add a Command button named cmdSend to the form.

Go ahead and pretty up your form and add some labels to make it look better. The only requirement is that you set optState(0)'s Caption property equal to "Low", optState(1)'s Caption property equal to "High", cmdSend's Caption property equal to "Send", and cboPinNumber's Style property equal to (2). Your form should look something like mine, below...

On To The Code
Now that the form is set up and ready to go, we need to start adding our code to the project. The user will select a pin number from cboPinNumber, select a pin state from optState, and then click cmdSend to send the data to the microcontroller. So first of all we need to get the pin numbers into the combo box, set up the MSComm control, and select one of the pin states to start with. So lets add the following code to our form...

Private Sub Form_Load()
Dim Pins As Long

' Add the pin numbers 0 to 15 to cboPinNumber
For Pins = 0 To 15
cboPinNumber.AddItem CStr(Pins)
Next Pins

' Default to Pin 0 being selected
cboPinNumber.ListIndex = 0

' Default to optState(0) being selected
optState(0).Value = True

' Use COM1
MSComm1.CommPort = 1

' 2400 baud, no parity, 8 data bits, 1 stop bit
MSComm1.Settings = "2400,N,8,1"

' Disable DTR
MSComm1.DTREnable = False

' Open the port
MSComm1.PortOpen = True

End Sub

Now we just need to add the code to send the data. When the user presses cmdSend, we need to do three things.

bulletGet the pin number...
bulletGet the pin state...
bulletSend the data...

Getting the pin number is very easy with the way that we have set up our form. As you may know a combo box lists items starting from a zero index. So this means that if we select pin 7 in the combo box, the combo box's ListIndex property is equal to 7.

To get the selected state we simply write a short If statement like so...

Dim PinState As Long
If optState(0).Value = True Then
PinState = 0
Else
PinState = 1
End If

Now lets put it all together and send the data when we press the cmdSend button...

Private Sub cmdSend_Click()
Dim PinNumber As Long
Dim PinState As Long

' Get Pin Number
PinNumber = cboPinNumber.ListIndex

' Get Pin State
If optState(0).Value = True Then
PinState = 0
Else
PinState = 1
End If

' Send Out Data
MSComm1.Output = Chr$(255) & Chr$(PinNumber) & Chr$(PinState)

End Sub

So we sent out the synch byte (255), followed by the pin number, followed by the pin state.

Finally we need to close the comm port when the VB project unloads so...

Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen = False
End Sub

We are finished with the VB part...! Not so bad, huh..?

The Microcontroller Part
For simplicity I am going to use a Basic Stamp II to receive the data and act accordingly to the data. You will need to hook up the Basic Stamp II just like you are going to program it and use the programming port (pin 16) for communications. Program the Basic Stamp II with the following code...

PinNumber var byte
PinState var byte

Main:

' Use the programming port to receive
' data at 2400 baud
' Wait for the synch byte (255) and then
' get the PinNumber and PinState
Serin 16,16780,[WAIT(255),PinNumber,PinState]

' If PinState=0 Then go to GoLow
' otherwise go to GoHigh
Branch PinState,[GoLow,GoHigh]
Goto Main


' Set The pin low
GoLow:
LOW PinNumber
Goto Main


' Set the pin high
GoHigh:
HIGH PinNumber
Goto Main

Now run the VB project, hook up some LEDs to some of the pins, select the pin number, select either HIGH or LOW, and press send. You should see the LED turn ON when you send a high command, and turn OFF when you send a LOW command.


Receiving Data From A Microcontroller

In the last article we sent data to a microcontroller and had it respond to the data that we sent...

In this article we are going to learn how to receive data from a microcontroller and make the PC respond. For simplicity we are going to have a Basic Stamp II get the RCTime value of a simple circuit and send the value to the PC for us to receive using VB.

We are going to get the RCTime value in the Stamp as a Word. This causes a little trouble when sending data to the PC, so I will show you how to split the word into two bytes, a HighByte and LowByte, and then join them back together to preserve the accuracy of the RCTime measurement...

The VB Part

bulletTo get started open Visual Basic.
bulletStart a new Standard EXE.
bulletNext go to the Project | Components... menu
bulletCheck the MSComm Control.
bulletClick OK.
bulletNext double-click on the yellow phone in the toolbar to add the MSComm control to your form.
bulletFinally add a label to your form and name it lblRCTime.



On To The Code
Now that the form is set up and ready, we need to get a quick understanding of how the MSComm control can receive data from the serial port. There are basically two methods, polling the port and responding to communications events.

Polling the port is done by setting up a timer to check the buffer for data, and if data is there, process it. Polling is better when you have variable length data that starts and ends with header and footer bytes respectively.

The event driven method is designed more for receiving fixed length data. It is also better because you don't waist time polling the buffer for data if none is there. Instead the MSComm control will tell you when data is there by firing the OnComm() event. This event fires just like a Click() event would fire if you clicked on a Command Button, only it is not the users action that fires this event, something must happen at the serial port.

When the OnComm() event is fired you must check the value of the CommEvent property to see what exactly happened. The CommEvent property will contain a different value for each different kind of communication event that occurs. Below is a table that shows the event, the value of the CommEvent property, and the corresponding VB Constant...

Constant

Value

Description

comEvSend

1

Send event.

comEvReceive

2

Receive event.

comEvCTS

3

Change in clear-to-send line.

comEvDSR

4

Change in data-set ready line.

comEvCD

5

Change in carrier detect line.

comEvRing

6

Ring detect.

comEvEOF

7

End of file.

In this project we are only concerned with the comEvReceive constant which has the value of 2 and is fired when data is available in the buffer.

Now that we have a feel for how the MSComm control will assist us in receiving data, lets first set up the MSComm control. Copy this commented code to your project...

Private Sub Form_Load()

' Fire Rx Event Every Two Bytes
MSComm1.RThreshold = 2

' When Inputting Data, Input 2 Bytes at a time
MSComm1.InputLen = 2

' 2400 Baud, No Parity, 8 Data Bits, 1 Stop Bit
MSComm1.Settings = "2400,N,8,1"

' Disable DTR
MSComm1.DTREnable = False

' Open COM1
MSComm1.CommPort = 1
MSComm1.PortOpen =
True

End Sub

You may notice that there are two new properties in the above code that have yet to be explained in these articles. The first is RThreshold. In this example, setting the RThreshold property equal to 2 tells the MSComm control to fire the comEvReceive event when there are at least two bytes available in the buffer. The second property, InputLen, tells the MSComm control to only give us the first two bytes when we request data from the buffer.

With that out of the way, lets take a look at the code that is executed when the OnComm() event is fired. The comments should help you along...

Private Sub MSComm1_OnComm()
Dim sData As String ' Holds our incoming data
Dim lHighByte As Long ' Holds HighByte value
Dim lLowByte As Long ' Holds LowByte value
Dim lWord As Long ' Holds the Word result

' If comEvReceive Event then get data and display
If MSComm1.CommEvent = comEvReceive Then

sData = MSComm1.Input
' Get data (2 bytes)
lHighByte = Asc(Mid$(sData, 1, 1))
' get 1st byte
lLowByte = Asc(Mid$(sData, 2, 1))
' Get 2nd byte

' Combine bytes into a word
lWord = (lHighByte * &H100) Or lLowByte

' Convert value to a string and display
lblRCTime.Caption = CStr(lWord)

End If
End Sub

The above code first checks the CommEvent property to see if a comEvReceive event has been fired. If so, we input the first two bytes of data, combine the bytes to make a word, and display the value in lblRCTime. Is it easier than you thought..?

The only thing left to do is close the COM port when our project is unloaded so...

Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen =
False
End Sub

The Microcontroller Part
For simplicity I am going to use a Basic Stamp II to send the data to the PC. You will need to hook up the Basic Stamp II just like you are going to program it and use the programming port (pin 16) for communications. Program the Basic Stamp II with the following code...

Result Var Word

Main:
High 0
Pause 1
RCTime 0,1,Result
Serout 16,16780,[Result.HighByte, Result.LowByte]
Pause 100
Goto Main

You will need to interface the Basic Stamp with a few components. Below is a schematic...

I used a 50k ohm pot and a 2.2 uF cap. This gave me results that almost covered the whole range of the RCTime measurement.

After hooking up the above circuit run your VB project, power up your Stamp, adjust the pot and watch the values change. You are now receiving data from the Stamp..!

No comments:

Post a Comment

Subscribe Now: Google

Followers

Total Pageviews

CO.CC:Free Domain