// Get the length of the area in words (2 bytes per word)
        public static int GetSpan(Modbus MB, T start, T end)
        {
            AttrData startAttr = MB.GetAttrData(start);             // Starting memory address (Words)
            AttrData endAttr   = MB.GetAttrData(end);               // Ending memory address

            Debug.Assert(startAttr.Val <= endAttr.Val);             // Make sure they are in the correct order
            return(endAttr.Val - startAttr.Val + endAttr.Data.Len); // Be sure to include the last element
        }
        private void GetMessages(ModbusPkt pkt)
        {
            StringBuilder sb   = new StringBuilder();
            List <string> msgs = new List <string>();

            string[] s = new string[3];
            // For now, look at the first 48 only.  Need to implement block read
            AttrData attrCount = MB.GetAttrData(ccMM.Registration);

            for (int i = 0; i < Math.Min(3, attrCount.Count); i++)
            {
                int reg = MB.GetDecAttribute(ccMM.Registration, i);
                if (reg == 0)
                {
                    continue;
                }
                for (int j = 15; j >= 0; j--)
                {
                    if ((reg & (1 << j)) > 0)
                    {
                        int n = i * 16 - j + 15;                      // 1-origin
                        MB.SetAttribute(ccIDX.Start_Stop_Management_Flag, 1);
                        MB.SetAttribute(ccIDX.Message_Number, n + 1); // Load the message into input registers
                        MB.SetAttribute(ccIDX.Start_Stop_Management_Flag, 2);
                        s[0] = MB.GetHRAttribute(ccMM.Group_Number);
                        s[1] = MB.GetHRAttribute(ccMM.Message_Number);
                        s[2] = MB.GetHRAttribute(ccMM.Message_Name);
                        msgs.Add(string.Join(",", s));
                    }
                }
            }
            AsyncComplete ac = new AsyncComplete(MB, pkt)
            {
                MultiLine = msgs.ToArray()
            };

            parent.BeginInvoke(new EventHandler(delegate { Complete(this, ac); }));
        }
Esempio n. 3
0
        // Attribute selection changed
        private void cbAttribute_SelectedIndexChanged(object sender, EventArgs e)
        {
            cbInstance.Items.Clear();
            if (cbAttribute.SelectedIndex >= 0)
            {
                int n1 = Array.FindIndex(ccNames, x => x == cbClass.Text);
                attValues = (int[])Enum.GetValues(MB.ClassCodeAttributes[n1]);
                int n2 = Array.FindIndex(attrNames, x => x == cbAttribute.Text);
                attr = MB.GetAttrData(MB.ClassCodes[n1], attValues[n2]);
                if (attr.HoldingReg)
                {
                    optHoldingRegister.Checked = true;
                }
                else
                {
                    optInputRegister.Checked = true;
                }
                switch (attr.Nozzle)
                {
                case Noz.None:
                    cbNozzle.SelectedIndex = 0;
                    break;

                case Noz.Current:
                    cbNozzle.SelectedIndex = MB.Nozzle + 1;
                    break;

                case Noz.Both:
                    cbNozzle.SelectedIndex = 3;
                    break;

                default:
                    break;
                }
                int n = attr.Count;
                for (int i = 0; i < n; i++)
                {
                    cbInstance.Items.Add(i);
                }
                cbInstance.SelectedIndex = 0;
            }
        }
        // Get an attribute and convert it to a string for SOP output
        public string Get(T item, int index, int resultLen)
        {
            string   result  = string.Empty;
            AttrData getAttr = MB.GetAttrData(item);                       // Get attributes of desired item
            int      n       = (getAttr.Val - BaseAttr.Val) * 2 +          // Get offset in byte array (2 bytes per word)
                               (index - this.Index) * BaseAttr.Stride * 2; // Relative to the Index that was loaded
            int len = getAttr.Data.Len;                                    // Get length

            switch (getAttr.Data.Fmt)                                      // Format the data as needed
            {
            case DataFormats.None:
                break;

            case DataFormats.SDecimal:
            case DataFormats.Decimal:
                len += len;                                 // Length is in words so double it
                int res = 0;
                for (int i = 0; i < len; i++)
                {
                    res = (res << 8) + b[n + i];            // Words are stored in Big Endial format
                }
                result = res.ToString($"D{resultLen}");     // To string with leading zeros
                break;

            case DataFormats.UTF8:
                char[] c = new char[len];
                Buffer.BlockCopy(b, n + 1, c, 0, len * 2 - 1); // Characters are stored as little endian.
                result = new string(c);
                break;

            case DataFormats.Date:                          // Probably on a TODO list
            case DataFormats.Bytes:
            case DataFormats.AttrText:
            default:
                break;
            }
            MB.LogIt($"BGet[{MB.GetNozzle(getAttr)}{getAttr.Val:X4}+{n / 2:X4}] {MB.GetAttributeName(getAttr.Class, getAttr.Val)} = " +
                     $"{result}");
            return(result);
        }
 // Let Section find the attrData
 public Section(Modbus MB, T attr, int index, int Len, bool load)
     : this(MB, MB.GetAttrData(attr), index, Len, load)
 {
 }
        bool Load;            // Save to cut down on trace I/O

        #endregion

        #region Constructor, Destructor, and Service Routines

        // Let Section find the attrData and calculate the span
        public Section(Modbus MB, T startAttr, T endAttr, int index, bool load)
            : this(MB, MB.GetAttrData(startAttr), index, GetSpan(MB, startAttr, endAttr), load)
        {
        }