|
-
Aug 11th, 2010, 09:45 AM
#1
Thread Starter
New Member
Algorithm Question
Hi All,
I did quite a bit of Google searching, but I’m honestly not even sure what type of Algorithm this would even be called.
Basically, I’m interfacing to a piece of hardware through a .dll which has the following syntax:
Code:
intError = GetHardwareStatus(intStatus)
Depending on the state of the Hardware the The GetHardwareStatus(intStatus) fills intStatus with the Error condition(s) from hardware.
The Hardware datasheet contains the following Error condition map:
Code:
ERROR1 = 1 ;
ERROR2 = 2 ;
ERROR3 = 4 ;
ERROR4 = 8 ;
ERROR5 = 16 ;
ERROR6 = 32 ;
ERROR7 = 64 ;
ERROR8 = 128 ;
ERROR9 = 256;
ERROR10 = 512 ;
Based on the Integer value loaded in intStatus I’m trying to figure out a clever way to determine which Error conditions have been set by hardware.
So for example:
Code:
intError = GetHardwareStatus(intStatus)
loads with an Integer value of 365 which means the hardware has the following error conditions.
Code:
ERROR9 [365-265 = 100]
ERROR7 [100-64=36]
ERROR6 [36-32 = 4]
ERROR3 [4-4=0]
I know I could use an IF/ELSE chain to subtract the ERROR condition from intStatus until I returned a 0 value, but it seems like there should be a more clever way of doing this.
Thanks in advance for your assistance and I apologize if this question has been asked 1000 times before me - I did a search on this forum, but did not find anything.
-
Aug 11th, 2010, 09:54 AM
#2
Re: Algorithm Question
Welcome to VBForums 
The answer isn't obvious unless you know it already, and I seriously doubt you could have guessed at the key words, which are "bit masking".
The trick is to do a comparison of the binary digits within the number (which is only possible because the values are powers of 2), which you can do like this:
Code:
If intStatus And ERROR1 Then
MsgBox "error 1"
End If
If intStatus And ERROR2 Then
MsgBox "error 2"
End If
...
It is far from clear, but the "And" used here is not the normal boolean And - it is the bit-masking version (which can cause problems for other situations if you aren't aware of it!).
If you don't know what binary is (or you just want details on how bit masking works), I recommend searching for a bit-masking tutorial, because it is a surprisingly hard thing to explain well.
-
Aug 11th, 2010, 10:46 AM
#3
Re: Algorithm Question
If you want short code, you can use this:
Code:
intError = GetHardwareStatus(intStatus)
Do While intError
lngCount = lngCount + 1
If intError And 1 Then MsgBox "Error " & lngCount
intError = intError \ 2
Loop
The last line essentially does a bitshift to right. So after first execution bit 10 [512] becomes bit 9 [256]. By always checking the state of bit 1 and increasing the counter we know which error we are dealing with at that moment. The loop keeps on running under intError no longer contains any active bits (ie. it's value is 0).
The advantage with using a counter like this is that you can easily make a separate function to deal with an error condition and seeing if it is necessary to tell about the error to the end user and what kind of message should be displayed (it makes no sense at all to display an error message that only makes sense to a programmer). Of course it is possible to make such a function with bitmasking as well in the style posted by si_the_geek. A counter would mostly be for your convenience.
Last edited by Merri; Aug 11th, 2010 at 10:51 AM.
-
Aug 11th, 2010, 05:29 PM
#4
Thread Starter
New Member
Re: Algorithm Question
I just wanted to thank both of you for your prompt replies! Once I knew to Google "bit masking" things got a lot easier! Thank you!
Here is what I ended up doing:
Code:
For i = 0 To 3 Step 1
Do While bln_ERROR1_Flag = False
intResult = GetHardwareStatus(CStr(i), intStatus)
'Clear Flag Values
bln_ERROR1_Flag = False
bln_ERROR2_Flag = False
bln_ERROR3_Flag = False
bln_ERROR4_Flag = False
bln_ERROR5_Flag = False
bln_ERROR6_Flag = False
bln_ERROR7_Flag = False
bln_ERROR8_Flag = False
bln_ERROR9_Flag = False
bln_ERROR10_Flag = False
If intStatus And ERROR1 Then
bln_ERROR1_Flag = True
End If
If intStatus And ERROR2 Then
bln_ERROR2_Flag = True
End If
If intStatus And ERROR3 Then
bln_ERROR3_Flag = True
End If
If intStatus And ERROR4 Then
bln_ERROR4_Flag = True
End If
If intStatus And ERROR5 Then
bln_ERROR5_Flag = True
End If
If intStatus And ERROR6 Then
bln_ERROR6_Flag = True
End If
If intStatus And ERROR7 Then
bln_ERROR7_Flag = True
End If
If intStatus And ERROR8 Then
bln_ERROR8_Flag = True
End If
If intStatus And ERROR9 Then
bln_ERROR9_Flag = True
End If
If intStatus And ERROR10 Then
bln_ERROR10_Flag = True
End If
Loop
Next i
-
Aug 11th, 2010, 10:34 PM
#5
Re: Algorithm Question
That code can be tightened up:
vb Code:
For i = 0 To 3
Do While bln_ERROR1_Flag = False
intResult = GetHardwareStatus(CStr(i), intStatus)
bln_ERROR1_Flag = (intStatus And ERROR1)
bln_ERROR2_Flag = (intStatus And ERROR2)
bln_ERROR3_Flag = (intStatus And ERROR3)
bln_ERROR4_Flag = (intStatus And ERROR4)
bln_ERROR5_Flag = (intStatus And ERROR5)
bln_ERROR6_Flag = (intStatus And ERROR6)
bln_ERROR7_Flag = (intStatus And ERROR7)
bln_ERROR8_Flag = (intStatus And ERROR8)
bln_ERROR9_Flag = (intStatus And ERROR9)
bln_ERROR10_Flag = (intStatus And ERROR10)
Loop
Next
It cuold be tightened up even further by putting the boolean variables into an array, but with only 10 flags to check it may not be worth it. Note also that the ERROR constants would have to be moved to an array as well, which means they'd no longer be constants. Not that that's a problem; just sayin'.
-
Aug 12th, 2010, 08:44 AM
#6
Thread Starter
New Member
Re: Algorithm Question
Thanks Ellis!
I'm a relative n00b and didn't even realize one could do that!
-
Aug 12th, 2010, 09:29 AM
#7
Re: Algorithm Question
VB6 features a lot of "automatic" datatype coercion that is not always apparent. In this case when trying to put Integer into a Boolean, the value is coerced to a Boolean. Any non-zero value = True, zero = False.
The fun little fact about Boolean is that it is technically an Integer: it is just simply forced that when all bits are set then the value is True (which is equal a value of -1). So a Boolean is not the same thing as a bit just to avoid any confusion. Boolean takes 16 bits in memory just like Integer does.
Thus your single 16-bit Integer intStatus becomes 160 bits when placed in 10 Boolean variables.
-
Aug 12th, 2010, 09:59 AM
#8
Re: Algorithm Question
And another example;
Code:
Private Sub Command5_Click()
Dim IntStatus As Integer, i As Integer, msg As String, IntResult As Integer
IntResult = GetHardwareStatus(CStr(i), IntStatus)
'IntStatus = 2 + 8 + 256
For i = 0 To 15
If IntStatus And 2 ^ i Then
msg = msg & "Error Condition " & i + 1 & vbCrLf
End If
Next
If Len(msg) Then MsgBox msg, , "Error conditions prevailing"
End Sub
-
Aug 12th, 2010, 10:39 PM
#9
Re: Algorithm Question
 Originally Posted by kakarot
Thanks Ellis!
I'm a relative n00b and didn't even realize one could do that!
In that case, your For...Next loop doesn't appear to be doing anything. Are you running the Do...Loop four times for a specific reason?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|