/// <summary> /// ロードされたXMLデータから該当する、 ///WorkID_Type, GroupCode, Workidを持つデータを取得し、MemAllocStruct型の値を返します。 ///指定されたエントリが存在しない場合は、例外が発生します。 ///ファイルがロードされていない状態で、この関数を呼び出した場合は、例外が発生します。 /// </summary> /// <param name="Type"></param> /// <param name="GroupCode"></param> /// <param name="WorkID"></param> /// <returns></returns> public MemAllocStruct GetEntry(int Type, int WorkID) { MemAllocStruct memallocstruct = new MemAllocStruct(); int GroupCode = 0; int ID = 0; WorkIDSampler(WorkID, ref GroupCode, ref ID); // XMLファイルを読む var nodes = from n in xmlAccessor.document.Descendants("workid_type") where n.Attribute("type").Value == Type.ToString() select n; nodes = from n in nodes.Descendants("group") where n.Attribute("code").Value == GroupCode.ToString() select n; nodes = from n in nodes.Descendants("workid") where n.Attribute("id").Value == "0x" + WorkID.ToString("X4") orderby n.Attribute("id") select n; // 見つかったノードが1でなければエラーを返す。 if (nodes.Count() != 1) { //例外発生 throw new MemoryAllocationDataException(); } var work = nodes.First(); memallocstruct.WorkIdType = Type; memallocstruct.GroupCode = GroupCode; memallocstruct.WorkID = ID; memallocstruct.SortNo = Int32.Parse(work.Attribute("sortno").Value); memallocstruct.Address = Convert.ToInt32(work.Attribute("address").Value, 16); memallocstruct.DoubleWord = Int32.Parse(work.Attribute("double_word").Value); memallocstruct.ValueFactor = Int32.Parse(work.Attribute("value_factor").Value); memallocstruct.BankStore = System.Convert.ToBoolean(Int32.Parse(work.Attribute("bank_store").Value)); memallocstruct.MinLimit = double.Parse(work.Attribute("min_limit").Value); memallocstruct.MaxLimit = double.Parse(work.Attribute("max_limit").Value); memallocstruct.DefaultValue = double.Parse(work.Attribute("default_value").Value); memallocstruct.Unit = work.Attribute("unit").Value; memallocstruct.address_special = Int32.Parse(work.Attribute("address_special").Value); memallocstruct.Comment = work.Attribute("comment").Value; /* 学習データ機能 (旧データベース機能) * Alchemist初期出荷バージョンと互換性維持の為に、memallocで任意扱いにしている為、無い場合もある為 */ if (work.Attribute("learn_key_code") != null) memallocstruct.learn_key_code = Int32.Parse(work.Attribute("learn_key_code").Value); else memallocstruct.learn_key_code = 0; return memallocstruct; }
/// <summary> /// MemReadで読み込んだWorkDataをdoubleに変換します。 /// </summary> /// <param name="Alloc"></param> /// <param name="WorkData"></param> /// <param name="result"></param> public static double ConvertWorkDataToDouble(MemAllocStruct Alloc, int[] WorkData) { // 16bitの場合 if (Alloc.DoubleWord == 0) { return Convert.ToDouble((short)WorkData[0]) / Convert.ToDouble(Alloc.ValueFactor); } // 32bitの場合 else { byte[] bytes1 = BitConverter.GetBytes(WorkData[0]); byte[] bytes2 = BitConverter.GetBytes(WorkData[1]); int ret = BitConverter.ToInt32(new byte[] { bytes1[0], bytes1[1], bytes2[0], bytes2[1] }, 0); return Convert.ToDouble(ret) / Convert.ToDouble(Alloc.ValueFactor); } }
/// <summary> /// WorkDataをMemWriteに渡せる整数値の配列に変換します。 /// </summary> /// <param name="Alloc">メモリ割当データの構造体を指定します。</param> /// <param name="WorkData">加工値、補正値、タイミング値等を指定します。</param> /// <param name="result">結果を返却します。</param> public static void ConvertWokdDataToInt(MemAllocStruct Alloc, double WorkData, out int[] result) { // 16bitの場合 if (Alloc.DoubleWord == 0) { result = new int[1]; // ValueFactor計算する result[0] = Convert.ToInt32(WorkData * Alloc.ValueFactor); } // 32bitの場合 else { result = new int[2]; // ValueFactor計算する int temp = Convert.ToInt32(WorkData * Alloc.ValueFactor); // byteデータに分割する byte[] bytes = BitConverter.GetBytes(temp); result[0] = BitConverter.ToInt16(new byte[] { bytes[0], bytes[1] }, 0); result[1] = BitConverter.ToInt16(new byte[] { bytes[2], bytes[3] }, 0); } }
/// <summary> /// 加工値メモリから取得したデータをBankDataに入れて返す /// </summary> /// <param name="BankData"></param> public int GetArray(ref BankDataStruct[] BankData) { int i = 0; MemAllocStruct memAllocStruct = null; int[] btnWorkID = new int[0]; // BankDataがnullだった場合構造体を割り当てる if (BankData == null) { BankData = new BankDataStruct[0]; } foreach (WorkDataStruct bankdata in map.Values) { if (bankdata.Type == SystemConstants.WORKMEM_TYPE_WORKDATA) { // work idのメモリ割当データを取得する try { // メモリ割当データを使用し、WorkIDに対応する共有メモリのアドレスを取得 memAllocStruct = memAllocData.GetEntry(SystemConstants.WORKID_TYPE_WORKDATA, bankdata.WorkID); } // WorkIDがメモリ割当データに存在していない場合 catch (MemoryAllocationDataException) { // データがあるものとして処理する memAllocStruct = new MemAllocStruct(); memAllocStruct.BankStore = true; } // bank_storeが保存対象だった場合 if (memAllocStruct.BankStore == true) { // 配列の要素を1つ増やす Array.Resize(ref BankData, BankData.Length + 1); // BankDataに加工値メモリの値を設定 BankData[i].Type = bankdata.Type; BankData[i].ID = bankdata.WorkID; BankData[i].value = bankdata.Value; i++; } } else { // ボタンIDのバンク保存対象を取得 ButtonActionStruct btnBankStore = new ButtonActionStruct(); try { btnBankStore = buttonControl.Get(bankdata.WorkID); } catch { btnBankStore.BankStore = SystemConstants.BTN_BANK_UNSAVED; } if (btnBankStore.BankStore == SystemConstants.BTN_BANK_SAVED) { // 配列の要素を1つ増やす Array.Resize(ref BankData, BankData.Length + 1); // BankDataに加工値メモリの値を設定 BankData[i].Type = bankdata.Type; BankData[i].ID = bankdata.WorkID; BankData[i].value = bankdata.Value; i++; } } } return SystemConstants.DCPF_SUCCESS; }
/// <summary> /// 加工値メモリから取得したデータをLearnDataに入れて返す /// </summary> /// <param name="LearnData"></param> /// <returns></returns> public int GetArray(ref LearnDataStruct[] LearnData) { int i = 0; MemAllocStruct memAllocStruct = null; // LearnDataがnullの場合、構造体を割当てる if (LearnData == null) LearnData = new LearnDataStruct[0]; foreach (WorkDataStruct learndata in map.Values) { if (learndata.Type == SystemConstants.WORKMEM_TYPE_WORKDATA) { // WorkIDのメモリ割当データを取得する try { memAllocStruct = memAllocData.GetEntry(SystemConstants.WORKID_TYPE_WORKDATA, learndata.WorkID); } catch (MemoryAllocationDataException) { memAllocStruct = new MemAllocStruct(); memAllocStruct.learn_key_code = SystemConstants.DB_GROUP_SEARCH_TYPE_NONE; } // 学習データ対象の場合 if (LearnDataStorage.IsLearnSearchKeyCode(memAllocStruct.learn_key_code)) { // 配列を一つ増やす Array.Resize(ref LearnData, LearnData.Length + 1); // LearnDataに加工値メモリの値を設定 LearnData[i].Type = learndata.Type; LearnData[i].SearchType = memAllocStruct.learn_key_code; LearnData[i].ID = learndata.WorkID; LearnData[i].value = learndata.Value; i++; } } else if (learndata.Type == SystemConstants.WORKMEM_TYPE_WORKBTN) { // ボタンIDの学習データ保存対象を取得 ButtonActionStruct btnLearnStore = new ButtonActionStruct(); try { btnLearnStore = buttonControl.Get(learndata.WorkID); } catch { btnLearnStore.SearchType = SystemConstants.DB_GROUP_SEARCH_TYPE_BTN; } if(btnLearnStore.SearchType != SystemConstants.DB_GROUP_SEARCH_TYPE_BTN) { // 配列の要素を1つ増やす Array.Resize(ref LearnData, LearnData.Length + 1); // LearnDataにデータを追加 LearnData[i].Type = learndata.Type; LearnData[i].SearchType = btnLearnStore.SearchType; LearnData[i].ID = learndata.WorkID; LearnData[i].value = learndata.Value; i++; } /* // 動作処理ボタンの場合 if (LearnDataStorage.IsLearnedModeBtn(learndata.WorkID)) { // 配列の要素を1つ増やす Array.Resize(ref LearnData, LearnData.Length + 1); // LearnDataにデータを追加 LearnData[i].Type = learndata.Type; LearnData[i].SearchType = SystemConstants.DB_GROUP_SEARCH_TYPE_BTN; LearnData[i].ID = learndata.WorkID; LearnData[i].value = learndata.Value; i++; } */ } } return SystemConstants.DCPF_SUCCESS; }
/// <summary> /// 共有メモリへ書き込む /// </summary> /// <param name="memAllocStruct"></param> /// <param name="WorkData"></param> /// <returns></returns> private int WriteMemory(MemAllocStruct memAllocStruct, double WorkData) { int result = 0; int[] num = null; // WorkDataを適切な形(整数値等)に変換 Utility.ConvertWokdDataToInt(memAllocStruct, WorkData, out num); // 通信クラスのMemWriteを使用して書込みます。 //16ビットの場合 if (memAllocStruct.DoubleWord == 0) { result = machineConnector.MemWrite(memAllocStruct.Address, num[0]); } //32ビットの場合 else { for (int i = 0; i < 2; i++) { result = machineConnector.MemWrite(memAllocStruct.Address + i, num[i]); if (result != SystemConstants.MCPF_SUCCESS) { break; } } } // 異常の場合 if (result != SystemConstants.MCPF_SUCCESS) { return result; } //機械側に送信 result = machineConnector.MemSend(memAllocStruct.Address, memAllocStruct.DoubleWord + 1, false); if (result == SystemConstants.MCPF_SUCCESS) { // DCPF_SUCCESSを返します。 return SystemConstants.DCPF_SUCCESS; } else { return result; } }
/// <summary> /// 共有メモリを読み出す /// </summary> /// <param name="memAllocStruct"></param> /// <param name="WorkData"></param> /// <returns></returns> private int ReadMemory(MemAllocStruct memAllocStruct, out double WorkData) { int result = 0; int iWorkData = 0; int[] num = null; // メモリ割当データを使用し、WorkIDに対応する共有メモリのアドレスからMemReadを使用してデータを取得 //16ビットの場合 if (memAllocStruct.DoubleWord == 0) { num = new int[1]; result = MemRead(memAllocStruct.Address, ref iWorkData); num[0] = iWorkData; } //32ビットの場合 else { num = new int[2]; for (int i = 0; i < 2; i++) { result = MemRead(memAllocStruct.Address + i, ref iWorkData); if (result != SystemConstants.MCPF_SUCCESS) { break; } num[i] = iWorkData; } } // 正常に処理が行われた場合 if (result == SystemConstants.MCPF_SUCCESS) { // 適切な形に変換し、WorkDataに入れて返す WorkData = Utility.ConvertWorkDataToDouble(memAllocStruct, num); // DCPF_SUCCESSを返す return SystemConstants.DCPF_SUCCESS; } else { WorkData = 0; return result; } }
/// <summary> /// 切断長もしくは切断長閾値が変更されたことにより区分の変更があるかをチェックし、変更があればメモリ上の /// 電線送り速度・加速時間・切断長補正の値を更新する。 /// </summary> private void FeedAndWireLenCheck(int WorkID, double WorkData, MemAllocStruct memAllocStruct) { int WireFlagNow = 0; int WireFlagOld = 0; double dWireLength = 0.0; double dTHRESA = 0.0; double dTHRESB = 0.0; double FeedSpeed = 0.0; double FeedAccel = 0.0; double WireLengthCorrect = 0.0; //前回の切断長を取得する。 workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.WIRE_LENGTH1, ref dWireLength); //閾値Aを取得する workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_SPEED_THRES1, ref dTHRESA); //閾値Bを取得する workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_SPEED_THRES2, ref dTHRESB); //前回の区分を割り出す WireFlagOld = CheckDivision(dWireLength, dTHRESA, dTHRESB); //現在の区分を割り出す //切断長が変更された場合 if (WorkID == SystemConstants.WIRE_LENGTH1) { WireFlagNow = CheckDivision(WorkData, dTHRESA, dTHRESB); } //閾値Aが変更された場合 else if (WorkID == SystemConstants.FEED_SPEED_THRES1) { WireFlagNow = CheckDivision(dWireLength, WorkData, dTHRESB); } //閾値Bが変更された場合 else { WireFlagNow = CheckDivision(dWireLength, dTHRESA, WorkData); } //前回と状態が異なる場合 if (WireFlagNow != WireFlagOld) { switch (WireFlagNow) { case 1: //区分A workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_SPEED1, ref FeedSpeed); workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_ACCEL1, ref FeedAccel); workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.WIRE_LENGTH_CORRECT1, ref WireLengthCorrect); WriteWorkData(SystemConstants.FEED_SPEED1, FeedSpeed, true, true); WriteWorkData(SystemConstants.FEED_ACCEL1, FeedAccel, true, true); WriteWorkData(SystemConstants.WIRE_LENGTH_CORRECT1, WireLengthCorrect, true, true); break; case 2: //区分B workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_SPEED2, ref FeedSpeed); workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_ACCEL2, ref FeedAccel); workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.WIRE_LENGTH_CORRECT2, ref WireLengthCorrect); WriteWorkData(SystemConstants.FEED_SPEED2, FeedSpeed, true, true); WriteWorkData(SystemConstants.FEED_ACCEL2, FeedAccel, true, true); WriteWorkData(SystemConstants.WIRE_LENGTH_CORRECT2, WireLengthCorrect, true, true); break; case 3: //区分C workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_SPEED3, ref FeedSpeed); workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.FEED_ACCEL3, ref FeedAccel); workDataMemory.Get(SystemConstants.WORKMEM_TYPE_WORKDATA, SystemConstants.WIRE_LENGTH_CORRECT3, ref WireLengthCorrect); WriteWorkData(SystemConstants.FEED_SPEED3, FeedSpeed, true, true); WriteWorkData(SystemConstants.FEED_ACCEL3, FeedAccel, true, true); WriteWorkData(SystemConstants.WIRE_LENGTH_CORRECT3, WireLengthCorrect, true, true); break; } } }