S7NetPlus / s7netplus

S7.NET+ -- A .NET library to connect to Siemens Step7 devices
MIT License
1.29k stars 577 forks source link

Addressing Mechanism for Logo PLCs #260

Closed noumanqaiser closed 4 years ago

noumanqaiser commented 4 years ago

Hello, I want to use S7.Net to read write data from a Siemens LOGO OBA8 PLC. I understood that S7.Net can be used to read/write data from Logo PLCs and the following Gist gives an great example of how this is to be done:

https://gist.github.com/mycroes/9bdc7cffdef08943edea1918812706a6

The only question the gist doesn't answer is how to determine datablock number and addresses for variables in Logo. Any replies on this would be appreciated.

noumanqaiser commented 4 years ago

I was researching on the problem above since some time and found the answer, sharing here so other can benefit. Logos Donot have datablock concept like other S7 PLCs and hence you can use whatever data block number when connecting to the logo PLC( so I use DB 0). Each logo has a VM addressing table which tells address range for most common memory variables.

(The document attached is an extract from Logo Soft Comfort Help material that explains the addressing scheme,

logo vm mapping.pdf

I used the address space for M flags. So bits M1 to M8 are situated at byte 1104 in the the memory space. So lets say you want to change M1 flag to TRUE, you would modify 1104.0 to a specific value. Within the Logo program you can then use the M flag for other logic, like modifying an output etc.

The following code allows you to read from Logo 0ba8 inputs(address 1024) and writing to M variables(address 1104).

Hope this helps everyone dealing with logo PLCs.

@mycroes Maybe it could be good to add this explanation to s7.net documentation to allow people to comfortably talk to logo PLCs which are pretty good for low cost projects with low IO needs.

` public Form1() { InitializeComponent(); string faultCode = ""; ModifyLogoOutput("85.70.4.142", 4, true,out faultCode);

        ModifyLogoOutput("85.70.4.142", 4, false, out faultCode);

    }

    public bool ModifyLogoOutput(string IPAddress, int outputnumber, bool Setvalue, out string message)
    {

        message = "Success";
        bool success = false;
        outputnumber--; //the bit address is one less then the actual number marked on the plc

        if (outputnumber >= 0 && outputnumber <= 5)
        {
            try
            {
                var plc = new Plc(CpuType.Logo0BA8, IPAddress, 0, 0);

                plc.Open();

                int registerAdd = 1104; //for modifying m0 to m5 values

                plc.WriteBit(DataType.DataBlock, 0, registerAdd, outputnumber, Setvalue);

                //checking if successfully written

                byte result = (byte)plc.Read(DataType.DataBlock, 0, 1064, VarType.Byte, 1); //just reading 1 byte from the result
                bool readValue = result.SelectBit(outputnumber);
                if (readValue == Setvalue)
                {
                    success = true;
                    message = "SUCCESS: Feedback Verified";
                }

            }
            catch (Exception ex)
            {
                message = "ERROR: " + ex.ToString();

            }
        }
        else message = "ERROR: invalid ouput number provided";

        return success;
    }

    public bool ReadLogoInput(string IPAddress, int InputNumber, out string message)
    {

        message = "Success";
        bool success = false;
        bool readValue = false;
        InputNumber--; //the bit address is one less then the actual number marked on the plc

        if (InputNumber >= 0 && InputNumber <= 5)
        {
            try
            {
                var plc = new Plc(CpuType.Logo0BA8, IPAddress, 0, 0);

                plc.Open();

                int registerAdd = 1106; //for reading m17 to m5 values

                byte result = (byte)plc.Read(DataType.DataBlock, 0, registerAdd, VarType.Byte, 1); //just reading 1 byte from the M17 onward register
                readValue = result.SelectBit(InputNumber);
                success = true;
                message = "SUCCESS: Value Read from Memory";

            }
            catch (Exception ex)
            {
                message = "ERROR: " + ex.ToString();

            }
        }
        else message = "ERROR: invalid ouput number provided";

        return readValue;
    }

`

noumanqaiser commented 4 years ago

Solution works