You can get the same output using a bit-mask.
Console.WriteLine("Using bitmask");
for (int i = 0; i < read.Length; i++)
{
int bitMask = 0x8000; // start from left most bit
Console.Write(string.Format("Register {0}: ", i));
for (int j = 0; j < 16; j++)
{
// test bit status and write 1 if set else 0
Console.Write(((read[i] & bitMask) == bitMask) ? "1" : "0");
bitMask >>= 1; // right shift mask one place
}
Console.WriteLine();
}
Or you could use a BitArray.
Console.WriteLine("Using 32bit BitArray");
for (int i = 0; i < read.Length; i++)
{
// convert 32bit integer to bit array
var bits = new System.Collections.BitArray(new[] { read[i] });
Console.Write(string.Format("Register {0}: ", i));
for (int j = 15; j >= 0; j--) // reverse loop as LSB is index 0
{
// test bit status and write 1 if set else 0
Console.Write(bits[j] ? "1" : "0");
}
Console.WriteLine();
}
You could also put all the registers in to a single BitArray.
But remember that the LSB is index 0.
// put all bits in BitArray (remember LSB is index 0)
var allbits = new System.Collections.BitArray(read);
nick.crane
Nearly a Posting Virtuoso
1,230 posts since Feb 2010
Reputation Points: 375
Solved Threads: 187
Regarding the reporting of the bit status as alarms:
I would have a system timer do the read operation and report any connection errors.
This would load the register values in to properties to allow external access.
Have another timer/event read the register bit status and report the alarm conditions.
Keeping the read/write as a separate operation makes debugging easier.
It also means that should you need UI then the read process is not hindered by UI thread operations and vice versa.
nick.crane
Nearly a Posting Virtuoso
1,230 posts since Feb 2010
Reputation Points: 375
Solved Threads: 187
My advice is to have a single thread that read/writes any data to/from the PLC.
This is necessary to ensure the PLC connection is not shared between threads; otherwise you will have trouble with synchronisation.
This thread should put the data in to some common (shared) resource. This could be a database or an object instance of a custom class written for this purpose.
Other tasks can then also read/write the data values from the shared resource without interfering with the PLC communications. What those tasks do is down to your application.
nick.crane
Nearly a Posting Virtuoso
1,230 posts since Feb 2010
Reputation Points: 375
Solved Threads: 187
Here is how I handle reading masked bits:
public static class BITS
{
public const byte BIT0 = 0x01;
public const byte BIT1 = 0x02;
public const byte BIT2 = 0x04;
public const byte BIT3 = 0x08;
public const byte BIT4 = 0x10;
public const byte BIT5 = 0x20;
public const byte BIT6 = 0x40;
public const byte BIT7 = 0x80;
}
Assigning properties to a bit-masked byte:
byte m_alarm;
public bool HasAlarm
{
get { return m_alarm > 0; }
}
public bool LowAlarm1
{
get { return (m_alarm & BITS.BIT0) == BITS.BIT0; }
set { m_alarm = (byte)((m_alarm & ~BITS.BIT0) | (value ? BITS.BIT0 : 0x00)); }
}
public bool HighAlarm1
{
get { return (m_alarm & BITS.BIT1) == BITS.BIT1; }
set { m_alarm = (byte)((m_alarm & ~BITS.BIT1) | (value ? BITS.BIT1 : 0x00)); }
}
sknake
Industrious Poster
4,954 posts since Feb 2009
Reputation Points: 1,764
Solved Threads: 735