Browse Source

更新为一次读取所有的

weijw 5 months ago
parent
commit
b18fa4c3e4
1 changed files with 198 additions and 12 deletions
  1. 198 12
      MainForm.cs

+ 198 - 12
MainForm.cs

@@ -11,6 +11,7 @@ namespace xicheji
         private readonly Config config;
         private readonly List<WashRecord> washRecords = new();
         private DateTime lastReceiveTime = DateTime.MinValue;
+        private byte[] currentDataBlock;
         private Plc? plc = null;
         private HikApi? hikApi = null;
 
@@ -43,6 +44,7 @@ namespace xicheji
                 ConnectPLC();
                 //ConnectCamera();
 
+                receivePLCTimer.Interval = config.PLCReceiveInterval * 1000;
                 receivePLCTimer.Enabled = true;
                 uploadTimer.Enabled = true;
             }
@@ -93,8 +95,7 @@ namespace xicheji
 
         private void ReadPLCData()
         {
-            lblWashCount.Text = ReadPLCString("洗车次数");
-            return;
+            currentDataBlock = plc!.ReadBytes(DataType.DataBlock, 1, 0, 100);
 
             var time = new DateTime(
                 DateTime.Now.Year,
@@ -162,31 +163,52 @@ namespace xicheji
         private string ReadPLCString(string name)
         {
             var variable = ConfigHelper.FindVariable(name);
-            if (plc == null || variable == null)
+            if (variable == null)
                 return string.Empty;
 
-            var value = plc.Read(variable.Key);
-            return $"{value} {variable.Desc}";
+            Parse(variable.Key, out _, out _, out var varType, out var address, out var bitNumber);
+            if (varType == VarType.DWord)
+            {
+                var value = S7.Net.Types.DWord.FromByteArray(currentDataBlock.Take(new Range(address, address + 4)).ToArray());
+                return $"{value} {variable.Desc}";
+            }
+            else if (varType == VarType.Word)
+            {
+                var value = S7.Net.Types.Word.FromByteArray(currentDataBlock.Take(new Range(address, address + 2)).ToArray());
+                return $"{value} {variable.Desc}";
+            }
+            return string.Empty;
         }
 
         private int ReadPLCInt(string name)
         {
             var variable = ConfigHelper.FindVariable(name);
-            if (plc == null || variable == null)
+            if (variable == null)
                 return 0;
 
-            var value = plc.Read(variable.Key);
-            return int.Parse(value?.ToString() ?? "0");
+            Parse(variable.Key, out var dataType, out var dbNumber, out var varType, out var address, out var bitNumber);
+            if (varType == VarType.DWord)
+            {
+                var value = S7.Net.Types.DWord.FromByteArray(currentDataBlock.Take(new Range(address, address + 4)).ToArray());
+                return (int)value;
+            }
+            else if (varType == VarType.Word)
+            {
+                var value = S7.Net.Types.Word.FromByteArray(currentDataBlock.Take(new Range(address, address + 2)).ToArray());
+                return value;
+            }
+            return 0;
         }
 
         private bool ReadPLCBool(string name)
         {
             var variable = ConfigHelper.FindVariable(name);
-            if (plc == null || variable == null)
+            if (variable == null)
                 return false;
 
-            var value = plc.Read(variable.Key);
-            return value?.ToString()?.ToLower() == "true";
+            Parse(variable.Key, out _, out _, out _, out var address, out var bitNumber);
+            var value = S7.Net.Types.Boolean.GetValue(currentDataBlock[address], bitNumber);
+            return value;
         }
 
         private void uploadTimer_Tick(object sender, EventArgs e)
@@ -216,7 +238,7 @@ namespace xicheji
             plc = new Plc(config.PLCType, config.PLCIP, int.Parse(config.PLCPort), 0, 1);
             plc.Open();
 
-            if (plc == null || !plc.IsConnected)
+            if (!plc.IsConnected)
             {
                 MessageBox.Show("PLC连接失败!");
                 return;
@@ -251,5 +273,169 @@ namespace xicheji
                 this.Text = now.ToString();
             });
         }
+
+
+        public static void Parse(string input, out DataType dataType, out int dbNumber, out VarType varType, out int address, out int bitNumber)
+        {
+            bitNumber = -1;
+            dbNumber = 0;
+
+            switch (input.Substring(0, 2))
+            {
+                case "DB":
+                    string[] strings = input.Split(new char[] { '.' });
+                    if (strings.Length < 2)
+                        throw new InvalidAddressException("To few periods for DB address");
+
+                    dataType = DataType.DataBlock;
+                    dbNumber = int.Parse(strings[0].Substring(2));
+                    address = int.Parse(strings[1].Substring(3));
+
+                    string dbType = strings[1].Substring(0, 3);
+                    switch (dbType)
+                    {
+                        case "DBB":
+                            varType = VarType.Byte;
+                            return;
+                        case "DBW":
+                            varType = VarType.Word;
+                            return;
+                        case "DBD":
+                            varType = VarType.DWord;
+                            return;
+                        case "DBX":
+                            bitNumber = int.Parse(strings[2]);
+                            if (bitNumber > 7)
+                                throw new InvalidAddressException("Bit can only be 0-7");
+                            varType = VarType.Bit;
+                            return;
+                        default:
+                            throw new InvalidAddressException();
+                    }
+                case "IB":
+                case "EB":
+                    // Input byte
+                    dataType = DataType.Input;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.Byte;
+                    return;
+                case "IW":
+                case "EW":
+                    // Input word
+                    dataType = DataType.Input;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.Word;
+                    return;
+                case "ID":
+                case "ED":
+                    // Input double-word
+                    dataType = DataType.Input;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.DWord;
+                    return;
+                case "QB":
+                case "AB":
+                case "OB":
+                    // Output byte
+                    dataType = DataType.Output;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.Byte;
+                    return;
+                case "QW":
+                case "AW":
+                case "OW":
+                    // Output word
+                    dataType = DataType.Output;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.Word;
+                    return;
+                case "QD":
+                case "AD":
+                case "OD":
+                    // Output double-word
+                    dataType = DataType.Output;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.DWord;
+                    return;
+                case "MB":
+                    // Memory byte
+                    dataType = DataType.Memory;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.Byte;
+                    return;
+                case "MW":
+                    // Memory word
+                    dataType = DataType.Memory;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.Word;
+                    return;
+                case "MD":
+                    // Memory double-word
+                    dataType = DataType.Memory;
+                    dbNumber = 0;
+                    address = int.Parse(input.Substring(2));
+                    varType = VarType.DWord;
+                    return;
+                default:
+                    switch (input.Substring(0, 1))
+                    {
+                        case "E":
+                        case "I":
+                            // Input
+                            dataType = DataType.Input;
+                            varType = VarType.Bit;
+                            break;
+                        case "Q":
+                        case "A":
+                        case "O":
+                            // Output
+                            dataType = DataType.Output;
+                            varType = VarType.Bit;
+                            break;
+                        case "M":
+                            // Memory
+                            dataType = DataType.Memory;
+                            varType = VarType.Bit;
+                            break;
+                        case "T":
+                            // Timer
+                            dataType = DataType.Timer;
+                            dbNumber = 0;
+                            address = int.Parse(input.Substring(1));
+                            varType = VarType.Timer;
+                            return;
+                        case "Z":
+                        case "C":
+                            // Counter
+                            dataType = DataType.Counter;
+                            dbNumber = 0;
+                            address = int.Parse(input.Substring(1));
+                            varType = VarType.Counter;
+                            return;
+                        default:
+                            throw new InvalidAddressException(string.Format("{0} is not a valid address", input.Substring(0, 1)));
+                    }
+
+                    string txt2 = input.Substring(1);
+                    if (txt2.IndexOf(".") == -1)
+                        throw new InvalidAddressException("To few periods for DB address");
+
+                    address = int.Parse(txt2.Substring(0, txt2.IndexOf(".")));
+                    bitNumber = int.Parse(txt2.Substring(txt2.IndexOf(".") + 1));
+                    if (bitNumber > 7)
+                        throw new InvalidAddressException("Bit can only be 0-7");
+                    return;
+            }
+        }
+
     }
+
 }