some tags are not refreshing on DskDevice IO Device

Hi All,

I cant figure out why some tags doesnt refresh.

I am reading an ION meter via modbus tcp, and Total Power data is coming on 2 registers. So, in variable tags i have one for High Value Register and other tag for the Low Value register. and via cicode i make the calculation formula Value=High Value * 65536 + Low Value. I have other variable tag on DskDevice L15 named Value. but this isnot refreshing while on runtime. also if i make other text with the same expression tag "Value=High Value * 65536 + Low Value".

could someone help me please

  • How do you trigger your cicode function containing the formula? Just defining it is not enough, you need to call it periodically.
    To do this you could define an event that calls your function every second or something like that.
    Does your function update the disk tag correct if you call your function manually (from a button for example)?

    And if you use citect 2016 or higher, please take a look at Calculated Variables. This functionality could do exactly what you want, just by defining a Cicode I/O Decvice and filling in your formula in the address field of a variable tag.

    Regards,
    Patrick
  • Hi Patrick,
    Thank you for reply. I have this on my cicode file:
    FUNCTION MTR1_KW_C()
    WHILE 1 DO
    MTR1_KW_CALC = (MTR1_KW_H*65536 + MTR1_KW_L)/1;
    SleepMS(100);
    END
    END
    FUNCTION MTR1_MAIN_C()
    While 1 DO
    ErrSet(1); // Disable error checking, e.g.: divide by Zero
    MTR1_KW_C();
    ErrSet(0); // Re-enable error checking.
    SleepMS(100);
    END
    END
    Does your function update the disk tag correct if you call your function manually (from a button for example)?
    -i tried this ando doesnt update the disk tag

    And if you use citect 2016 or higher, please take a look at Calculated Variables. This functionality could do exactly what you want, just by defining a Cicode I/O Decvice and filling in your formula in the address field of a variable tag.
    -This is exactly what i need, but im using Citect 2015 7.50 SP1 Patch 29 [5] :(

    Thank you,
    Regards,
    Pavel Lopez
  • SetupEditor - DiskDrv -> UpDateTime -> 0. Maybe it will help.
  • Hi Pavel,

    Are you certain that your main function is running? Do you start it on startup of your application?
    You can configure a startup function in the Computer Setup Wizard.
    I suggest that you run these functions on the I/O server, because if you run them on the client you HAVE to be logged in to Citect to be able to write to the disk tag (security restriction on the client process).

    This might be the main problem now: not being logged in in Citect.

    Also, you should remove a WHILE 1 loop from one of your functions.
    Your main function is already running in an endless loop so it will start a new calculation function every 100ms.
    If you leave the WHILE 1 in your calculation function it will also never stop and thus every 100ms a new instance of this function will run in parallel of the existing one, creating a memory leak and other unpredictable behaviour.

    I suggest adjusting your functions like this:

    FUNCTION MTR1_KW_C()
    ErrSet(1); // Disable error checking, e.g.: divide by Zero
    MTR1_KW_CALC = MTR1_KW_H * 65536 + MTR1_KW_L;
    ErrSet(0); // Re-enable error checking.
    END

    FUNCTION MTR1_MAIN_C()
    ErrSet(1); // Disable error checking
    WHILE TRUE DO
    TaskNew("MTR1_KW_C", "", 8); // Call this function as a new task, but only if it does not run already
    SleepMS(100);
    END
    ErrSet(0); // Re-enable error checking.
    END

    Calling your calculation function with TaskNew() prevents running more than 1 instance of it, for example when your calculation takes longer than 100ms.

    Regards,
    Patrick
  • Hi,
    thank you for your comment. I also try that and doesn't work :S
  • Hi Patrick,
    Thank you for take your time to help me, I make what you suggest and still frozen values. but now I notice a strange behavior that you may help me, I think is easier.

    When I use this cicode, and I erase raw Zero scale, Raw Full Scale, Eng Zero Scale, Eng Full Scale on variables tags for "MTR1_KW_CALC":

    FUNCTION MTR1_KW_C()
    ErrSet(1); // Disable error checking, e.g.: divide by Zero
    MTR1_KW_CALC = MTR1_KW_H * 65536 + MTR1_KW_L;
    ErrSet(0); // Re-enable error checking.
    END

    FUNCTION MTR1_MAIN_C()
    ErrSet(1); // Disable error checking
    WHILE TRUE DO
    TaskNew("MTR1_KW_C", "", 8); // Call this function as a new task, but only if it does not run already
    SleepMS(100);
    END
    ErrSet(0); // Re-enable error checking.
    END

    It works fine, and refresh very well. But, now I get the whole number (-32789 for example) and I need to move the decimal point 3 espaces (-32.789 for example)

    I tried to maked on cicode dividing by 1000 but it freeze again.also I tried using raw scale and eng scale to move the decimal point and it also freeze.

    right now, my new issue is that I cant move the decimal point without freezing the value :(

    thank you very much

    regards,
  • From reading your comment on how you defined your Disk Tag, I suspect you used the GENERIC protocol and defined the tag with data type LONG (a 32 bit integer number), so you cannot use decimal points for that data type. Please try to redefine your disk tag as a REAL (floating point number) and an address within the range R0 to R16376.
  • It is a problem to have an endless loop in both the main function and the calc function. However, it won't start a new task each time. Since the main function in the original code just calls the calc function directly, that blocks the main function from continuing to run until the calc function finishes (and it will never finish since it has an endless loop). It would make more sense to remove the loop from the calc function since the main function will call it every 100ms.

    If your code is more complicated than the sample you shared, then it is possible that the code could do something to generate a fatal error (like dividing by 0). That would cause Citect to terminate the task and both functions would stop running. It is better to avoid endless loops like this in your code and call the function periodically from an Event.
  • If you want to store a floating point value in a disk tag, it makes more sense to store it in a REAL (and you can use the same range for both the raw and engineering scales, like -100000 to 100000). However, it is technically valid to store a floating point value in an integer data type. This is often used with PLCs registers or sensors that don't support floating point values. Citect will take the floating point value and apply the engineering to raw scaling factor to it. Then, if it is still in the raw range it will write it to the variable, dropping any extra decimal places.

    For example, say your tag is a LONG with the scales:
    Raw zero: 0, Raw Full: 100, Eng Zero: 0, Eng Full: 10
    If you write 5.5 to the tag, it will be stored in the LONG as 55, but when Citect reads it back to display it on screen it will display as 5.5. However, if you tried to write 10.5 it would scale to the raw value 105 and since those are above the max value it would fail to write to the tag.

    Pavel, what are the scales on your tags and what value are you trying to write? If you leave the scales blank, I believe it defaults to 0 to 32000, which is a problem if you're trying to write a negative number. Try writing with the TagDebugForm() tool instead of your code (just call TagDebugForm() from a button). That way you know if it's the code or the tag that is the problem.

  • Hi Patrick & Eric Black,
    Thank you guys for help me, finally it is working perfectly; this done by your knowledge & answers.

    Yes, it was defined using GENERIC protocol and defined with Data Type LONG. I changed to REAL, and works perfectly. The scaling I do it on the MTR1_KW_H and MTR1_KW_L. So the result of the calculation doesn't need a scaling on the DiskDevice. just the scale that I need. raw zero 0 and raw full 40 eng zero 0 and eng full 40.

    Thank you very much,
    Regards