Search code examples
pythonplcsnap7

snap7 - read_area for similar addressed variables


I am working right now with a PLC from Siemens and my task now is to implement some actions on python with it. For it I am using snap7 to read and write values. I am still fairly new in this topic, so a question arose (from watching a video and reading the documentation of the package).

I defined in TIA portal a couple of tags: %MD0 containing a real value, %MW0 containing also a real and %QW0 as an analog output (int).

I need to read the values of %MD0 and %MW0. The function I want to use is read_area, which has the following arguments:

  • area: area to be read from.
  • dbnumber: number of the db to be read from. In case of Inputs, Marks or Outputs, this should be equal to 0.
  • start: byte index to start reading.
  • size: number of bytes to read.

The problem I have is, when reading the values of both %MD0 and %MW0, how can I be sure, which one am I reading? Since the arguments would be virtually the same:

read_area(snap7.types.Areas.MK, 0, 0, 2)

Has somebody already figured this out? Or the best thing would be to use different numbers for the tags to avoid confusion, i.e. %MD0, %MW1, %QW3 and so on...?

I have been trying with a very simple code and the PLC emulation included in TIA portal. Still can not find a way to tell which tag am I reading from.


Solution

  • There is a little confusion from your side, you are trying to read overlapped memory areas, so when you define %MDO you are defining a double Word that means 4 bytes and when you define %MW0 you are defining a Word that means 2 bytes.

    Lets say you have in %MD0 4 characters because 1 char = 1 Byte

    %MD0[0] = 16#30;
    %MD0[1] = 16#31;
    %MD0[2] = 16#32;
    %MD0[3] = 16#33;
    

    so if you try to read %MW0, which length is 2 Bytes, you will have the following result:

    %MW0[0] = 16#30;
    %MW0[1] = 16#31;
    

    So according to your example the only way to identify which memory area you are reading is to remember which length you defined in you read_area function.

    In fact you are wrong trying to read the memory areas with the same parameters, in order to read %MD0 you have to call the read_area function with the following parameters:

    read_area(snap7.types.Areas.MK, 0, 0, 4)
    

    And in order to read the %MW0 you need to use the following parameters:

    read_area(snap7.types.Areas.MK, 0, 0, 2)
    

    So with that been said if you give the length = 4 you are reading the %MD0and if the length = 2 you are reading %MW0.