Public bSeekingSync As Boolean‘used to indicate that the program is ‘looking to synchronise the bytes Public nFrozenTime As Single ‘used to timeout to allow sync Public iDMMMessage9 As B
Trang 1Public bSeekingSync As Boolean
‘used to indicate that the program is
‘looking to synchronise the bytes
Public nFrozenTime As Single
‘used to timeout to allow sync
Public iDMMMessage(9) As Byte
Public bEndFlag As Boolean
‘used to denote stop button
‘input buffer
Public bBlocReceived As Boolean
‘indicates a 9 byte block has been recived
Public iInputPointer As Integer
Add a procedure called PollDMM as follows:
‘number of characters to receive before
‘generating on comm event
Trang 2While (Timer - nFrozenTime) < 0.2
‘waiting untill there is a dead time
If bBlocReceived = True Then
‘block has been received.
‘write them to sheet1
Initially, the serial port is opened and configured for single-byte reception using the “with”
construction At the end of the port setup, some values are initialized bSeekingSync is a flag that indicates to the OnComm interrupt that we are looking for a sync signal nFrozen is set
to the current time in seconds bBlocReceived is cleared, but is not used in the
synchroniza-tion process The intensynchroniza-tion is that during the interrupt caused by a character recepsynchroniza-tion, if
bSeekingSync is TRUE, then the latest time is stored on nFrozen, thereby resetting the
coun-ter In the background loop in PollDMM, the program waits for the time to expire at 200 mS Pay attention to the DoEvents instruction—without it there will be no OnComm interrupt
In Parenthesis: Timer
The Timer function in VBA returns the number of seconds since midnight It has a lution of 10 mS If this (or any) program is going to run late at night, you need to allow for this rollover
Trang 3reso-In Parenthesis: DoEvents
Running loops in VBA where there are no screen updates or other system calls, can result
in the program consuming a large portion of the system’s resources and certain processes may not run During these loops, it is advisable to execute a DoEvents instruction which allows Windows to handle all the other processes going on
The OnComm event is an interrupt routine that occurs for almost any status change of the UART The property CommEvent defines the reason for the interrupt See “In Parenthesis: OnComm” for a list of the possible values of the property It is possible to sort out the cause
of the interrupt and to service it by using Select Case construct within the OnComm event
Go to the MSComm code window You can do this in two ways In the VBA Explorer, double-click on the UserForm1 folder (or wherever the control is stored) Right-click on the
MSComm telephone icon, and select View Code from the pop-up window A quicker way
is to right-click on the UserForm1 folder in the VBA Explorer, and select View Code from
there This will take us straight to the OnComm event The code we will use is:
Private Sub MSComm1_OnComm()
Dim Dummy As Variant
Dim RXbytes() As Byte
Dim iI As Integer
Select Case MSComm1.CommEvent
Case comEvReceive
If bSeekingSync = True Then
‘looking for sync.
nFrozenTime = Timer
‘refresh time since a character
‘has been seen
Trang 4Notice in the first part of the OnComm event, while bSeekingSync is TRUE, that timer gets refreshed and the data buffer emptied.
If we look at the PollDMM procedure again, we see that once the synchronization is found, the serial port is reconfigured to handle 9 bytes of data at a time When the 9 bytes are received, they are actually read in the else clause of the OnComm procedure A flag is set for the PollDMM procedure to indicate there is valid data available to be processed in the loop-ing section of PollDMM
The background loop scans two Boolean variables The first, bBlocReceived, has just been cussed The second, bEndFlag, is a flag to indicate that the process should halt It is generated
dis-from a Command button, which we will introduce shortly Once a block of data is received,
it is placed on Sheet1 using the Cells instruction Just prior to this, the code sets the active
sheet to Sheet1 using a Sheets(“Sheet1”).Select statement.
In Parenthesis: OnComm Event
It is possible to use the serial port without resorting to the interrupts used by the Comm event Given that the operating system can have a lot to do, and can be fairly unpredictable in doing it, it is safer, in my opinion, to rely on the interrupt structure The OnComm event can be triggered by the following occurrences The names are actual VB constants that can be used in the case statements
On-Normal Operation:
comEvCD: change in state of the CD input signal
comEvCTS: change in state of the CTS input signal
comEvDSR: change in state of the DSR input signal
comEvRing: change in state of the RI input signal
comEvReceive: The receive buffer has RThreshold characters stored
comEvSend: The transmit buffer has less than SThreshold characters stored
comEvEOF: EOF (End of File) character (0x1A) received
Exceptions:
comEventBreak: break signal received
comEventFrame: framing error detected
comEventOverrun: overrun error detected
comEventRxOver: more than RThreshold characters received
comEventRxParity: parity error detected
comEventTxOver: more than SThreshold characters placed in buffer
comEventDCB: unexpected error retrieving Device Control Block from port
Trang 5Before we attempt to run this, let’s place two Command buttons on Sheet1 View | Toolbars
Control Toolbox brings up the correct toolbox Place two buttons and change the names to
cmdStart and cmdStop Then change the captions to Stop and Start In their click events, let’s
add the code:
Private Sub cmdStart_Click()
‘disable interrupts- sometimes the click happens
‘while the inrerrupt is being serviced
‘if this isn’t here the click may have no effect
‘in those circustances
Private Sub Workbook_Open()
Trang 6In Excel, click on the Start button and watch the numbers change Change the function selector on the DMM and observe the effects It’s all downhill from here, but we still have quite a bit to cover Figure 14-6 is how the worksheet should appear with the DMM reading
as in Figure 14-7
Try stopping the process by clicking on the Stop button Typically, this is very difficult since
it appears that the OnComm interrupt masks the click I don’t know why, but after some trial and error, I found that menu bars are not subject to the same problems so I modified the program to run from a Menu Bar
Figure 14-6: Placing incoming data on the worksheet In fact, the reading was 164.8 mA.
Trang 7I have left this spreadsheet stored on the CD-ROM as DMM1.xls, in case you wish to
experi-ence the frustration on having to click many times on the stop button just to get it to be seen
by the PC
Before we add the toolbar, let’s get rid of the Command buttons If the Control Toolbox is
not visible, make it so by View | Toolbars | Control Toolbox Make sure the Design Mode button (the set square) is active Right-click on each button and select Cut from the pop-up
menu Unfortunately, this does not remove the code we have written referring to these
ex-buttons We have to go to VBA and in the VBA Explorer, right-click on Sheet1 and select
View Code Delete the code for both buttons and then in a similar fashion view the code for
the workbook and delete the code for the workbook open event
Now let’s create a toolbar In Sheet1, click on Tools | Customize and select the Toolbars tab Click on the New button and we should see something like Figure 14-8.
After clicking on the OK button, this toolbar will be added to the list (It will be available
to any application if it is enabled by placing a check next to the name.) A small toolbar
appears with no buttons on it To add a button, click on the Commands tab in the ize dialog box Find the entry Macros in the Categories window and then click and drag the
Custom-Custom button to the DMM toolbar Repeat the process of adding a Custom-Custom button and you will have two smiley-faced buttons within the bar While keeping the Customize dialog box
open, right-click on one of the smileys and modify the Name to &Acquire The ampersand
places a line under the following letter and can be used for a keyboard shortcut nately, this shuts the pop-up window and we have to right-click several times to complete
Unfortu-the setup Check next to Unfortu-the Image and Text and Change Unfortu-the Button Image to Unfortu-the picture
of a running man Assign the macro PollDMM with this button Change the second button
to a Stop button in a similar fashion, assigning the macro ForceStop to it See Figure 14-9
Figure 14-7: Setup of DMM being read into worksheet.
Trang 8Figure 14-8: Adding a toolbar named DMM.
Figure 14-9: Setting up toolbar button properties.
Trang 9The toolbar should look like Figure 14-10.
Figure 14-10: Resulting toolbar.
In Parenthesis: Custom Toolbar Limitation
The toolbar, once created, will always appear in all workbooks as they are opened They can be turned off using the “X” in the top right-hand corner Toolbars can be re-enabled
from the Customize dialog under the Toolbars tab (see Figure 14-8) Finding the toolbar
and checking the box next to it will re-enable it
By default, toolbars are stored with Excel and not with the workbook They can be bedded into the workbook from the Customize dialog under the Toolbars tab (see Figure
em-14-8) Click on the Attach button, and in the resulting dialog select the desired toolbar
that is listed in the Custom Toolbars window and click on the Copy>> button to copy
the toolbar to the Toolbars in workbook window Click on the OK button followed by
the Close button and save the workbook
As a direct upshot of this, the macro associated with a menu button is tied to a particular workbook If that workbook is not open, it will be opened This can be positive since it will automatically open a workbook when the control is clicked without any effort on our part However, in our current example it is problematic As we go, I am saving different versions of the same workbook and the macros, although they are named the same, are different Make sure that the macros the buttons refer to are in the current workbook
In order to do this, make sure the Customize dialog is open, right-click on the button and edit the cell to the associated macro
We also need to edit both macros to make sure that we don’t try to open an open port or to close a closed port The beginning of PollDMM becomes:
Trang 10‘number of characters to receive before
‘generating on comm event
.DTREnable = True
.RTSEnable = False
End With
‘add check if port is open
If UserForm1.MSComm1.PortOpen = False Then
‘disable interrupts- sometimes the click happens
‘while the interrupt is being serviced
‘if this isn’t here the click may have no effect
‘in those circumstances
If UserForm1.MSComm1.PortOpen = True Then
Conversion of DMM Display to Data
I have decided to ignore all the non-numeric outputs that are possible, like the units I don’t see any point in trying to recreate the universal DVM input since an interface that we are trying to create would likely be to gather a single range of data I will also presume that since the user has to manually invoke the RS-232 interface, he or she can just as easily set the unit
to a particular range (anything but autorange) I hope you find this approach reasonable It will certainly make the code shorter and more understandable
Trang 11In Module1 of VBA, enter the following function:
Public Function sCreateDigit(i7Segment As Integer) As String
Dim bDecPnt As Boolean
Dim sRetVal As String
Dim iTemp As Integer
‘checking for decimal point
‘see text for description on And
iTemp = i7Segment And 8
‘using lookup table for possible characters
Select Case i7Segment
Trang 12Visual Basic unfortunately uses the same word for both a logical and a bitwise AND It is taken in context, so that you cannot look for a bit in an integer (as in the above code) by
entering if i7segment AND 8 since VB would evaluate i7segment which is either true or false
(nonzero or zero), and logically AND it with the number 8 (which will always be true) and the meaning will not be the same as a bitwise AND The way around this is to ascribe the
operation to a variable as in iTemp=i7segment And 8 and then have a conditional test for
iTemp
Enter the formula:
=sCreateDigit(A4)
in cell C4 Copy the cell to C5, C6 and C7 In cell C11, enter the formula:
=C7 & C6 & C5 & C4
which concatenates the digits and creates a number that should agree with the instantaneous display of the DMM
In cell C12, the formula:
=value(c11) converts the string to a number We could format C11 (and I have) to
re-semble an LED output by changing the size and color of the cell text format
Analog Meter Chart
Despite the fact that I said I did not want to recreate a DVM input, there is an interesting way of applying a pie chart to make it look like an analog meter While it is hardly Labview®,
it is certainly a lot cheaper
Before we start, it might be easier if you looked at Figure 14-19 to get an idea of what we are trying to implement The full 360 degrees of the pie chart are broken into three sectors The first sector of the pie chart is obviously our reading as a percentage of full scale The second sector is the full-scale reading minus the actual reading, and the third sector is the balance of
Trang 13the pie chart The meter will operate through an angle of 150 degrees (which we can make programmable by entering it in a cell), so we need to scale the ratios according to this Take
a look at the formulas in Figure 14-11
Figure 14-11: Formulas needed for analog meter Note cell B17 has been named MetAng.
Obviously the sum of the elements of the pie chart must add up to the whole Return to the
nonformula display (Tools | Options and uncheck Formulas on the View tab), and block
select cells B19 to B21 Click on the Chart Wizard icon on the main toolbar (or click on
Insert | Chart) You should see the first window of the Chart Wizard Select the Pie Chart
as in Figure 14-12 Click on Next.
The second step (Figure 14-13) gives us an idea of what we are going to see Since we have already predefined the data block, no further entry is needed so we click on Next
Trang 14Figure 14-12: Step 1 – We are going to create a pie chart.
Figure 14-13: Step 2 – We have the option to modify the selected data series.
Trang 15In the third step, we can add a title on the Titles tab Click on the Legend tab and deselect the Show legend option Then click on Next
Figure 14-14: Step 3 – S ome cosmetic changes.
Finally, we need to decide where the chart will reside I decided that it should be on Sheet1
(see Figure 14-15) Then click on Finish.
Figure 14-15: Step 4 – W e place the chart on Sheet1.
We maneuver the chart to a convenient place on the sheet as in Figure 14-16
Now we want to get rid of the largest area of the chart Click on this area until it is selected
You may need to click twice Then right-click and select Format Data Point from the
pop-up menu Under the Patterns tab (Figure 14-17), we set the selection to no border and no
Area fill effect
Trang 16Figure 14-16: Chart is now resident on Sheet1.
Figure 14-17: Making the
largest area invisible.
Trang 17Next we click on the Options tab We can see that the largest slice has already vanished Modify the Angle of the first slice to 75 degrees and deselect the Vary colors by slice op- tion The result is Figure 14-18 Click on OK.
Figure 14-18: Rotating the dial Using the same color for both slices makes the separating line appear like a needle.
We can change the background color to anything I chose to go with white Click on both segments in turn so they are selected (again you may need to click twice), and right-click
Select Format Data Point and then select the white color in the Patterns tab As an
after-thought, I suppose you could change the background color if an alarm exists
Before we decide to run the data acquisition, I need to mention something that will save you some confusion For some reason that I do not understand, when the chart is placed on Sheet1, the code in the PollDMM procedure:
For i = 0 To 8
Cells(i + 1, 1) = iDMMMessage(i)
Next i
will not run without generating an error If the chart is on another sheet there is no problem,
although we would need to get rid of the Sheets(“Sheet1”).Select statement that occurs just
prior to the above code If it is left in, viewing the chart becomes quite irritating with the
continual return of Sheet1 Of course, this would necessitate changing the Cells(i+1,1) to
include a reference to Sheet1 I actually take this approach later in the example, but for the moment, let it ride
Trang 18I also tried experimenting with concatenation of strings adding the iteration number “i” to a string containing “A” to allow a slightly less elegant approach (as in Range(“Ax”) where x is the string value of i), but that caused the same problem However, if we take the brute force approach of writing each cell directly, it works well That section of PollDMM becomes:
If bBlocReceived = True Then
‘block has been received.
‘write them to sheet1
Trang 19Before you modify the procedures for this new approach, please consider the information in
“In Parenthesis: Custom Toolbar Limitation.”
If we like, we can add an outer ring to the meter with indication for certain ranges (Take a look at Figure 14-24 for our objective.) In order to do this, we must clear the existing chart since we need to start again We modify the angle of the meter to 180 degrees just to simplify matters and we create a second table in cells D19 to E22 The cells in D19 to D22 represent the different ranges that should appear while the cells in E19 to E22 define text to appear in the ranges
Figure 14-20: Preparing a donut chart.