takahiro_takahiro
@takahiro_takahiro

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Modbus通信 配列処理について

Modbus TCP通信を使って相手PLCに書かれているデータを読み出しフォーム上に表示するソフトウェアを作成しています。
コード後半の★部にて,PLCから読みだしたデータをint型の配列へ格納してCSVファイルへ出力しています。
ただ現状のプログラムだと整数しか扱えないため,小数点も扱えるようdouble型の配列に格納したいのですが,方法がわかりません。
Array.ConvertAllも試してみましたが,イマイチ使い方がわからずエラー解消できませんでした。

どなかた記述方法を教えていただけないでしょうか?
よろしくお願いいたします。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EasyModbus;
using Csv;
using System.IO;
using System.Net.NetworkInformation;
using System.Net.Http.Headers;

namespace ModbusCommunication
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string FileTime;
        string FileName;
        string LogTime;
        double Loop;

        public void btnStart1_Click(object sender, EventArgs e) 
        {
            timer1.Start();
            btnStart1.BackColor = Color.Lime;
            btnStop1.BackColor = Color.White;
            btnStart1.Enabled = false;          //スタートボタンの操作不可
            //ModbusCommEX();
            FileTime = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss");
            FileName = FileTime + ".csv";
            using (StreamWriter header = new StreamWriter(@"C:\20221213テスト\" + FileName, true, Encoding.GetEncoding("Shift_JIS")))
            {
                header.WriteLine("時刻,データ1,データ2,データ3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," +
                    ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,");          //ヘッダを出力
            }
            string LoopDateSize = numDataSize1.Text;
            Loop = Math.Ceiling(double.Parse(LoopDateSize) / 100);  //ループ回数の計算
        }
        public void btnStop1_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            btnStart1.BackColor = Color.White;
            btnStop1.BackColor = Color.Lime;
            btnStart1.Enabled = true;       //スタートボタン操作OK
            MessageBox.Show("計測終了");
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        public void timer1_Tick(object sender, EventArgs e)
        {
            ModbusComm();                                                         //タイマーがカウントするごとに"ModbusComm"を起動
            string DSPTime = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss");        //フォーム上の時刻を1秒ごとに更新
            labelTime1.Text = "時刻:" + DSPTime;
        }

        public void ModbusComm()
        {
            ModbusClient modbusClient = new ModbusClient("192.168.1.128", 502);    //Ip-Address and Port of Modbus-TCP-Server
            modbusClient.Connect();

            //ログタイムの取得
            LogTime = DateTime.Now.ToString("HH:mm:ss:fff");


            //入力された「データサイズ(データ個数)」を文字列⇒整数型へ変換
            string newDataSize = numDataSize1.Text;
            int NewDataSize = int.Parse(newDataSize);

            //入力された「アドレス」を文字列⇒整数型へ変換
            string newAddress = numAddress1.Text;
            int NewAddress = int.Parse(newAddress);

            //入力された「係数1」を文字列⇒整数型へ変換
            string newConvFactor1 = ConvFactor1.Text;
            int NewConvFactor1 = int.Parse(newConvFactor1);

            //入力された「係数2」を文字列⇒整数型へ変換
            string newConvFactor2 = ConvFactor2.Text;
            int NewConvFactor2 = int.Parse(newConvFactor2);

            //入力された「係数3」を文字列⇒整数型へ変換
            string newConvFactor3 = ConvFactor3.Text;
            int NewConvFactor3 = int.Parse(newConvFactor3);

            //入力された「オフセット1」を文字列⇒整数型へ変換
            string newOffSet1 = OffSet1.Text;
            int NewOffSet1 = int.Parse(newOffSet1);

            //入力された「オフセット2」を文字列⇒整数型へ変換
            string newOffSet2 = OffSet2.Text;
            int NewOffSet2 = int.Parse(newOffSet2);

            //入力された「オフセット3」を文字列⇒整数型へ変換
            string newOffSet3 = OffSet3.Text;
            int NewOffSet3 = int.Parse(newOffSet3);

            //入力された「データサイズ」と「アドレス」をもとにPLCから
            //データを読み出し”readHoldingRegisters”へ格納

            //string LineText= "";
            int MaxDateSize = 100;
            int L = 0;
            while (L < Loop)
            {
                if (L == 0)
                {
                int[] readHoldingRegisters = modbusClient.ReadHoldingRegisters(NewAddress, MaxDateSize); //★
                int[] NewConvFactor = new int[MaxDateSize];// { NewConvFactor1, NewConvFactor2, NewConvFactor3 };//★
                int[] NewOffSet = new int[MaxDateSize];// { NewOffSet1, NewOffSet2, NewOffSet3 }; //★
                NewConvFactor[0] = NewConvFactor1;
                NewConvFactor[1] = NewConvFactor2;
                NewConvFactor[2] = NewConvFactor3;

               
                    for (int a = 0; a < MaxDateSize; ++a)
                    {
                        readHoldingRegisters[a] = readHoldingRegisters[a] * NewConvFactor[a] + NewOffSet[a];                  //配列0番目を工業値変換
                                                                                                                              //readHoldingRegisters[1] = readHoldingRegisters[1] * NewConvFactor2 + NewOffSet2;                  //配列1番目を工業値変換
                                                                                                                              //readHoldingRegisters[2] = readHoldingRegisters[2] * NewConvFactor3 + NewOffSet3;                  //配列2番目を工業値変換
                    }
                    boxText1.Text = String.Join(" , ", readHoldingRegisters);
                }
                else if(L==1)
                {
                    int[] readHoldingRegisters = modbusClient.ReadHoldingRegisters(NewAddress, NewDataSize-MaxDateSize);
                    int[] NewConvFactor = new int[MaxDateSize];// { NewConvFactor1, NewConvFactor2, NewConvFactor3 };
                    int[] NewOffSet = new int[MaxDateSize];// { NewOffSet1, NewOffSet2, NewOffSet3 };
                    NewConvFactor[0] = 1;
                    NewConvFactor[1] = 1;
                    NewConvFactor[2] = 13;
                    NewConvFactor[49] = 1;

                    for (int a = 0; a < NewDataSize - MaxDateSize; ++a)
                    {
                        readHoldingRegisters[a] = readHoldingRegisters[a] * NewConvFactor[a] + NewOffSet[a];                  
                                                                                                                                              
                                                                                                                                               
                    }
                    boxText2.Text = String.Join(" , ", readHoldingRegisters);
                }
                L++;
                NewAddress = NewAddress + 100;
            }

            //配列の中身を一気に表示
            using (StreamWriter sw = new StreamWriter(@"C:\20221213テスト\" + FileName, true, Encoding.GetEncoding("Shift_JIS")))
                {
                    sw.WriteLine(LogTime +","+boxText1.Text+","+boxText2.Text);
                }
            modbusClient.Disconnect();                                                //Disconnect from Server

        }
    }
}

image.png

↑通信設定と結果表示画面

0

1Answer

Modbusのライブラリのサンプル・ドキュメント等が存在するなら、
それらを読むのが一番早い気はしますが。
まずは入手元・提供元のWebサイトを確認してみてはどうでしょう。

0Like

Comments

  1. 提供元のwebサイトを調べてみたところ,int型しか扱えないようでした。
    double型への変換は別の方法を考えてみようと思います。

Your answer might help someone💌