Author Topic: Changing colors by bit  (Read 5760 times)

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Changing colors by bit
« on: October 04, 2014, 07:32:31 PM »
Hello,I am new to Vb and Advanced HMI.  I work with electrical distribution equipment and want to build a project where i can animate a line that represents a busbar with different colors depending on the source of power that is feeding it.  For example utility power is green, generator power is red etc.  I can read modbus bits that tell me what source the bus bar is connected to but how do I change colors depending on register bits?  Also does anyone know of a free software that allows me to create graphics for this purpose.  right now I am using microsoft paint, but that is very cumbersome.  Thanks for the help. 

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Changing colors by bit
« Reply #1 on: October 04, 2014, 08:30:00 PM »
Your second question is an easy one. Try Inkscape, it is a good vector editing software that is free.

For changing a line color, there are a number of ways to do this. Try this to see if it gets you going in the right direction:

1) Add the Modbus driver and set the communication parameters
2) Add a DataSubscriber and set the PLCAddressValue to an integer value (e.g. 40001)
3) Add a Label to the form and set the AutoSize property to False
4) Stretch the Label out to a rectangle (this will become your line)
5) Double click the DataSubscriber to get back to the code
6) Enter this code:
Code: [Select]
   Private Sub DataSubscriber1_DataChanged(sender As System.Object, e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs) Handles DataSubscriber1.DataChanged
        Try
            Select Case CInt(e.Values(0))
                Case 1 'Bit 1
                    Label1.BackColor = Color.Red
                Case 2 'Bit 2
                    Label1.BackColor = Color.Blue
                Case 4 'Bit 3
                    Label1.BackColor = Color.Green
                Case 8 'Bit 4
                    Label1.BackColor = Color.Yellow
            End Select
        Catch ex As Exception

        End Try
    End Sub
Note : This code will only work if one bit in the word is set at a time.
« Last Edit: October 05, 2014, 03:16:10 PM by Archie »

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Changing colors by bit
« Reply #2 on: October 05, 2014, 02:37:03 PM »
I tried this without success.  i set the modbus tcp driver parameters and added a data subscriber1 and set to 40015  then added a label as described.  I also tried using a basic label from AdvHMI components and changed the code to include "Basiclabel1"  Neither one worked.  I verified good comms to the devices.  What else should I try, thanks.   

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Changing colors by bit
« Reply #3 on: October 05, 2014, 02:52:07 PM »
Also add another BasicLabel to the form and set PLCAddressValue to the same address you set in the DataSubscriber (e.g. 40001). This will verify the value is being read through the Modbus

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Changing colors by bit
« Reply #4 on: October 05, 2014, 03:13:51 PM »
I am reading a value of 17 (first and 5th bits)as seen by the bottom label2.  I changed the code to include "basiclabel1".  also I decreased the code to only bit 1 and 2 to avoid possible problems with 5th bit.  No success yet.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Changing colors by bit
« Reply #5 on: October 05, 2014, 03:15:19 PM »
The simple example I had given does not support a value of 17 because it has 2 bits sets simultaneously. Can you get it to be a value of 1 or 2?

or add this line to the case
Code: [Select]
Case 17
            Label1.BackColor = Color.Yellow
« Last Edit: October 05, 2014, 03:17:36 PM by Archie »

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Changing colors by bit
« Reply #6 on: October 05, 2014, 03:56:14 PM »
A better piece of code that will only look at the first 4 bits:
Code: [Select]
Private Sub DataSubscriber1_DataChanged(sender As System.Object, e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs) Handles DataSubscriber1.DataChanged
        Try
            Select Case (CInt(e.Values(0)) and 15)
                Case 1 'Bit 1
                    Label1.BackColor = Color.Red
                Case 2 'Bit 2
                    Label1.BackColor = Color.Blue
                Case 4 'Bit 3
                    Label1.BackColor = Color.Green
                Case 8 'Bit 4
                    Label1.BackColor = Color.Yellow
                Case Else
                    Label1.Text="More than 1 bit set"
            End Select
        Catch ex As Exception

        End Try
    End Sub

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Changing colors by bit
« Reply #7 on: October 05, 2014, 07:39:39 PM »
Works great thanks.  What code changes are needed be use this to show an image(.bmp) as well?  Many thanks!!

edward745

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Changing colors by bit
« Reply #8 on: October 16, 2014, 03:45:27 PM »
Yeah agreed
Works great thanks from me also.  What code changes are needed be use this to show an image(.bmp) as well?  Many thanks!!

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Changing colors by bit
« Reply #9 on: October 20, 2014, 12:34:39 AM »
Im looking to include all bits in the register.  I tried the 5th and 6th bit and this code did not work.  I changed the case to 16 and 32 respectively..no luck.  What code do I need for this to work?  Thanks 

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Changing colors by bit
« Reply #10 on: October 20, 2014, 08:19:32 AM »
The "(CInt(e.Values(0)) and 15)" filters out the first 4 bits. To start looking at all the bits, you also have to consider how you want to handle the situation when multiple bits are set simultaneously.

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Changing colors by bit
« Reply #11 on: October 20, 2014, 01:41:52 PM »
Being new to Vb, Im not sure what that entails.  i just need to display status'(in my case picture boxes) depending on multiple  bits in various registers.  The 4th bit may be position A while 7th bit may be position B.  In addition the 3rd bit of the same register may indicate alarm status.  I have tried to just convert the integer value of a basic label to binary and do some sort of bit check with a "select case" operator but have had no luck. I was also thinking that maybe there would be a way to use the "msg by bit" command for this but not sure how to translate the message to show a picturebox or other graphic.   Is there a way to do this using either method? Many thanks

DougLyons

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
Changing colors by bit
« Reply #12 on: October 21, 2014, 11:58:49 PM »
You can just insert 16 of the Common Controls "Label" components.
Name them Label1 to Label16 and change their TEXT to "0" for brevity.
Note that this is not the same as the "BasicLabel" AdvancedHMI Component.

Now the code below should set the corresponding bits in your value for you and display the bits on the labels.
This makes use of the fact that a comparison (? <> 0) returns a -1 if TRUE and a 0 if False.
Also, because values in BASIC are generally signed a value of greater than 32767 is returned as a negative number.

Code: [Select]
   
Dim Value1 As Long
Private Sub DataSubscriber1_DataChanged(sender As Object, e As Drivers.Common.PlcComEventArgs) Handles DataSubscriber1.DataChanged
        Try
            Value1 = e.Values(0)
            Debug.Print((Value1 < 0) * -1.0)
        Catch ex As Exception
            Debug.Print("Error in Reading")
        End Try
        Label1.Text = ((Value1 < 0) * -1.0)             ' Bit 1 (High Bit)
        Label2.Text = ((Value1 And 16384) <> 0) * -1
        Label3.Text = ((Value1 And 8192) <> 0) * -1
        Label4.Text = ((Value1 And 4096) <> 0) * -1
        Label5.Text = ((Value1 And 2048) <> 0) * -1
        Label6.Text = ((Value1 And 1024) <> 0) * -1
        Label7.Text = ((Value1 And 512) <> 0) * -1
        Label8.Text = ((Value1 And 256) <> 0) * -1
        Label9.Text = ((Value1 And 128) <> 0) * -1
        Label10.Text = ((Value1 And 64) <> 0) * -1
        Label11.Text = ((Value1 And 32) <> 0) * -1
        Label12.Text = ((Value1 And 16) <> 0) * -1
        Label13.Text = ((Value1 And 8) <> 0) * -1
        Label14.Text = ((Value1 And 4) <> 0) * -1
        Label15.Text = ((Value1 And 2) <> 0) * -1
        Label16.Text = ((Value1 And 1) <> 0) * -1       ' Bit 16 (Low Bit)
    End Sub

I have run this and it worked for me.
Let me know if you need more help.

DougLyons

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
Re: Changing colors by bit
« Reply #13 on: October 22, 2014, 12:10:57 AM »
Continuing from the above:

You can add statements such as the following to change the visibility of the PictureBoxes:

PictureBox1.Visible = (Value1 And 1)  ' Low Bit
PictureBox2.Visible = (Value1 And 2)
PictureBox3.Visible = (Value1 < 0)      'High Bit
« Last Edit: October 22, 2014, 12:58:38 AM by DougLyons »

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Changing colors by bit
« Reply #14 on: October 27, 2014, 09:10:54 AM »
Hi Doug, so I had a chance to test this and the code works well.  However there is one glitch.  I am using the "If LabelX.text=1 then picturebox.show". where I have a "stack" of pictureboxes that change to give me animation.  The problem is that after a short while, like a minute or two the labels all read a value of zero eventhough the status has not changed.  i have another label to show me the value of the register Im polling and it does not change.  It seems like if the data does not change after a short while then visual basic or the datasubscriber stops executing the code, which then my animation is all wrong. Is there another way.  I was going to try and convert the integer to a binary string and try to point some code to a particular bit.  Your thoughts??  Thanks