1

I try to read data from datablock (DB60), but I get only ?5. So in data block should be JAMES17.

private void button1_Click(object sender, EventArgs e)
      {
            if (button1.Text == "Connect PLC")
            {
                button1.Text = "Disconnect PLC";
                ClassPLCS7Client.PLCClientConnect_Result ConnectResult = new 
ClassPLCS7Client.PLCClientConnect_Result();
                ConnectResult = PLCClient.Connect(("192.168.0.2"), 0, 1);

               if (ConnectResult.State == ClassPLCS7Client.PLCClientConnectState.Connected)
            {
                this.label1.Text = "Connected PLC1 " + ConnectResult.ReSultString;
                label1.ForeColor = Color.Green;
                ClassPLCS7Client.ReadDataBlockString_Result read = new ClassPLCS7Client.ReadDataBlockString_Result();
                read = PLCClient.ReadDataBlockString(60, 0, 7);       
                this.textBox1.Text = read.DataValue[0];
                //this.textBox1.Text = arr4[];// read.ReSultString;
            }
            else
            {
                this.label1.Text = "Fail " + ConnectResult.ReSultString;

                label1.ForeColor = Color.Red;
            }

        }
        else
        {
            button1.Text = "Connect PLC";
            disconnect_plc();
            this.label1.Text = "Disconnect";
            label1.ForeColor = Color.Black;
        }

    }<code>
ZF007
  • 3,708
  • 8
  • 29
  • 48
James Cass
  • 13
  • 1
  • 5
  • I'd never heard of S7.net until I saw this question but are you unchecking 'Optimized block access' in the DB properties? – Deolus Aug 22 '17 at 14:00
  • Yes, i unchecking the optimized block already. – James Cass Aug 22 '17 at 15:03
  • Ah, I see what you have done. You have defined each character as a string. A string defaults to 255 chars long. So you just need one entry `String "JAMES17"`. I think you can even define the string with a length so it would be `String[7] "JAMES17"`. I'm not at work so I'm not sure. – Deolus Aug 22 '17 at 15:14
  • I get this "?J?A?M?E?S?1?7" . Almost correct so i have no idea what is wrong. Help me pls. – James Cass Aug 23 '17 at 04:01
  • @JamesCass - It sounds like you're reading the string as a single byte per char character set when it is a double byte, for example UTF-7 instead of Unicode. – Enigmativity Aug 23 '17 at 04:20
  • https://www.dropbox.com/s/reqa2t4ps7kh91e/3.PNG?dl=1 It still get worng word. T^T – James Cass Aug 23 '17 at 04:52
  • https://www.dropbox.com/s/xx7d0tq5045gwv8/4.PNG?dl=1 I should get this word. "James17" is not "JAMES17" – James Cass Aug 23 '17 at 05:03

2 Answers2

0

From i try to change DB60 to string "JAMES17" the result is

https://www.dropbox.com/s/awdadp53tuyszpe/2.PNG?dl=1

I found this code in the class ReadDataBlockString_Result. So i call this function and not sure how to use it.

public ReadDataBlockString_Result ReadDataBlockString(int DataBlockNumber, 
int StartAddress, int LenghtOfRead)
        {
            ReadDataBlockString_Result rt = new ReadDataBlockString_Result();
            rt.MemoryByte = new byte[256];


            //if (this.State == PLCClientConnectState.Connected)
            //{

                rt.DataValue = new string[LenghtOfRead];
                int i = 0;
                int CaptureIndex = StartAddress;
                for (i = 0; i <= LenghtOfRead - 1; i++)
                {
                    rt.ResultCode = PLCClient.DBRead(DataBlockNumber, CaptureIndex, 256, rt.MemoryByte);
                    CaptureIndex = CaptureIndex + 256;

                    if (rt.ResultCode == 0)
                    {
                        string Convertedvalue = null;
                        Convertedvalue = System.Text.Encoding.ASCII.GetString(rt.MemoryByte);
                        rt.DataValue[i] = Convertedvalue;
                    }


                }

            //}
            //else
            //{
            //    rt.ResultCode = -1;
            //}

            rt.ReSultString = PLCClient.ErrorText(rt.ResultCode);

            return rt;
        }
James Cass
  • 13
  • 1
  • 5
  • I don't think that will work as it is just reading single bytes then converting them to ASCII. You need to read the whole string in one go then convert it. Which reference package are you using? (S7NetPlus, ezPLC_S7, ITools.Siemens or something else?) Although I will be limited in how much I can help you as I don't have C# at work. – Deolus Aug 23 '17 at 04:57
  • Ok, you are already using `ReadDataBlockString` in your original post. You just need to change the parameters to `ReadDataBlockString(60, 0 , 1)` assuming your string is the first entry in DB60 (`data1 STRING 0.0 "JAMES17"`). If this doesn't solve anything, then I'm not sure what to suggest. – Deolus Aug 23 '17 at 05:38
  • oh Thanks, i just change the data in plc to be char can solve it. – James Cass Aug 23 '17 at 09:14
0

First : you are putting J string in byte offset 0 and A string in byte offset 256 and M string in byte offset 512 etcetera .... you don't have a string in consecutive bytes as it should be.

Second: when S7 stores a string the two first bytes are reserved to store the first the max string size in bytes and the second the actual size of string. Therefore in your case your memory must contain this: (Assuming the reserved memory is 256 bytes size)

offset 0 == 254, offset 1 == 7, offset 2 to 8 == 'JAMES17'

from56
  • 3,976
  • 2
  • 13
  • 23