Results 1 to 9 of 9

Thread: Algorithm Question

  1. #1

    Thread Starter
    New Member
    Join Date
    Jan 2008
    Posts
    3

    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
    Code:
    intStatus
    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.

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    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.

  3. #3
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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.

  4. #4

    Thread Starter
    New Member
    Join Date
    Jan 2008
    Posts
    3

    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

  5. #5
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Algorithm Question

    That code can be tightened up:
    vb Code:
    1. For i = 0 To 3
    2.     Do While bln_ERROR1_Flag = False
    3.         intResult = GetHardwareStatus(CStr(i), intStatus)
    4.  
    5.         bln_ERROR1_Flag = (intStatus And ERROR1)
    6.         bln_ERROR2_Flag = (intStatus And ERROR2)
    7.         bln_ERROR3_Flag = (intStatus And ERROR3)
    8.         bln_ERROR4_Flag = (intStatus And ERROR4)
    9.         bln_ERROR5_Flag = (intStatus And ERROR5)
    10.         bln_ERROR6_Flag = (intStatus And ERROR6)
    11.         bln_ERROR7_Flag = (intStatus And ERROR7)
    12.         bln_ERROR8_Flag = (intStatus And ERROR8)
    13.         bln_ERROR9_Flag = (intStatus And ERROR9)
    14.         bln_ERROR10_Flag = (intStatus And ERROR10)
    15.      Loop
    16. 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'.

  6. #6

    Thread Starter
    New Member
    Join Date
    Jan 2008
    Posts
    3

    Re: Algorithm Question

    Thanks Ellis!

    I'm a relative n00b and didn't even realize one could do that!

  7. #7
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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.

  8. #8
    Frenzied Member
    Join Date
    Mar 2008
    Posts
    1,210

    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

  9. #9
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Algorithm Question

    Quote Originally Posted by kakarot View Post
    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
  •  



Click Here to Expand Forum to Full Width