Question about TCP Modbus Master Trigger

Roy444
2017-10-08
2017-10-09
  • Roy444 - 2017-10-08

    Hi all,

    I'll first describe the goal:
    1. Have an outside device write into a variable of codesys.
    2. Detect the variable in (1) has been changed.
    3. After detection, make the modbus master write to another device via trigger.

    what I've tried to do:
    make a stuct with:
    LastValue : BOOL; //linked to the another device in (3)
    CurrentValue : BOOL; //linked to the outside device in (1)
    Trigger : BOOL; //linked to the modbus master trigger

    now i got a task where I do the following:
    Trigger := FALSE;
    IF (CurrentValue <> LastValue) THEN
    LastValue := CurrentValue;
    Trigger := TRUE;
    END_IF

    When i ran this code, the trigger didn't work as planned, meaning the modbus master didn't update me about the change.
    i mainly suspect about the syncing of the tasks, one task runs the code above controlling the trigger and another task runs the modbus master module who checks the trigger rising edge and performs the writing action.

    Questions:
    1. how would you sync between the two tasks? how to control the trigger properly?
    2. What type of scheduler protocol is being used, might help me understand the problem.

    Thanks in advance for any help
    Roy.

     
  • josepmariarams - 2017-10-08

    Reset the trigger in the other task.

     
  • Roy444 - 2017-10-09

    after linking code program and the modbus module to the same task
    and also found a bug i had with the program, the trigger worked well!

    no need for different tasks.

    adding the code i ran with:

    TYPE Modbus_Data :
    STRUCT
    Old:ARRAY[0..15] OF BOOL := [16(FALSE)];
    New:ARRAY[0..15] OF BOOL := [16(FALSE)];
    Trigger:BOOL := FALSE;
    END_STRUCT
    END_TYPE

    arrModbusData: ARRAY[0..1] OF Modbus_Data;

    PROGRAM Modbus_programm
    VAR
    wordIndex : UINT;
    bitIndex : UINT;
    isTriggerNeeded : BOOL;
    modbusDataArrayLength : int := SIZEOF(arrModbusData)/SIZEOF(Modbus_Data);
    END_VAR
    VAR CONSTANT
    NUMBER_OF_BITS_IN_WORD : INT := 16;
    END_VAR


    isTriggerNeeded := FALSE;
    FOR wordIndex:=0 TO modbusDataArrayLength -1 DO
    arrModbusData[wordIndex].Trigger := FALSE;
    FOR bitIndex:=0 TO NUMBER_OF_BITS_IN_WORD - 1 DO
    IF(arrModbusData[wordIndex].New[bitIndex] <> arrModbusData[wordIndex].Old[bitIndex]) THEN
    arrModbusData[wordIndex].Old[bitIndex] := arrModbusData[wordIndex].New[bitIndex];
    isTriggerNeeded := TRUE;
    END_IF;
    END_FOR;
    IF(isTriggerNeeded = TRUE) THEN
    arrModbusData[wordIndex].Trigger := TRUE;
    END_IF;
    END_FOR;

     

Log in to post a comment.