en
cz

Time synchronization in UC... controllers

The UC102, UC200 and FC… zone controllers are equipped with real-time clocks (RTC). It is true that time programs are usually solved in higher-level process stations, but if the user is to be able to change the weekly time program himself directly on the controller, there is no choice but to enable the local time program.

However, this is controlled by the RTC circuit. It is a good idea to synchronize the local clock from time to time, especially since it does not have the option of switching between summer and winter time. Time synchronization can of course be performed from the ModComTool program, but this method is not very suitable for regular – and preferably automatic – time setting.

In the Modbus table, the time is stored in RAM and can be overwritten at any time. However, the problem will be with the format, the time does not appear in this form anywhere in the PLC:


Part of the Modbus table with RTC

For successful synchronization, we should proceed as follows:

  • use real time from the PLC, ideally synchronized from the NTP server
  • once in a while (hour, day...) convert the current time to the format described above
  • write this data to each controller on the bus.

We can easily fulfill the first point by setting the NTP client in the PLC and connecting to a local or remote NTP server, see also here: https://www.domat-int.com/en/how-to-configure-a-local-ntp-server.

In the Modbus table, we read that for successful writing to the RTC registers, it is necessary to enable writing by setting the first bit in word register 3 (Status LSB register). To enable it, we will therefore need a binary variable for writing the coil with the F15 function to bit register 33 (2 × 16 bits in registers 1 and 2 are skipped, so the initial element is the 33rd bit of the entire table).

For writing, the enable bit must be set.

To convert time, it will be easiest to prepare a block in the ST language, e.g.:

FUNCTION_BLOCK UCTimeSync
    VAR
        s, m, h, d, dow, mm : sint;
        y, i : int;
        sync, write : bool;
        totalsecs : lint;
        trigger:R_TRIG;
        toff:TOF;
        uctimearr : array [0..7] of byte;
    END_VAR
    VAR_INPUT
        trig : bool;
    END_VAR
    VAR_OUTPUT
        writeena: bool;
        uctime : ulint;
    END_VAR
    trigger(CLK:=trig,Q=>sync);
    if sync then
        write := true;
        LIB.CORE.V1_0.B99_PCTIMENODE(LOCAL:=TRUE, SEC=>s,MIN=>m, HOUR=>h, DAY=>d, WDAY=>dow, MON=>mm, YEAR=>y);
        uctimearr[7]:= to_byte(to_bcd_byte(y - 2000)); // year
        uctimearr[6]:= 0;        
        uctimearr[5]:= to_bcd_byte(d); // date
        uctimearr[4]:= to_byte(to_bcd_byte(mm)); // month
        uctimearr[3]:= to_bcd_byte(h); //
        uctimearr[2]:= to_bcd_byte(dow + 1); // day of week
        uctimearr[1]:= to_bcd_byte(s);// s
        uctimearr[0]:= to_bcd_byte(m); // m
        uctime := to_ulint(uctimearr[0]);
        for i := 1 to 7 DO
            uctime := uctime * 256;
            uctime := uctime + to_ulint(uctimearr[i]);
        end_for;
     end_if;
     toff(IN:=write,PT:= t#1s,Q=>writeena);
     write := false;
END_FUNCTION_BLOCK

The time conversion is activated by a rising edge at the trig input. The output is a write enable pulse (writeena) and a lint type uctime variable with the converted current PLC time according to the table above. It would be more elegant to choose an eight-byte field for uctime, but for a field type variable it is not possible to set the write only when the value changes in the communication driver. The lint type has 8 bytes, so it exceeds all four registers 49…52, which contain the current time.

Writing to the bus is done in a standard way using two groups in the prototype:

Setting the order of groups

Let's note the order of group ordering in the driver. First, the write permission must be granted (default order 0) and then the actual writing (order 1). Details about the Modbus driver and telegram queuing can be found here: https://www.domat-int.com/cs/domat-modbus-driver-a-jeho-optimizace

Each controller must have its own addressed prototype. In the current firmware version, broadcast writes with line address 0 are not supported.

Finally, we ensure regular synchronization using the rising edge at the trig input of the synchronization block. This can be triggered by a time program or a pulse source; a time program with synchronization once a day after 3 a.m. is more suitable, so that there is a correct transition between summer and winter time.

Time program for triggering synchronization

Of course, one common function block is enough for all IRC controllers.

The complete project with example is available for download here:

Files for download