Convert Allen Bradley Logix 5000 Time to Unix Time (Epoch)

My favorite time format for time stamping events is to use Unix Time.  The AB Logix 5000 controllers offer time in a format that is similar, but requires some conversion.  Here is code for a RedLion device that does that conversion.

Screenshot from 2016-07-28 17:24:19

//convert timestamp from Allen Bradley Logix 5000 style to unixtime style timestamp
// Sparky Geek, LLC - March 2016
// rev 01 - July 2016 - added unsigned to float program call
// changed program to pass 2 numbers instead of PLC number
// moved initialization of constants to seperate program

//Allen Bradley time is in the format of:
// DINT[0] contains the lower 32 bits of the value. DINT[1] contains the upper 32 bits of the value.
// The value is in microseconds and is referenced from 0000 hours, January 1, 1972.
// both of these values are unsigned integers, but are commonly incorrectly displayed as signed integers
// newer AB PLCs reference from 1970, just like unixtime, but V11 uses 1972

//Unix time (also known as POSIX time or Epoch time) is a system for describing instants in time,
// defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), 
// Thursday, 1 January 1970, not counting leap seconds. 
 
cstring working_str;
 
//convert unsigned integer to a float --lower value
working_str = UintToFloat(In_Low); 
TextToR64(working_str,TimeStampConvert.lower[0]);
//convert unsigned integer to a float --upper value
working_str = UintToFloat(In_Hi); 
TextToR64(working_str,TimeStampConvert.upper[0]); 
//move upper value to upper register
MulR64(TimeStampConvert.upperMoved[0],TimeStampConvert.upper[0],TimeStampConvert._2E32[0]);
//microseconds since 1972
AddR64(TimeStampConvert.ab_time_us[0],TimeStampConvert.upperMoved[0],TimeStampConvert.lower[0]); 
//seconds since 1972
DivR64(TimeStampConvert.ab_time_sec[0],TimeStampConvert.ab_time_us[0],TimeStampConvert._1Million[0]); 
//seconds since 1970 = unixtime
AddR64(TimeStampConvert.unixtime[0],TimeStampConvert.ab_time_sec[0],TimeStampConvert.delta_sec[0]); 
//convert to text 
return AsTextR64WithFormat("12.2.0",TimeStampConvert.unixtime[0]);

The call to UintToFloat() is described at blog.briangallimore.com/2016/07/28/convert-unsigned-integer-to-float/

There is another program that runs once on startup that initializes the constants used in this program:

//initialize variables (constants) used in the 'timestampConvert' program
// Sparky Geek, LLC - July 2016

cstring TwoE32 = "4294967296"; //the value of 2 raised to the 32nd power
cstring TwoE31 = "2147483648"; //the value of 2 raised to the 31st power
int OneMillion = 1000000; //difference between microseconds (used in AB time) and seconds (used in unix time)
int DeltaSeconds = 63072000; //difference in time (seconds) between 1970 (unix time) and 1972 (old AB time) 
//initialize 64 bit registers to hold values used in other programs
TextToR64(TwoE32,TimeStampConvert._2E32[0]); //2^32
TextToR64(TwoE31,TimeStampConvert._2E31[0]); //2^31
IntToR64(TimeStampConvert._1Million[0],OneMillion); //difference between seconds and microseconds
IntToR64(TimeStampConvert.delta_sec[0],DeltaSeconds); //difference in seconds between 1970 to 1972

 

This entry was posted in Industrial Automation and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.