From 4705c0f9b4b47442cbb06477812f25b55018880a Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Sat, 15 Apr 2023 22:12:55 +0200 Subject: [PATCH 01/13] TOD casting --- s7.cpp | 16 ++++++++++++++++ s7.h | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/s7.cpp b/s7.cpp index b264a17..8e6a9d6 100644 --- a/s7.cpp +++ b/s7.cpp @@ -530,3 +530,19 @@ float S7_GetRealAt(byte Buffer[], int Pos) } //**************************************************************************** + // Get 4x int unsigned value h/m/s/ms (S7 TOD) + // TOD#0:0:0.0 to TOD#23:59 : 59.999 + // Time in steps of 1 ms + TOD S7_GetTODAt(byte Buffer[], int Pos) + { + uint32_t time = S7_GetUDIntAt(Buffer, Pos); + uint32_t ms = time % 1000; + time = (time - ms) / 1000; + uint32_t s = time % 60; + time = (time - s) / 60; + uint32_t m = time % 60; + uint32_t h = (time - m) / 60; + return TOD{ h,m,s,ms }; + } + + //**************************************************************************** \ No newline at end of file diff --git a/s7.h b/s7.h index d76bdca..e6fefc0 100644 --- a/s7.h +++ b/s7.h @@ -46,6 +46,8 @@ using namespace std; #define S7_TYPE_STRING 15 #define S7_TYPE_ARRAYCHAR 16 +struct TOD { uint32_t h; uint32_t m; uint32_t s; uint32_t ms; }; + string S7_GetTxtPLCType (short int plcType); // Get Text description of PLC Type int S7_GetDataTypeSize (int type); // Get data type size @@ -122,4 +124,6 @@ int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LIn void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value); //Set Array of char (S7 ARRAY OF CHARS) + TOD S7_GetTODAt(byte Buffer[], int Pos); // Get 4x int unsigned value(S7 TOD) + #endif // S7_H From 0549e472dd63b8d620207c02e1eefe95b5945de9 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Sat, 15 Apr 2023 22:15:28 +0200 Subject: [PATCH 02/13] DATE casting --- s7.cpp | 17 +++++++++++++++++ s7.h | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/s7.cpp b/s7.cpp index 8e6a9d6..c8d1f7d 100644 --- a/s7.cpp +++ b/s7.cpp @@ -545,4 +545,21 @@ float S7_GetRealAt(byte Buffer[], int Pos) return TOD{ h,m,s,ms }; } + //**************************************************************************** + // Get 3x int unsigned value year/month/day (S7 DATE) + // D#1990-1-1 to D#2168 - 12 - 31 + // IEC date in steps of 1 day + DATE S7_GetDATEAt(byte Buffer[], int Pos) + { + const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 + const unsigned era = z / 146097; + const unsigned doe = (z - era * 146097); // [0, 146096] + const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] + const unsigned y = yoe + era * 400; + const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] + const unsigned mp = (5 * doy + 2) / 153; // [0, 11] + const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] + const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] + return DATE{ y + (m <= 2), m, d }; + } //**************************************************************************** \ No newline at end of file diff --git a/s7.h b/s7.h index e6fefc0..3b33c8b 100644 --- a/s7.h +++ b/s7.h @@ -48,6 +48,8 @@ using namespace std; struct TOD { uint32_t h; uint32_t m; uint32_t s; uint32_t ms; }; +struct DATE { uint32_t year; uint32_t month; uint32_t day; }; + string S7_GetTxtPLCType (short int plcType); // Get Text description of PLC Type int S7_GetDataTypeSize (int type); // Get data type size @@ -126,4 +128,6 @@ int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LIn TOD S7_GetTODAt(byte Buffer[], int Pos); // Get 4x int unsigned value(S7 TOD) + DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get 3x int unsigned value(S7 DATE) + #endif // S7_H From b9c5476ea906262d562179ff34194a04fd9b6289 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega <45517077+PiotrBzdrega@users.noreply.github.com> Date: Sat, 15 Apr 2023 22:19:53 +0200 Subject: [PATCH 03/13] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 15a3baa..749031e 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,7 @@ This S7 C/C++ functions allows to parsing data read from Siemens PLC/SINAMICs by History of versions 21-Dic-2015 - First version +15-Apr-2023 - TOD & DATE mapping added (PiotrBzdręga) + From 3ef7245fc33a8137abe16d5e30f00b18644ed575 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Sun, 16 Apr 2023 20:06:57 +0200 Subject: [PATCH 04/13] get DATE_AND_TIME --- s7.cpp | 17 ++++++++++++++++- s7.h | 5 +++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/s7.cpp b/s7.cpp index c8d1f7d..349e4d4 100644 --- a/s7.cpp +++ b/s7.cpp @@ -562,4 +562,19 @@ float S7_GetRealAt(byte Buffer[], int Pos) const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] return DATE{ y + (m <= 2), m, d }; } - //**************************************************************************** \ No newline at end of file + //**************************************************************************** + // Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) + // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 + DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) + { + uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 999] + year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 + uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] + uint16_t day = S7_BDCToByte(Buffer[Pos + 2]); // [1, 31] + uint16_t hour = S7_BDCToByte(Buffer[Pos + 3]); // [0, 23] + uint16_t minute = S7_BDCToByte(Buffer[Pos + 4]); // [0, 59] + uint16_t second = S7_BDCToByte(Buffer[Pos + 5]); // [0, 59] + uint16_t msec = S7_BDCToByte(Buffer[Pos + 6]) * 10 + ((Buffer[Pos + 7] >> 4) & 0x0F); // [0, 999] 7 (4MSB) + uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) + return DATE_AND_TIME{ year, month, day, hour, minute, second, msec, weekday }; + } \ No newline at end of file diff --git a/s7.h b/s7.h index 3b33c8b..15bbfd9 100644 --- a/s7.h +++ b/s7.h @@ -50,6 +50,9 @@ struct TOD { uint32_t h; uint32_t m; uint32_t s; uint32_t ms; }; struct DATE { uint32_t year; uint32_t month; uint32_t day; }; +struct DATE_AND_TIME { uint16_t year; uint16_t month; uint16_t day; uint16_t hour; uint16_t minute; uint16_t second; uint16_t msec; uint16_t weekday; }; + + string S7_GetTxtPLCType (short int plcType); // Get Text description of PLC Type int S7_GetDataTypeSize (int type); // Get data type size @@ -130,4 +133,6 @@ int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LIn DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get 3x int unsigned value(S7 DATE) + DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos); // Get struct of DATE_AND_TIME (S7 DATE_AND_TIME) + #endif // S7_H From 7700b6e1db82852416723fc7d8bb477248c0b7ab Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Sun, 16 Apr 2023 21:36:36 +0200 Subject: [PATCH 05/13] DTL get added --- s7.cpp | 34 ++++++++++++++++++++++++++++------ s7.h | 3 +++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/s7.cpp b/s7.cpp index 349e4d4..a7e5e1b 100644 --- a/s7.cpp +++ b/s7.cpp @@ -542,39 +542,61 @@ float S7_GetRealAt(byte Buffer[], int Pos) time = (time - s) / 60; uint32_t m = time % 60; uint32_t h = (time - m) / 60; + return TOD{ h,m,s,ms }; } //**************************************************************************** - // Get 3x int unsigned value year/month/day (S7 DATE) + // Get (Year-Month-Day) (S7 DATE) + // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. // D#1990-1-1 to D#2168 - 12 - 31 // IEC date in steps of 1 day DATE S7_GetDATEAt(byte Buffer[], int Pos) { const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 const unsigned era = z / 146097; - const unsigned doe = (z - era * 146097); // [0, 146096] + const unsigned doe = (z - era * 146097); // [0, 146096] const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] const unsigned y = yoe + era * 400; const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] - const unsigned mp = (5 * doy + 2) / 153; // [0, 11] + const unsigned mp = (5 * doy + 2) / 153; // [0, 11] const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] - const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] + const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] + return DATE{ y + (m <= 2), m, d }; } //**************************************************************************** // Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) + // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) { - uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 999] + uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 999] year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 - uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] + uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] uint16_t day = S7_BDCToByte(Buffer[Pos + 2]); // [1, 31] uint16_t hour = S7_BDCToByte(Buffer[Pos + 3]); // [0, 23] uint16_t minute = S7_BDCToByte(Buffer[Pos + 4]); // [0, 59] uint16_t second = S7_BDCToByte(Buffer[Pos + 5]); // [0, 59] uint16_t msec = S7_BDCToByte(Buffer[Pos + 6]) * 10 + ((Buffer[Pos + 7] >> 4) & 0x0F); // [0, 999] 7 (4MSB) uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) + return DATE_AND_TIME{ year, month, day, hour, minute, second, msec, weekday }; + } + //**************************************************************************** + // Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) + // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. + // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 + DTL S7_GetDTLAt(byte Buffer[], int Pos) + { + uint16_t year = S7_GetUIntAt(Buffer,Pos); // 1970, 2262] + uint16_t month = static_cast(S7_GetByteAt(Buffer,Pos + 2)); // [1, 12] + uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] + uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] + uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] + uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] + uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] + uint32_t nanosec = S7_GetUDIntAt(Buffer,Pos+8); // [0, 999999999] + + return DTL{ year, month, day, weekday, hour, minute, second, nanosec }; } \ No newline at end of file diff --git a/s7.h b/s7.h index 15bbfd9..59a88ea 100644 --- a/s7.h +++ b/s7.h @@ -52,6 +52,7 @@ struct DATE { uint32_t year; uint32_t month; uint32_t day; }; struct DATE_AND_TIME { uint16_t year; uint16_t month; uint16_t day; uint16_t hour; uint16_t minute; uint16_t second; uint16_t msec; uint16_t weekday; }; +struct DTL { uint16_t year; uint16_t month; uint16_t day; uint16_t weekday; uint16_t hour; uint16_t minute; uint16_t second; uint32_t nanosec; }; string S7_GetTxtPLCType (short int plcType); // Get Text description of PLC Type @@ -135,4 +136,6 @@ int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LIn DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos); // Get struct of DATE_AND_TIME (S7 DATE_AND_TIME) + DTL S7_GetDTLAt(byte Buffer[], int Pos); // Get struct of DTL (S7 DTL) + #endif // S7_H From e4ca3a97467fb94a363ef677c00455126ddac246 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Mon, 17 Apr 2023 07:08:23 +0200 Subject: [PATCH 06/13] correct description of new functions --- s7.cpp | 42 +++++++++++++++++++++++++++++++++--------- s7.h | 8 ++++++-- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/s7.cpp b/s7.cpp index a7e5e1b..48d835f 100644 --- a/s7.cpp +++ b/s7.cpp @@ -530,20 +530,33 @@ float S7_GetRealAt(byte Buffer[], int Pos) } //**************************************************************************** - // Get 4x int unsigned value h/m/s/ms (S7 TOD) + // Get TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) // TOD#0:0:0.0 to TOD#23:59 : 59.999 // Time in steps of 1 ms TOD S7_GetTODAt(byte Buffer[], int Pos) { uint32_t time = S7_GetUDIntAt(Buffer, Pos); - uint32_t ms = time % 1000; - time = (time - ms) / 1000; - uint32_t s = time % 60; - time = (time - s) / 60; - uint32_t m = time % 60; - uint32_t h = (time - m) / 60; - - return TOD{ h,m,s,ms }; + uint32_t msec = time % 1000; + time = (time - msec) / 1000; + uint32_t second = time % 60; + time = (time - second) / 60; + uint32_t minute = time % 60; + uint32_t hour = (time - minute) / 60; + + return TOD{ hour,minute,second,msec }; + } + + //**************************************************************************** + // Set TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) + // TOD#0:0:0.0 to TOD#23:59 : 59.999 + // Time in steps of 1 ms + void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec ) + { + uint32_t time = msec; + time += 1000 * second; + time += 60 * 1000 * hour; + time += 60 * 60 * 1000 * hour; + S7_SetUDIntAt(Buffer,Pos,time); } //**************************************************************************** @@ -551,6 +564,7 @@ float S7_GetRealAt(byte Buffer[], int Pos) // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. // D#1990-1-1 to D#2168 - 12 - 31 // IEC date in steps of 1 day + //http://howardhinnant.github.io/date_algorithms.html#Acknowledgments DATE S7_GetDATEAt(byte Buffer[], int Pos) { const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 @@ -564,6 +578,16 @@ float S7_GetRealAt(byte Buffer[], int Pos) const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] return DATE{ y + (m <= 2), m, d }; + } + //**************************************************************************** + // Set (Year-Month-Day) (S7 DATE) + // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. + // D#1990-1-1 to D#2168 - 12 - 31 + // IEC date in steps of 1 day + //http://howardhinnant.github.io/date_algorithms.html#Acknowledgments + void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day) + { + } //**************************************************************************** // Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) diff --git a/s7.h b/s7.h index 59a88ea..cfebf53 100644 --- a/s7.h +++ b/s7.h @@ -130,9 +130,13 @@ int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LIn void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value); //Set Array of char (S7 ARRAY OF CHARS) - TOD S7_GetTODAt(byte Buffer[], int Pos); // Get 4x int unsigned value(S7 TOD) + TOD S7_GetTODAt(byte Buffer[], int Pos); // Get struct of TOD (S7 TOD) - DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get 3x int unsigned value(S7 DATE) + void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec); // Set struct of TOD(S7 TOD) + + DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get struct of DATE (S7 DATE) + + void S7_SetDATEAt(byte Buffer[], int Pos); // Get struct of DATE (S7 DATE) DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos); // Get struct of DATE_AND_TIME (S7 DATE_AND_TIME) From 8290fd65fb1847b69920c8d7d9d04a80624d7356 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Tue, 18 Apr 2023 06:34:12 +0200 Subject: [PATCH 07/13] Set Date functions, formating --- s7.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++------------- s7.h | 84 ++++++++++++++++++++++++++++++---------------------------- 2 files changed, 106 insertions(+), 59 deletions(-) diff --git a/s7.cpp b/s7.cpp index 48d835f..96551a0 100644 --- a/s7.cpp +++ b/s7.cpp @@ -529,10 +529,11 @@ float S7_GetRealAt(byte Buffer[], int Pos) Value.copy ((char*) &Buffer[Pos],Size); } - //**************************************************************************** - // Get TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) - // TOD#0:0:0.0 to TOD#23:59 : 59.999 - // Time in steps of 1 ms + //**************************************************************************** + // Get TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) + // TOD#0:0:0.0 to TOD#23:59 : 59.999 + // Time in steps of 1 ms + //https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW TOD S7_GetTODAt(byte Buffer[], int Pos) { uint32_t time = S7_GetUDIntAt(Buffer, Pos); @@ -564,7 +565,7 @@ float S7_GetRealAt(byte Buffer[], int Pos) // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. // D#1990-1-1 to D#2168 - 12 - 31 // IEC date in steps of 1 day - //http://howardhinnant.github.io/date_algorithms.html#Acknowledgments + //http://howardhinnant.github.io/date_algorithms.html#civil_from_days DATE S7_GetDATEAt(byte Buffer[], int Pos) { const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 @@ -584,10 +585,16 @@ float S7_GetRealAt(byte Buffer[], int Pos) // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. // D#1990-1-1 to D#2168 - 12 - 31 // IEC date in steps of 1 day - //http://howardhinnant.github.io/date_algorithms.html#Acknowledgments + //http://howardhinnant.github.io/date_algorithms.html#days_from_civil void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day) { - + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t Value= era * 146097 + static_cast(doe) - 726773; + S7_SetUDIntAt(Buffer, Pos, Value); } //**************************************************************************** // Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) @@ -595,7 +602,7 @@ float S7_GetRealAt(byte Buffer[], int Pos) // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) { - uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 999] + uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 99] year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] uint16_t day = S7_BDCToByte(Buffer[Pos + 2]); // [1, 31] @@ -608,19 +615,55 @@ float S7_GetRealAt(byte Buffer[], int Pos) return DATE_AND_TIME{ year, month, day, hour, minute, second, msec, weekday }; } //**************************************************************************** + // Set year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) + // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. + // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 + void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) + { + year %= 100; //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 + Buffer[Pos] = S7_ByteToBDC(year); // [0, 99] + Buffer[Pos + 1] = S7_ByteToBDC(month); // [1, 12] + Buffer[Pos + 2] = S7_ByteToBDC(day); // [1, 31] + Buffer[Pos + 3] = S7_ByteToBDC(hour); // [0, 23] + Buffer[Pos + 4] = S7_ByteToBDC(minute); // [0, 59] + Buffer[Pos + 5] = S7_ByteToBDC(second); // [0, 59] + Buffer[Pos + 6] = S7_ByteToBDC(msec/10); + Buffer[Pos + 7] = msec%10 & 0x0F; + + //uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) + //??? + + } + //**************************************************************************** // Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - DTL S7_GetDTLAt(byte Buffer[], int Pos) + DTL S7_GetDTLAt(byte Buffer[], int Pos) + { + uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] + uint16_t month = static_cast(S7_GetByteAt(Buffer, Pos + 2)); // [1, 12] + uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] + uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] + uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] + uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] + uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] + uint32_t nanosec = S7_GetUDIntAt(Buffer, Pos + 8); // [0, 999999999] + + return DTL{ year, month, day, weekday, hour, minute, second, nanosec }; + } + //**************************************************************************** + // Set Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) + // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. + // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 + void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t nanosec) { - uint16_t year = S7_GetUIntAt(Buffer,Pos); // 1970, 2262] - uint16_t month = static_cast(S7_GetByteAt(Buffer,Pos + 2)); // [1, 12] - uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] - uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] - uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] - uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] - uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] - uint32_t nanosec = S7_GetUDIntAt(Buffer,Pos+8); // [0, 999999999] - - return DTL{ year, month, day, weekday, hour, minute, second, nanosec }; + S7_SetUIntAt(Buffer,Pos,year); // 1970, 2262] + S7_SetByteAt(Buffer,Pos + 2,month); // [1, 12] + S7_SetByteAt(Buffer, Pos + 3,day); // [1, 31] + //uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] + S7_SetByteAt(Buffer, Pos + 5,hour); // [0, 23] + S7_SetByteAt(Buffer, Pos + 6,minute); // [0, 59] + S7_SetByteAt(Buffer, Pos + 7,second); // [0, 59] + S7_SetUDIntAt(Buffer,Pos+8,nanosec); // [0, 999999999] + } \ No newline at end of file diff --git a/s7.h b/s7.h index cfebf53..c32c354 100644 --- a/s7.h +++ b/s7.h @@ -54,92 +54,96 @@ struct DATE_AND_TIME { uint16_t year; uint16_t month; uint16_t day; uint16_t hou struct DTL { uint16_t year; uint16_t month; uint16_t day; uint16_t weekday; uint16_t hour; uint16_t minute; uint16_t second; uint32_t nanosec; }; -string S7_GetTxtPLCType (short int plcType); // Get Text description of PLC Type + string S7_GetTxtPLCType (short int plcType); // Get Text description of PLC Type int S7_GetDataTypeSize (int type); // Get data type size -uint16_t S7_GetWordFromTSAP ( string TSAP); // Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams + uint16_t S7_GetWordFromTSAP ( string TSAP); // Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams - string S7_GetTxtAreaSource (int areaSource); // Get Text message of Area Source + string S7_GetTxtAreaSource (int areaSource); // Get Text message of Area Source int S7_BDCToByte (byte B); // Get BDC and convert to byte - byte S7_ByteToBDC (int Value); // Convert Byte to BDC + byte S7_ByteToBDC (int Value); // Convert Byte to BDC - bool S7_GetBitAt ( byte Buffer[], int Pos, int Bit); // Get Bit position at buffer of bytes + bool S7_GetBitAt ( byte Buffer[], int Pos, int Bit); // Get Bit position at buffer of bytes - void S7_SetBitAt ( byte Buffer[], int Pos, int Bit, bool Value); // Set Bit position at buffer of bytes + void S7_SetBitAt ( byte Buffer[], int Pos, int Bit, bool Value); // Set Bit position at buffer of bytes -uint8_t S7_GetByteAt(byte Buffer[], int Pos); // Get Byte (0..255) at buffer of bytes + uint8_t S7_GetByteAt(byte Buffer[], int Pos); // Get Byte (0..255) at buffer of bytes - void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value ); // Set Byte (0..255) at buffer of bytes + void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value ); // Set Byte (0..255) at buffer of bytes - int8_t S7_GetSIntAt(byte Buffer[], int Pos); // Get SInt (-128..127) at buffer of bytes + int8_t S7_GetSIntAt(byte Buffer[], int Pos); // Get SInt (-128..127) at buffer of bytes - void S7_SetSIntAt(byte Buffer[], int Pos, int Value); // Set SInt (-128..127) at buffer of bytes + void S7_SetSIntAt(byte Buffer[], int Pos, int8_t Value); // Set SInt (-128..127) at buffer of bytes - uint16_t S7_GetUIntAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 + uint16_t S7_GetUIntAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 - void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value ); // Set 16 bit unsigned value (S7 UInt) 0..65535 + void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value ); // Set 16 bit unsigned value (S7 UInt) 0..65535 - uint16_t S7_GetWordAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 + uint16_t S7_GetWordAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 - void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value ); // Set 16 bit unsigned value (S7 UInt) 0..65535 + void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value ); // Set 16 bit unsigned value (S7 UInt) 0..65535 - int16_t S7_GetIntAt(byte Buffer[], int Pos); // Get 16 bit signed value (S7 int) -32768..32767 at buffer of bytes + int16_t S7_GetIntAt(byte Buffer[], int Pos); // Get 16 bit signed value (S7 int) -32768..32767 at buffer of bytes - void S7_SetIntAt(byte Buffer[], int Pos, int16_t Value); // Set 16 bit signed value (S7 int) -32768..32767 at buffer of bytes + void S7_SetIntAt(byte Buffer[], int Pos, int16_t Value); // Set 16 bit signed value (S7 int) -32768..32767 at buffer of bytes - uint32_t S7_GetUDIntAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 + uint32_t S7_GetUDIntAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 - void S7_SetUDIntAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 + void S7_SetUDIntAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 - uint32_t S7_GetDWordAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 + uint32_t S7_GetDWordAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 - void S7_SetDWordAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 + void S7_SetDWordAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 - long S7_GetDIntAt(byte Buffer[], int Pos); // Get 32 bit signed value (S7 DInt) -2147483648..2147483647 + long S7_GetDIntAt(byte Buffer[], int Pos); // Get 32 bit signed value (S7 DInt) -2147483648..2147483647 - void S7_SetDIntAt(byte Buffer[], int Pos, long Value); // Set 32 bit signed value (S7 DInt) -2147483648..2147483647 + void S7_SetDIntAt(byte Buffer[], int Pos, long Value); // Set 32 bit signed value (S7 DInt) -2147483648..2147483647 - uint64_t S7_GetULIntAt(byte Buffer[], int Pos); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 + uint64_t S7_GetULIntAt(byte Buffer[], int Pos); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 void S7_SetULIntAt(byte Buffer[], int Pos, uint64_t Value); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 uint64_t S7_GetLWordAt(byte Buffer[], int Pos); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 + void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 -int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 + int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 - void S7_SetLIntAt(byte Buffer[], int Pos, int64_t Value); // Set 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 + void S7_SetLIntAt(byte Buffer[], int Pos, int64_t Value); // Set 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 - float S7_GetRealAt(byte Buffer[], int Pos); // Get 32 bit floating point number (S7 Real) (Range of float) + float S7_GetRealAt(byte Buffer[], int Pos); // Get 32 bit floating point number (S7 Real) (Range of float) - void S7_SetRealAt(byte Buffer[], int Pos, float Value); // Set 32 bit floating point number (S7 Real) (Range of float) + void S7_SetRealAt(byte Buffer[], int Pos, float Value); // Set 32 bit floating point number (S7 Real) (Range of float) - double S7_GetLRealAt(byte Buffer[], int Pos); // Get 64 bit floating point number (S7 LReal) (Range of double) + double S7_GetLRealAt(byte Buffer[], int Pos); // Get 64 bit floating point number (S7 LReal) (Range of double) - void S7_SetLRealAt(byte Buffer[], int Pos, double Value); // Set 64 bit floating point number (S7 LReal) (Range of double) + void S7_SetLRealAt(byte Buffer[], int Pos, double Value); // Set 64 bit floating point number (S7 LReal) (Range of double) - string S7_GetStringAt(byte Buffer[], int Pos); // Get String (S7 String) + string S7_GetStringAt(byte Buffer[], int Pos); // Get String (S7 String) - void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value); // Set String (S7 String) + void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value); // Set String (S7 String) - string S7_GetCharsAt(byte Buffer[], int Pos, int Size); //Get Array of char (S7 ARRAY OF CHARS) + string S7_GetCharsAt(byte Buffer[], int Pos, int Size); //Get Array of char (S7 ARRAY OF CHARS) - void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value); //Set Array of char (S7 ARRAY OF CHARS) + void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value); //Set Array of char (S7 ARRAY OF CHARS) - TOD S7_GetTODAt(byte Buffer[], int Pos); // Get struct of TOD (S7 TOD) + TOD S7_GetTODAt(byte Buffer[], int Pos); // Get struct of TOD (S7 TOD) - void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec); // Set struct of TOD(S7 TOD) + void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec); // Set struct of TOD(S7 TOD) - DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get struct of DATE (S7 DATE) + DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get struct of DATE (S7 DATE) - void S7_SetDATEAt(byte Buffer[], int Pos); // Get struct of DATE (S7 DATE) + void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day); // Set struct of DATE (S7 DATE) - DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos); // Get struct of DATE_AND_TIME (S7 DATE_AND_TIME) + DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos); // Get struct of DATE_AND_TIME (S7 DATE_AND_TIME) - DTL S7_GetDTLAt(byte Buffer[], int Pos); // Get struct of DTL (S7 DTL) + void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec); // Set struct of DATE_AND_TIME (S7 DATE_AND_TIME) + + DTL S7_GetDTLAt(byte Buffer[], int Pos); // Get struct of DTL (S7 DTL) + + void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t nanosec); // Set struct of DTL (S7 DTL) #endif // S7_H From 68a74d6eadd5f8821f813daf58d15ed68a2d7913 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Tue, 18 Apr 2023 07:22:13 +0200 Subject: [PATCH 08/13] new DATE types, UNDONE FLAGS --- s7.cpp | 60 ++++++++++++++++++++++++++++++++++++++-------------------- s7.h | 4 ++++ 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/s7.cpp b/s7.cpp index 96551a0..be77911 100644 --- a/s7.cpp +++ b/s7.cpp @@ -61,6 +61,7 @@ string S7_GetTxtPLCType (short int plcType) case S7_TYPE_WORD: case S7_TYPE_UINT: case S7_TYPE_INT: + case S7_TYPE_DATE: size = 2; break; @@ -68,6 +69,7 @@ string S7_GetTxtPLCType (short int plcType) case S7_TYPE_UDINT: case S7_TYPE_DINT: case S7_TYPE_REAL: + case S7_TYPE_TOD: size = 4; break; @@ -75,9 +77,14 @@ string S7_GetTxtPLCType (short int plcType) case S7_TYPE_ULINT: case S7_TYPE_LINT: case S7_TYPE_LREAL: + case S7_TYPE_DATE_AND_TIME: size = 8; break; + case S7_TYPE_DTL: + size = 12; + break; + }; return size; @@ -535,7 +542,7 @@ float S7_GetRealAt(byte Buffer[], int Pos) // Time in steps of 1 ms //https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW TOD S7_GetTODAt(byte Buffer[], int Pos) - { + {// UNDONE: check result uint32_t time = S7_GetUDIntAt(Buffer, Pos); uint32_t msec = time % 1000; time = (time - msec) / 1000; @@ -551,8 +558,9 @@ float S7_GetRealAt(byte Buffer[], int Pos) // Set TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) // TOD#0:0:0.0 to TOD#23:59 : 59.999 // Time in steps of 1 ms + //https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec ) - { + {// UNDONE: check result uint32_t time = msec; time += 1000 * second; time += 60 * 1000 * hour; @@ -565,9 +573,10 @@ float S7_GetRealAt(byte Buffer[], int Pos) // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. // D#1990-1-1 to D#2168 - 12 - 31 // IEC date in steps of 1 day + //https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL //http://howardhinnant.github.io/date_algorithms.html#civil_from_days DATE S7_GetDATEAt(byte Buffer[], int Pos) - { + {// UNDONE: check result const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 const unsigned era = z / 146097; const unsigned doe = (z - era * 146097); // [0, 146096] @@ -580,14 +589,16 @@ float S7_GetRealAt(byte Buffer[], int Pos) return DATE{ y + (m <= 2), m, d }; } + //**************************************************************************** // Set (Year-Month-Day) (S7 DATE) // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. // D#1990-1-1 to D#2168 - 12 - 31 // IEC date in steps of 1 day + //https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL //http://howardhinnant.github.io/date_algorithms.html#days_from_civil void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day) - { + {// UNDONE: check result year -= month <= 2; const unsigned era = year / 400; const unsigned yoe = static_cast(year - era * 400); // [0, 399] @@ -596,12 +607,14 @@ float S7_GetRealAt(byte Buffer[], int Pos) uint32_t Value= era * 146097 + static_cast(doe) - 726773; S7_SetUDIntAt(Buffer, Pos, Value); } + //**************************************************************************** // Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 + //https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) - { + {// UNDONE: check result uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 99] year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] @@ -614,12 +627,14 @@ float S7_GetRealAt(byte Buffer[], int Pos) return DATE_AND_TIME{ year, month, day, hour, minute, second, msec, weekday }; } + //**************************************************************************** // Set year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 - void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) - { + //https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL + void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) + {// UNDONE: check result year %= 100; //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 Buffer[Pos] = S7_ByteToBDC(year); // [0, 99] Buffer[Pos + 1] = S7_ByteToBDC(month); // [1, 12] @@ -634,29 +649,32 @@ float S7_GetRealAt(byte Buffer[], int Pos) //??? } + //**************************************************************************** // Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - DTL S7_GetDTLAt(byte Buffer[], int Pos) - { - uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] - uint16_t month = static_cast(S7_GetByteAt(Buffer, Pos + 2)); // [1, 12] - uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] - uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] - uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] - uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] - uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] - uint32_t nanosec = S7_GetUDIntAt(Buffer, Pos + 8); // [0, 999999999] - - return DTL{ year, month, day, weekday, hour, minute, second, nanosec }; - } + + DTL S7_GetDTLAt(byte Buffer[], int Pos) + {// UNDONE: check result + uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] + uint16_t month = static_cast(S7_GetByteAt(Buffer, Pos + 2)); // [1, 12] + uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] + uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] + uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] + uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] + uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] + uint32_t nanosec = S7_GetUDIntAt(Buffer, Pos + 8); // [0, 999999999] + + return DTL{ year, month, day, weekday, hour, minute, second, nanosec }; + } + //**************************************************************************** // Set Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t nanosec) - { + {// UNDONE: check result S7_SetUIntAt(Buffer,Pos,year); // 1970, 2262] S7_SetByteAt(Buffer,Pos + 2,month); // [1, 12] S7_SetByteAt(Buffer, Pos + 3,day); // [1, 31] diff --git a/s7.h b/s7.h index c32c354..22a8464 100644 --- a/s7.h +++ b/s7.h @@ -45,6 +45,10 @@ using namespace std; #define S7_TYPE_STRING 15 #define S7_TYPE_ARRAYCHAR 16 +#define S7_TYPE_TOD 17 +#define S7_TYPE_DATE 18 +#define S7_TYPE_DATE_AND_TIME 19 +#define S7_TYPE_DTL 20 struct TOD { uint32_t h; uint32_t m; uint32_t s; uint32_t ms; }; From c02dae53fdfb6bcf1e4d78b9f7834bc9f67b23b1 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Mon, 15 May 2023 06:11:22 +0200 Subject: [PATCH 09/13] String size; weekday calculate; TOD hour -> minute SetDATE UDInt -> UInt; SetDtL param type --- s7.cpp | 52 +++++++++++++++++++++++++++++++++++++++------------- s7.h | 2 +- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/s7.cpp b/s7.cpp index be77911..daa09db 100644 --- a/s7.cpp +++ b/s7.cpp @@ -85,6 +85,10 @@ string S7_GetTxtPLCType (short int plcType) size = 12; break; + case S7_TYPE_STRING: + size = 254; + break; + }; return size; @@ -563,7 +567,7 @@ float S7_GetRealAt(byte Buffer[], int Pos) {// UNDONE: check result uint32_t time = msec; time += 1000 * second; - time += 60 * 1000 * hour; + time += 60 * 1000 * minute; time += 60 * 60 * 1000 * hour; S7_SetUDIntAt(Buffer,Pos,time); } @@ -604,8 +608,8 @@ float S7_GetRealAt(byte Buffer[], int Pos) const unsigned yoe = static_cast(year - era * 400); // [0, 399] const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - uint32_t Value= era * 146097 + static_cast(doe) - 726773; - S7_SetUDIntAt(Buffer, Pos, Value); + uint32_t Value= era * 146097 + static_cast(doe) - 726773; //[726773] (offset) days from 0000-03-01 to 1990-01-01 + S7_SetUIntAt(Buffer, Pos, Value); } //**************************************************************************** @@ -635,18 +639,29 @@ float S7_GetRealAt(byte Buffer[], int Pos) //https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) {// UNDONE: check result - year %= 100; //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 - Buffer[Pos] = S7_ByteToBDC(year); // [0, 99] + //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 + Buffer[Pos] = S7_ByteToBDC(year%100); // [0, 89] Buffer[Pos + 1] = S7_ByteToBDC(month); // [1, 12] Buffer[Pos + 2] = S7_ByteToBDC(day); // [1, 31] Buffer[Pos + 3] = S7_ByteToBDC(hour); // [0, 23] Buffer[Pos + 4] = S7_ByteToBDC(minute); // [0, 59] Buffer[Pos + 5] = S7_ByteToBDC(second); // [0, 59] - Buffer[Pos + 6] = S7_ByteToBDC(msec/10); - Buffer[Pos + 7] = msec%10 & 0x0F; + Buffer[Pos + 6] = S7_ByteToBDC(msec/10); // [0, 99] + - //uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) - //??? + //weekday calculation + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t days = era * 146097 + static_cast(doe) - 726773; + uint8_t weekday = ((days + 1) % 7) + 1; //1990-01-01[Monday(1)] [1,7] + + Buffer[Pos + 7] = weekday; // [1, 7] + Buffer[Pos + 7] |= ((msec % 10) << 4); // [0, 9] + + } @@ -654,7 +669,7 @@ float S7_GetRealAt(byte Buffer[], int Pos) // Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - + //https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL DTL S7_GetDTLAt(byte Buffer[], int Pos) {// UNDONE: check result uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] @@ -673,15 +688,26 @@ float S7_GetRealAt(byte Buffer[], int Pos) // Set Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t nanosec) + //https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL + void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec) {// UNDONE: check result S7_SetUIntAt(Buffer,Pos,year); // 1970, 2262] S7_SetByteAt(Buffer,Pos + 2,month); // [1, 12] S7_SetByteAt(Buffer, Pos + 3,day); // [1, 31] - //uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] + + //weekday calculation + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t days = era * 146097 + static_cast(doe) - 726773; + uint8_t weekday = ((days + 1) % 7) + 1; //1990-01-01[Monday(1)] [1,7] + + S7_SetByteAt(Buffer, Pos + 4, weekday); // [1, 7] S7_SetByteAt(Buffer, Pos + 5,hour); // [0, 23] S7_SetByteAt(Buffer, Pos + 6,minute); // [0, 59] S7_SetByteAt(Buffer, Pos + 7,second); // [0, 59] - S7_SetUDIntAt(Buffer,Pos+8,nanosec); // [0, 999999999] + S7_SetUDIntAt(Buffer,Pos + 8,nanosec); // [0, 999999999] } \ No newline at end of file diff --git a/s7.h b/s7.h index 22a8464..2230d62 100644 --- a/s7.h +++ b/s7.h @@ -148,6 +148,6 @@ struct DTL { uint16_t year; uint16_t month; uint16_t day; uint16_t weekday; uint DTL S7_GetDTLAt(byte Buffer[], int Pos); // Get struct of DTL (S7 DTL) - void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t nanosec); // Set struct of DTL (S7 DTL) + void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec); // Set struct of DTL (S7 DTL) #endif // S7_H From 424270f29a3a39d24498a5d15c64070fc70edc4a Mon Sep 17 00:00:00 2001 From: PiotrBzdrega <45517077+PiotrBzdrega@users.noreply.github.com> Date: Mon, 15 May 2023 06:13:56 +0200 Subject: [PATCH 10/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 749031e..9b7f0b7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This S7 C/C++ functions allows to parsing data read from Siemens PLC/SINAMICs by History of versions 21-Dic-2015 - First version -15-Apr-2023 - TOD & DATE mapping added (PiotrBzdręga) +15-May-2023 - TOD, DTL, DATE, DATE_AND_TIME SET/GET added (PiotrBzdręga) From 70ea935f190ef340a5bc365cc82849d9804777c0 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Mon, 15 May 2023 06:24:18 +0200 Subject: [PATCH 11/13] UNDONE comments delete & autoformat --- s7.cpp | 857 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 436 insertions(+), 421 deletions(-) diff --git a/s7.cpp b/s7.cpp index daa09db..0aac226 100644 --- a/s7.cpp +++ b/s7.cpp @@ -13,185 +13,186 @@ #include "s7.h" #include "string.h" // for memcpy - using namespace std; -static byte Mask[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; +static byte Mask[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; //**************************************************************************** // Get Text description of PLC Type -string S7_GetTxtPLCType (short int plcType) +string S7_GetTxtPLCType(short int plcType) { switch (plcType) { - case S7_PLC_300_400: - return "S7 300/400"; - break; + case S7_PLC_300_400: + return "S7 300/400"; + break; - case S7_PLC_1200_1500: - return "S7 1200/1500"; - break; + case S7_PLC_1200_1500: + return "S7 1200/1500"; + break; - case S7_PLC_LOGO_200: - return "LOGO/S7 200"; - break; + case S7_PLC_LOGO_200: + return "LOGO/S7 200"; + break; - case S7_PLC_SINAMICS: - return "SINAMICS"; - break; + case S7_PLC_SINAMICS: + return "SINAMICS"; + break; } } //**************************************************************************** // Get data type size in bytes of the specified type - int S7_GetDataTypeSize (int type) +int S7_GetDataTypeSize(int type) { - int size =0; // for unkown type return 0 + int size = 0; // for unkown type return 0 - switch (type) - { - case S7_TYPE_BOOL: - case S7_TYPE_BYTE: - case S7_TYPE_SINT: - size = 1; - break; - - case S7_TYPE_WORD: - case S7_TYPE_UINT: - case S7_TYPE_INT: - case S7_TYPE_DATE: - size = 2; - break; - - case S7_TYPE_DWORD: - case S7_TYPE_UDINT: - case S7_TYPE_DINT: - case S7_TYPE_REAL: - case S7_TYPE_TOD: - size = 4; - break; - - case S7_TYPE_LWORD: - case S7_TYPE_ULINT: - case S7_TYPE_LINT: - case S7_TYPE_LREAL: - case S7_TYPE_DATE_AND_TIME: - size = 8; - break; - - case S7_TYPE_DTL: - size = 12; - break; - - case S7_TYPE_STRING: - size = 254; - break; - - }; - - return size; - } - - //**************************************************************************** - - // Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams - // Enter TSAP in format ##.## in hex - // Return: the TSAP number in a word and decimal format - uint16_t S7_GetWordFromTSAP ( string TSAP) - { - short int pos = TSAP.find ('.'); // find the delimiter into the source string - - if (pos == string::npos) {// no delimiter was found, return 0 - return 0; - } - else { // was found '.' - string first = TSAP.substr (0,pos); // get the first argument - string second = TSAP.substr (pos+1,2) ; // get the second argument - - // convert both TSAP arguments from hex (16) in string format to a number in decimal - char* p; // used in the strtol function - - uint8_t number1 = strtol(first.c_str(), &p, 16); // convert string with data in any base (10, 16) to long - uint8_t number2 = strtol(second.c_str(), &p, 16); // convert string with data in any base (10, 16) to long - - uint16_t res = number1 << 8 | number2; - - return res; - } - - } - - //**************************************************************************** - // Get Text message of Area Source - string S7_GetTxtAreaSource (int areaSource) + switch (type) { - switch (areaSource) - { - case S7_AREA_SOURCE_I: // Inputs - return "INPUTS"; - break; - - case S7_AREA_SOURCE_Q: // Outputs - return "OUTPUTS"; - break; - - case S7_AREA_SOURCE_M: // Memory Marks - return "Marks"; - break; - - case S7_AREA_SOURCE_DB: // Data Block - return "DB"; - break; - - default: - return "Unkown Data Source"; - }; + case S7_TYPE_BOOL: + case S7_TYPE_BYTE: + case S7_TYPE_SINT: + size = 1; + break; + + case S7_TYPE_WORD: + case S7_TYPE_UINT: + case S7_TYPE_INT: + case S7_TYPE_DATE: + size = 2; + break; + + case S7_TYPE_DWORD: + case S7_TYPE_UDINT: + case S7_TYPE_DINT: + case S7_TYPE_REAL: + case S7_TYPE_TOD: + size = 4; + break; + + case S7_TYPE_LWORD: + case S7_TYPE_ULINT: + case S7_TYPE_LINT: + case S7_TYPE_LREAL: + case S7_TYPE_DATE_AND_TIME: + size = 8; + break; + + case S7_TYPE_DTL: + size = 12; + break; + + case S7_TYPE_STRING: + size = 254; + break; + }; + + return size; +} + +//**************************************************************************** + +// Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams +// Enter TSAP in format ##.## in hex +// Return: the TSAP number in a word and decimal format +uint16_t S7_GetWordFromTSAP(string TSAP) +{ + short int pos = TSAP.find('.'); // find the delimiter into the source string + + if (pos == string::npos) + { // no delimiter was found, return 0 + return 0; + } + else + { // was found '.' + string first = TSAP.substr(0, pos); // get the first argument + string second = TSAP.substr(pos + 1, 2); // get the second argument + + // convert both TSAP arguments from hex (16) in string format to a number in decimal + char *p; // used in the strtol function + + uint8_t number1 = strtol(first.c_str(), &p, 16); // convert string with data in any base (10, 16) to long + uint8_t number2 = strtol(second.c_str(), &p, 16); // convert string with data in any base (10, 16) to long + + uint16_t res = number1 << 8 | number2; + + return res; } +} + +//**************************************************************************** +// Get Text message of Area Source +string S7_GetTxtAreaSource(int areaSource) +{ + switch (areaSource) + { + case S7_AREA_SOURCE_I: // Inputs + return "INPUTS"; + break; + + case S7_AREA_SOURCE_Q: // Outputs + return "OUTPUTS"; + break; + + case S7_AREA_SOURCE_M: // Memory Marks + return "Marks"; + break; + case S7_AREA_SOURCE_DB: // Data Block + return "DB"; + break; + + default: + return "Unkown Data Source"; + }; +} //**************************************************************************** // Get BDC and convert to byte -int S7_BDCToByte (byte B) +int S7_BDCToByte(byte B) { - return ((B >> 4) * 10 ) + (B & 0x0F); + return ((B >> 4) * 10) + (B & 0x0F); } //**************************************************************************** // Convert Byte to BDC -byte S7_ByteToBDC (int Value) +byte S7_ByteToBDC(int Value) { - return (byte) ((( Value /10 ) << 4) | (Value % 10)); + return (byte)(((Value / 10) << 4) | (Value % 10)); } //**************************************************************************** // Get Bit position at buffer of bytes, bits 0..7 -bool S7_GetBitAt ( byte Buffer[], int Pos, int Bit) +bool S7_GetBitAt(byte Buffer[], int Pos, int Bit) { - if (Bit < 0) Bit = 0; - if (Bit > 7) Bit = 7; + if (Bit < 0) + Bit = 0; + if (Bit > 7) + Bit = 7; return (Buffer[Pos] & Mask[Bit]) != 0; } - //**************************************************************************** // Set Bit position at buffer of bytes -void S7_SetBitAt ( byte Buffer[], int Pos, int Bit, bool Value) +void S7_SetBitAt(byte Buffer[], int Pos, int Bit, bool Value) { - if (Bit < 0) Bit = 0; - if (Bit > 7) Bit = 7; + if (Bit < 0) + Bit = 0; + if (Bit > 7) + Bit = 7; if (Value) - Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]); + Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]); else - Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]); + Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]); } //**************************************************************************** @@ -199,18 +200,17 @@ void S7_SetBitAt ( byte Buffer[], int Pos, int Bit, bool Value) // Get Byte (0..255) at buffer of bytes uint8_t S7_GetByteAt(byte Buffer[], int Pos) { - return Buffer[Pos] ; + return Buffer[Pos]; } //**************************************************************************** // Set Byte (0..255) at buffer of bytes -void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value ) +void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value) { - Buffer [Pos] = Value; + Buffer[Pos] = Value; } - //**************************************************************************** // Get SInt (-128..127) at buffer of bytes @@ -218,9 +218,9 @@ int8_t S7_GetSIntAt(byte Buffer[], int Pos) { int Value = Buffer[Pos]; if (Value < 128) - return Value; + return Value; else - return (int8_t) (Value - 256); + return (int8_t)(Value - 256); } //**************************************************************************** @@ -228,24 +228,26 @@ int8_t S7_GetSIntAt(byte Buffer[], int Pos) // Set SInt (-128..127) at buffer of bytes void S7_SetSIntAt(byte Buffer[], int Pos, int8_t Value) { - if (Value < -128) Value = -128; - if (Value > 127) Value = 127; + if (Value < -128) + Value = -128; + if (Value > 127) + Value = 127; Buffer[Pos] = (byte)Value; } //**************************************************************************** // Get 16 bit unsigned value (S7 UInt) 0..65535 - uint16_t S7_GetUIntAt(byte Buffer[], int Pos) +uint16_t S7_GetUIntAt(byte Buffer[], int Pos) { - return (uint16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); - } + return (uint16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); +} - //**************************************************************************** +//**************************************************************************** // Set 16 bit unsigned value (S7 UInt) 0..65535 -void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value ) +void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value) { Buffer[Pos] = (byte)(Value >> 8); Buffer[Pos + 1] = (byte)(Value & 0x00FF); @@ -253,27 +255,26 @@ void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value ) //**************************************************************************** - // Get 16 bit unsigned value (S7 Word) 0..65535 +// Get 16 bit unsigned value (S7 Word) 0..65535 uint16_t S7_GetWordAt(byte Buffer[], int Pos) { - return S7_GetUIntAt(Buffer, Pos) ; + return S7_GetUIntAt(Buffer, Pos); } //**************************************************************************** // Set 16 bit unsigned value (S7 Word) 0..65535 - void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value ) +void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value) { S7_SetUIntAt(Buffer, Pos, Value); - } - +} //**************************************************************************** // Get 16 bit signed value (S7 int) -32768..32767 at buffer of bytes int16_t S7_GetIntAt(byte Buffer[], int Pos) { - return (int16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); + return (int16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); } //**************************************************************************** @@ -292,9 +293,12 @@ void S7_SetIntAt(byte Buffer[], int Pos, int16_t Value) long S7_GetDIntAt(byte Buffer[], int Pos) { long Result; - Result = Buffer[Pos]; Result <<= 8; - Result += Buffer[Pos + 1]; Result <<= 8; - Result += Buffer[Pos + 2]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result += Buffer[Pos + 1]; + Result <<= 8; + Result += Buffer[Pos + 2]; + Result <<= 8; Result += Buffer[Pos + 3]; return Result; } @@ -317,9 +321,12 @@ void S7_SetDIntAt(byte Buffer[], int Pos, long Value) uint32_t S7_GetUDIntAt(byte Buffer[], int Pos) { uint32_t Result; - Result = Buffer[Pos]; Result <<= 8; - Result |= Buffer[Pos + 1]; Result <<= 8; - Result |= Buffer[Pos + 2]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result |= Buffer[Pos + 1]; + Result <<= 8; + Result |= Buffer[Pos + 2]; + Result <<= 8; Result |= Buffer[Pos + 3]; return Result; } @@ -336,13 +343,12 @@ void S7_SetUDIntAt(byte Buffer[], int Pos, uint32_t Value) Buffer[Pos] = (byte)((Value >> 24) & 0xFF); } - //**************************************************************************** // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 uint32_t S7_GetDWordAt(byte Buffer[], int Pos) { - return S7_GetUDIntAt (Buffer, Pos); + return S7_GetUDIntAt(Buffer, Pos); } //**************************************************************************** @@ -360,13 +366,20 @@ void S7_SetDWordAt(byte Buffer[], int Pos, uint32_t Value) uint64_t S7_GetULIntAt(byte Buffer[], int Pos) { uint64_t Result; - Result = Buffer[Pos]; Result <<= 8; - Result |= Buffer[Pos + 1]; Result <<= 8; - Result |= Buffer[Pos + 2]; Result <<= 8; - Result |= Buffer[Pos + 3]; Result <<= 8; - Result |= Buffer[Pos + 4]; Result <<= 8; - Result |= Buffer[Pos + 5]; Result <<= 8; - Result |= Buffer[Pos + 6]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result |= Buffer[Pos + 1]; + Result <<= 8; + Result |= Buffer[Pos + 2]; + Result <<= 8; + Result |= Buffer[Pos + 3]; + Result <<= 8; + Result |= Buffer[Pos + 4]; + Result <<= 8; + Result |= Buffer[Pos + 5]; + Result <<= 8; + Result |= Buffer[Pos + 6]; + Result <<= 8; Result |= Buffer[Pos + 7]; return Result; } @@ -374,7 +387,7 @@ uint64_t S7_GetULIntAt(byte Buffer[], int Pos) //**************************************************************************** // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - void S7_SetULIntAt(byte Buffer[], int Pos, uint64_t Value) +void S7_SetULIntAt(byte Buffer[], int Pos, uint64_t Value) { Buffer[Pos + 7] = (byte)(Value & 0xFF); Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF); @@ -384,24 +397,23 @@ uint64_t S7_GetULIntAt(byte Buffer[], int Pos) Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF); Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF); Buffer[Pos] = (byte)((Value >> 56) & 0xFF); - } - - //**************************************************************************** - // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +} - uint64_t S7_GetLWordAt(byte Buffer[], int Pos) - { - return S7_GetULIntAt (Buffer, Pos) ; - } +//**************************************************************************** +// Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - //**************************************************************************** - // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +uint64_t S7_GetLWordAt(byte Buffer[], int Pos) +{ + return S7_GetULIntAt(Buffer, Pos); +} - void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value) - { - S7_SetULIntAt ( Buffer, Pos, Value) ; - } +//**************************************************************************** +// Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value) +{ + S7_SetULIntAt(Buffer, Pos, Value); +} //**************************************************************************** @@ -409,13 +421,20 @@ uint64_t S7_GetULIntAt(byte Buffer[], int Pos) int64_t S7_GetLIntAt(byte Buffer[], int Pos) { int64_t Result; - Result = Buffer[Pos]; Result <<= 8; - Result += Buffer[Pos + 1]; Result <<= 8; - Result += Buffer[Pos + 2]; Result <<= 8; - Result += Buffer[Pos + 3]; Result <<= 8; - Result += Buffer[Pos + 4]; Result <<= 8; - Result += Buffer[Pos + 5]; Result <<= 8; - Result += Buffer[Pos + 6]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result += Buffer[Pos + 1]; + Result <<= 8; + Result += Buffer[Pos + 2]; + Result <<= 8; + Result += Buffer[Pos + 3]; + Result <<= 8; + Result += Buffer[Pos + 4]; + Result <<= 8; + Result += Buffer[Pos + 5]; + Result <<= 8; + Result += Buffer[Pos + 6]; + Result <<= 8; Result += Buffer[Pos + 7]; return Result; } @@ -425,55 +444,57 @@ int64_t S7_GetLIntAt(byte Buffer[], int Pos) // Set 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 void S7_SetLIntAt(byte Buffer[], int Pos, int64_t Value) { - Buffer[Pos + 7] = (byte)(Value & 0xFF); - Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF); - Buffer[Pos + 5] = (byte)((Value >> 16) & 0xFF); - Buffer[Pos + 4] = (byte)((Value >> 24) & 0xFF); - Buffer[Pos + 3] = (byte)((Value >> 32) & 0xFF); - Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF); - Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF); - Buffer[Pos] = (byte)((Value >> 56) & 0xFF); + Buffer[Pos + 7] = (byte)(Value & 0xFF); + Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF); + Buffer[Pos + 5] = (byte)((Value >> 16) & 0xFF); + Buffer[Pos + 4] = (byte)((Value >> 24) & 0xFF); + Buffer[Pos + 3] = (byte)((Value >> 32) & 0xFF); + Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF); + Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF); + Buffer[Pos] = (byte)((Value >> 56) & 0xFF); } //**************************************************************************** // Get 32 bit floating point number (S7 Real) (Range of float) float S7_GetRealAt(byte Buffer[], int Pos) { - uint32_t Pack = S7_GetUDIntAt(Buffer, Pos); - float Res; memcpy (&Res, &Pack, 4); - return Res; + uint32_t Pack = S7_GetUDIntAt(Buffer, Pos); + float Res; + memcpy(&Res, &Pack, 4); + return Res; } //**************************************************************************** // Set 32 bit floating point number (S7 Real) (Range of float) - void S7_SetRealAt(byte Buffer[], int Pos, float Value) - { +void S7_SetRealAt(byte Buffer[], int Pos, float Value) +{ - uint32_t Pack; - memcpy (&Pack, &Value, 4); - S7_SetUDIntAt (Buffer, Pos, Pack); - } + uint32_t Pack; + memcpy(&Pack, &Value, 4); + S7_SetUDIntAt(Buffer, Pos, Pack); +} - //**************************************************************************** +//**************************************************************************** - // Get 64 bit floating point number (S7 LReal) (Range of double) - double S7_GetLRealAt(byte Buffer[], int Pos) - { - uint64_t Pack = S7_GetULIntAt(Buffer, Pos) ; - double Res; memcpy (&Res, &Pack, 8); - return Res; - } +// Get 64 bit floating point number (S7 LReal) (Range of double) +double S7_GetLRealAt(byte Buffer[], int Pos) +{ + uint64_t Pack = S7_GetULIntAt(Buffer, Pos); + double Res; + memcpy(&Res, &Pack, 8); + return Res; +} - //**************************************************************************** +//**************************************************************************** - // Set 64 bit floating point number (S7 LReal) (Range of double) - void S7_SetLRealAt(byte Buffer[], int Pos, double Value) - { - uint64_t Pack; - memcpy (&Pack, &Value, 8); - S7_SetULIntAt (Buffer, Pos, Pack); - } +// Set 64 bit floating point number (S7 LReal) (Range of double) +void S7_SetLRealAt(byte Buffer[], int Pos, double Value) +{ + uint64_t Pack; + memcpy(&Pack, &Value, 8); + S7_SetULIntAt(Buffer, Pos, Pack); +} //**************************************************************************** // Get String (S7 String) @@ -482,232 +503,226 @@ float S7_GetRealAt(byte Buffer[], int Pos) // - 2nd byte: Current Length // - 3rd ... n byte: string characters - string S7_GetStringAt(byte Buffer[], int Pos) - { - string res; +string S7_GetStringAt(byte Buffer[], int Pos) +{ + string res; - int size = (int) Buffer[Pos + 1]; + int size = (int)Buffer[Pos + 1]; - res.insert (0, (char*) &Buffer[Pos+2],size); + res.insert(0, (char *)&Buffer[Pos + 2], size); - return res; - } + return res; +} - //**************************************************************************** - // Set String (S7 String) - // In Siemens the standard string has format: - // - 1st byte: Max Length - // - 2nd byte: Current Length - // - 3rd ... n byte: string characters +//**************************************************************************** +// Set String (S7 String) +// In Siemens the standard string has format: +// - 1st byte: Max Length +// - 2nd byte: Current Length +// - 3rd ... n byte: string characters - void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value) - { - int size = Value.size(); +void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value) +{ + int size = Value.size(); - Buffer[Pos] = (byte)MaxLen; - Buffer[Pos + 1] = (byte)size; + Buffer[Pos] = (byte)MaxLen; + Buffer[Pos + 1] = (byte)size; - Value.copy ((char*) &Buffer[Pos+2],size); - } + Value.copy((char *)&Buffer[Pos + 2], size); +} - //**************************************************************************** - //Get Array of char (S7 ARRAY OF CHARS) - string S7_GetCharsAt(byte Buffer[], int Pos, int Size) - { - string res; +//**************************************************************************** +// Get Array of char (S7 ARRAY OF CHARS) +string S7_GetCharsAt(byte Buffer[], int Pos, int Size) +{ + string res; - res.insert (0, (char*) &Buffer[Pos],Size); + res.insert(0, (char *)&Buffer[Pos], Size); - return res; - } + return res; +} #include - //**************************************************************************** - //Set Array of char (S7 ARRAY OF CHARS) - void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value) - { - int MaxLen = BufferLen - Pos; - int Size = Value.size(); - - cout << " Max Len: " << MaxLen << " Size: " << Size << endl; - - // Truncs the string if there's no room enough - if (Size > MaxLen) Size = MaxLen; +//**************************************************************************** +// Set Array of char (S7 ARRAY OF CHARS) +void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value) +{ + int MaxLen = BufferLen - Pos; + int Size = Value.size(); + cout << " Max Len: " << MaxLen << " Size: " << Size << endl; + // Truncs the string if there's no room enough + if (Size > MaxLen) + Size = MaxLen; - Value.copy ((char*) &Buffer[Pos],Size); - } + Value.copy((char *)&Buffer[Pos], Size); +} - //**************************************************************************** - // Get TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) - // TOD#0:0:0.0 to TOD#23:59 : 59.999 - // Time in steps of 1 ms - //https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW - TOD S7_GetTODAt(byte Buffer[], int Pos) - {// UNDONE: check result - uint32_t time = S7_GetUDIntAt(Buffer, Pos); - uint32_t msec = time % 1000; - time = (time - msec) / 1000; - uint32_t second = time % 60; - time = (time - second) / 60; - uint32_t minute = time % 60; - uint32_t hour = (time - minute) / 60; - - return TOD{ hour,minute,second,msec }; - } +//**************************************************************************** +// Get TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) +// TOD#0:0:0.0 to TOD#23:59 : 59.999 +// Time in steps of 1 ms +// https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW +TOD S7_GetTODAt(byte Buffer[], int Pos) +{ + uint32_t time = S7_GetUDIntAt(Buffer, Pos); + uint32_t msec = time % 1000; + time = (time - msec) / 1000; + uint32_t second = time % 60; + time = (time - second) / 60; + uint32_t minute = time % 60; + uint32_t hour = (time - minute) / 60; + + return TOD{hour, minute, second, msec}; +} - //**************************************************************************** - // Set TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) - // TOD#0:0:0.0 to TOD#23:59 : 59.999 - // Time in steps of 1 ms - //https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW - void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec ) - {// UNDONE: check result - uint32_t time = msec; - time += 1000 * second; - time += 60 * 1000 * minute; - time += 60 * 60 * 1000 * hour; - S7_SetUDIntAt(Buffer,Pos,time); - } +//**************************************************************************** +// Set TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) +// TOD#0:0:0.0 to TOD#23:59 : 59.999 +// Time in steps of 1 ms +// https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW +void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec) +{ + uint32_t time = msec; + time += 1000 * second; + time += 60 * 1000 * minute; + time += 60 * 60 * 1000 * hour; + S7_SetUDIntAt(Buffer, Pos, time); +} - //**************************************************************************** - // Get (Year-Month-Day) (S7 DATE) - // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. - // D#1990-1-1 to D#2168 - 12 - 31 - // IEC date in steps of 1 day - //https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL - //http://howardhinnant.github.io/date_algorithms.html#civil_from_days - DATE S7_GetDATEAt(byte Buffer[], int Pos) - {// UNDONE: check result - const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 - const unsigned era = z / 146097; - const unsigned doe = (z - era * 146097); // [0, 146096] - const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] - const unsigned y = yoe + era * 400; - const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] - const unsigned mp = (5 * doy + 2) / 153; // [0, 11] - const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] - const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] - - return DATE{ y + (m <= 2), m, d }; - } +//**************************************************************************** +// Get (Year-Month-Day) (S7 DATE) +// The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. +// D#1990-1-1 to D#2168 - 12 - 31 +// IEC date in steps of 1 day +// https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL +// http://howardhinnant.github.io/date_algorithms.html#civil_from_days +DATE S7_GetDATEAt(byte Buffer[], int Pos) +{ + const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 + const unsigned era = z / 146097; + const unsigned doe = (z - era * 146097); // [0, 146096] + const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] + const unsigned y = yoe + era * 400; + const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] + const unsigned mp = (5 * doy + 2) / 153; // [0, 11] + const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] + const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] + + return DATE{y + (m <= 2), m, d}; +} - //**************************************************************************** - // Set (Year-Month-Day) (S7 DATE) - // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. - // D#1990-1-1 to D#2168 - 12 - 31 - // IEC date in steps of 1 day - //https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL - //http://howardhinnant.github.io/date_algorithms.html#days_from_civil - void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day) - {// UNDONE: check result - year -= month <= 2; - const unsigned era = year / 400; - const unsigned yoe = static_cast(year - era * 400); // [0, 399] - const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] - const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - uint32_t Value= era * 146097 + static_cast(doe) - 726773; //[726773] (offset) days from 0000-03-01 to 1990-01-01 - S7_SetUIntAt(Buffer, Pos, Value); - } +//**************************************************************************** +// Set (Year-Month-Day) (S7 DATE) +// The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. +// D#1990-1-1 to D#2168 - 12 - 31 +// IEC date in steps of 1 day +// https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL +// http://howardhinnant.github.io/date_algorithms.html#days_from_civil +void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day) +{ + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t Value = era * 146097 + static_cast(doe) - 726773; //[726773] (offset) days from 0000-03-01 to 1990-01-01 + S7_SetUIntAt(Buffer, Pos, Value); +} - //**************************************************************************** - // Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) - // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. - // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 - //https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL - DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) - {// UNDONE: check result - uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 99] - year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 - uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] - uint16_t day = S7_BDCToByte(Buffer[Pos + 2]); // [1, 31] - uint16_t hour = S7_BDCToByte(Buffer[Pos + 3]); // [0, 23] - uint16_t minute = S7_BDCToByte(Buffer[Pos + 4]); // [0, 59] - uint16_t second = S7_BDCToByte(Buffer[Pos + 5]); // [0, 59] - uint16_t msec = S7_BDCToByte(Buffer[Pos + 6]) * 10 + ((Buffer[Pos + 7] >> 4) & 0x0F); // [0, 999] 7 (4MSB) - uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) - - return DATE_AND_TIME{ year, month, day, hour, minute, second, msec, weekday }; - } +//**************************************************************************** +// Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) +// The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. +// Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 +// https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL +DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) +{ + uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 99] + year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 + uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] + uint16_t day = S7_BDCToByte(Buffer[Pos + 2]); // [1, 31] + uint16_t hour = S7_BDCToByte(Buffer[Pos + 3]); // [0, 23] + uint16_t minute = S7_BDCToByte(Buffer[Pos + 4]); // [0, 59] + uint16_t second = S7_BDCToByte(Buffer[Pos + 5]); // [0, 59] + uint16_t msec = S7_BDCToByte(Buffer[Pos + 6]) * 10 + ((Buffer[Pos + 7] >> 4) & 0x0F); // [0, 999] 7 (4MSB) + uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) + + return DATE_AND_TIME{year, month, day, hour, minute, second, msec, weekday}; +} - //**************************************************************************** - // Set year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) - // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. - // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 - //https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL - void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) - {// UNDONE: check result - //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 - Buffer[Pos] = S7_ByteToBDC(year%100); // [0, 89] - Buffer[Pos + 1] = S7_ByteToBDC(month); // [1, 12] - Buffer[Pos + 2] = S7_ByteToBDC(day); // [1, 31] - Buffer[Pos + 3] = S7_ByteToBDC(hour); // [0, 23] - Buffer[Pos + 4] = S7_ByteToBDC(minute); // [0, 59] - Buffer[Pos + 5] = S7_ByteToBDC(second); // [0, 59] - Buffer[Pos + 6] = S7_ByteToBDC(msec/10); // [0, 99] - - - //weekday calculation - year -= month <= 2; - const unsigned era = year / 400; - const unsigned yoe = static_cast(year - era * 400); // [0, 399] - const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] - const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - uint32_t days = era * 146097 + static_cast(doe) - 726773; - uint8_t weekday = ((days + 1) % 7) + 1; //1990-01-01[Monday(1)] [1,7] - - Buffer[Pos + 7] = weekday; // [1, 7] - Buffer[Pos + 7] |= ((msec % 10) << 4); // [0, 9] - - - - } +//**************************************************************************** +// Set year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) +// The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. +// Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 +// https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL +void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) +{ + //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 + Buffer[Pos] = S7_ByteToBDC(year % 100); // [0, 89] + Buffer[Pos + 1] = S7_ByteToBDC(month); // [1, 12] + Buffer[Pos + 2] = S7_ByteToBDC(day); // [1, 31] + Buffer[Pos + 3] = S7_ByteToBDC(hour); // [0, 23] + Buffer[Pos + 4] = S7_ByteToBDC(minute); // [0, 59] + Buffer[Pos + 5] = S7_ByteToBDC(second); // [0, 59] + Buffer[Pos + 6] = S7_ByteToBDC(msec / 10); // [0, 99] + + // weekday calculation + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t days = era * 146097 + static_cast(doe) - 726773; + uint8_t weekday = ((days + 1) % 7) + 1; // 1990-01-01[Monday(1)] [1,7] + + Buffer[Pos + 7] = weekday; // [1, 7] + Buffer[Pos + 7] |= ((msec % 10) << 4); // [0, 9] +} - //**************************************************************************** - // Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) - // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. - // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - //https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL - DTL S7_GetDTLAt(byte Buffer[], int Pos) - {// UNDONE: check result - uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] - uint16_t month = static_cast(S7_GetByteAt(Buffer, Pos + 2)); // [1, 12] - uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] - uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] - uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] - uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] - uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] - uint32_t nanosec = S7_GetUDIntAt(Buffer, Pos + 8); // [0, 999999999] - - return DTL{ year, month, day, weekday, hour, minute, second, nanosec }; - } +//**************************************************************************** +// Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) +// An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. +// Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 +// https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL +DTL S7_GetDTLAt(byte Buffer[], int Pos) +{ + uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] + uint16_t month = static_cast(S7_GetByteAt(Buffer, Pos + 2)); // [1, 12] + uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] + uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] + uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] + uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] + uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] + uint32_t nanosec = S7_GetUDIntAt(Buffer, Pos + 8); // [0, 999999999] + + return DTL{year, month, day, weekday, hour, minute, second, nanosec}; +} - //**************************************************************************** - // Set Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) - // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. - // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - //https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL - void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec) - {// UNDONE: check result - S7_SetUIntAt(Buffer,Pos,year); // 1970, 2262] - S7_SetByteAt(Buffer,Pos + 2,month); // [1, 12] - S7_SetByteAt(Buffer, Pos + 3,day); // [1, 31] - - //weekday calculation - year -= month <= 2; - const unsigned era = year / 400; - const unsigned yoe = static_cast(year - era * 400); // [0, 399] - const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] - const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - uint32_t days = era * 146097 + static_cast(doe) - 726773; - uint8_t weekday = ((days + 1) % 7) + 1; //1990-01-01[Monday(1)] [1,7] - - S7_SetByteAt(Buffer, Pos + 4, weekday); // [1, 7] - S7_SetByteAt(Buffer, Pos + 5,hour); // [0, 23] - S7_SetByteAt(Buffer, Pos + 6,minute); // [0, 59] - S7_SetByteAt(Buffer, Pos + 7,second); // [0, 59] - S7_SetUDIntAt(Buffer,Pos + 8,nanosec); // [0, 999999999] - - } \ No newline at end of file +//**************************************************************************** +// Set Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) +// An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. +// Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 +// https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL +void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec) +{ + S7_SetUIntAt(Buffer, Pos, year); // 1970, 2262] + S7_SetByteAt(Buffer, Pos + 2, month); // [1, 12] + S7_SetByteAt(Buffer, Pos + 3, day); // [1, 31] + + // weekday calculation + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t days = era * 146097 + static_cast(doe) - 726773; + uint8_t weekday = ((days + 1) % 7) + 1; // 1990-01-01[Monday(1)] [1,7] + + S7_SetByteAt(Buffer, Pos + 4, weekday); // [1, 7] + S7_SetByteAt(Buffer, Pos + 5, hour); // [0, 23] + S7_SetByteAt(Buffer, Pos + 6, minute); // [0, 59] + S7_SetByteAt(Buffer, Pos + 7, second); // [0, 59] + S7_SetUDIntAt(Buffer, Pos + 8, nanosec); // [0, 999999999] +} \ No newline at end of file From 69995c01574bf5261e12a484bbbc7c9f7af4f5bd Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Mon, 15 May 2023 06:24:18 +0200 Subject: [PATCH 12/13] UNDONE comments delete & autoformat --- s7.cpp | 857 +++++++++++++++++++++++++++++---------------------------- s7.h | 187 +++++++------ 2 files changed, 545 insertions(+), 499 deletions(-) diff --git a/s7.cpp b/s7.cpp index daa09db..0aac226 100644 --- a/s7.cpp +++ b/s7.cpp @@ -13,185 +13,186 @@ #include "s7.h" #include "string.h" // for memcpy - using namespace std; -static byte Mask[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; +static byte Mask[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; //**************************************************************************** // Get Text description of PLC Type -string S7_GetTxtPLCType (short int plcType) +string S7_GetTxtPLCType(short int plcType) { switch (plcType) { - case S7_PLC_300_400: - return "S7 300/400"; - break; + case S7_PLC_300_400: + return "S7 300/400"; + break; - case S7_PLC_1200_1500: - return "S7 1200/1500"; - break; + case S7_PLC_1200_1500: + return "S7 1200/1500"; + break; - case S7_PLC_LOGO_200: - return "LOGO/S7 200"; - break; + case S7_PLC_LOGO_200: + return "LOGO/S7 200"; + break; - case S7_PLC_SINAMICS: - return "SINAMICS"; - break; + case S7_PLC_SINAMICS: + return "SINAMICS"; + break; } } //**************************************************************************** // Get data type size in bytes of the specified type - int S7_GetDataTypeSize (int type) +int S7_GetDataTypeSize(int type) { - int size =0; // for unkown type return 0 + int size = 0; // for unkown type return 0 - switch (type) - { - case S7_TYPE_BOOL: - case S7_TYPE_BYTE: - case S7_TYPE_SINT: - size = 1; - break; - - case S7_TYPE_WORD: - case S7_TYPE_UINT: - case S7_TYPE_INT: - case S7_TYPE_DATE: - size = 2; - break; - - case S7_TYPE_DWORD: - case S7_TYPE_UDINT: - case S7_TYPE_DINT: - case S7_TYPE_REAL: - case S7_TYPE_TOD: - size = 4; - break; - - case S7_TYPE_LWORD: - case S7_TYPE_ULINT: - case S7_TYPE_LINT: - case S7_TYPE_LREAL: - case S7_TYPE_DATE_AND_TIME: - size = 8; - break; - - case S7_TYPE_DTL: - size = 12; - break; - - case S7_TYPE_STRING: - size = 254; - break; - - }; - - return size; - } - - //**************************************************************************** - - // Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams - // Enter TSAP in format ##.## in hex - // Return: the TSAP number in a word and decimal format - uint16_t S7_GetWordFromTSAP ( string TSAP) - { - short int pos = TSAP.find ('.'); // find the delimiter into the source string - - if (pos == string::npos) {// no delimiter was found, return 0 - return 0; - } - else { // was found '.' - string first = TSAP.substr (0,pos); // get the first argument - string second = TSAP.substr (pos+1,2) ; // get the second argument - - // convert both TSAP arguments from hex (16) in string format to a number in decimal - char* p; // used in the strtol function - - uint8_t number1 = strtol(first.c_str(), &p, 16); // convert string with data in any base (10, 16) to long - uint8_t number2 = strtol(second.c_str(), &p, 16); // convert string with data in any base (10, 16) to long - - uint16_t res = number1 << 8 | number2; - - return res; - } - - } - - //**************************************************************************** - // Get Text message of Area Source - string S7_GetTxtAreaSource (int areaSource) + switch (type) { - switch (areaSource) - { - case S7_AREA_SOURCE_I: // Inputs - return "INPUTS"; - break; - - case S7_AREA_SOURCE_Q: // Outputs - return "OUTPUTS"; - break; - - case S7_AREA_SOURCE_M: // Memory Marks - return "Marks"; - break; - - case S7_AREA_SOURCE_DB: // Data Block - return "DB"; - break; - - default: - return "Unkown Data Source"; - }; + case S7_TYPE_BOOL: + case S7_TYPE_BYTE: + case S7_TYPE_SINT: + size = 1; + break; + + case S7_TYPE_WORD: + case S7_TYPE_UINT: + case S7_TYPE_INT: + case S7_TYPE_DATE: + size = 2; + break; + + case S7_TYPE_DWORD: + case S7_TYPE_UDINT: + case S7_TYPE_DINT: + case S7_TYPE_REAL: + case S7_TYPE_TOD: + size = 4; + break; + + case S7_TYPE_LWORD: + case S7_TYPE_ULINT: + case S7_TYPE_LINT: + case S7_TYPE_LREAL: + case S7_TYPE_DATE_AND_TIME: + size = 8; + break; + + case S7_TYPE_DTL: + size = 12; + break; + + case S7_TYPE_STRING: + size = 254; + break; + }; + + return size; +} + +//**************************************************************************** + +// Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams +// Enter TSAP in format ##.## in hex +// Return: the TSAP number in a word and decimal format +uint16_t S7_GetWordFromTSAP(string TSAP) +{ + short int pos = TSAP.find('.'); // find the delimiter into the source string + + if (pos == string::npos) + { // no delimiter was found, return 0 + return 0; + } + else + { // was found '.' + string first = TSAP.substr(0, pos); // get the first argument + string second = TSAP.substr(pos + 1, 2); // get the second argument + + // convert both TSAP arguments from hex (16) in string format to a number in decimal + char *p; // used in the strtol function + + uint8_t number1 = strtol(first.c_str(), &p, 16); // convert string with data in any base (10, 16) to long + uint8_t number2 = strtol(second.c_str(), &p, 16); // convert string with data in any base (10, 16) to long + + uint16_t res = number1 << 8 | number2; + + return res; } +} + +//**************************************************************************** +// Get Text message of Area Source +string S7_GetTxtAreaSource(int areaSource) +{ + switch (areaSource) + { + case S7_AREA_SOURCE_I: // Inputs + return "INPUTS"; + break; + + case S7_AREA_SOURCE_Q: // Outputs + return "OUTPUTS"; + break; + + case S7_AREA_SOURCE_M: // Memory Marks + return "Marks"; + break; + case S7_AREA_SOURCE_DB: // Data Block + return "DB"; + break; + + default: + return "Unkown Data Source"; + }; +} //**************************************************************************** // Get BDC and convert to byte -int S7_BDCToByte (byte B) +int S7_BDCToByte(byte B) { - return ((B >> 4) * 10 ) + (B & 0x0F); + return ((B >> 4) * 10) + (B & 0x0F); } //**************************************************************************** // Convert Byte to BDC -byte S7_ByteToBDC (int Value) +byte S7_ByteToBDC(int Value) { - return (byte) ((( Value /10 ) << 4) | (Value % 10)); + return (byte)(((Value / 10) << 4) | (Value % 10)); } //**************************************************************************** // Get Bit position at buffer of bytes, bits 0..7 -bool S7_GetBitAt ( byte Buffer[], int Pos, int Bit) +bool S7_GetBitAt(byte Buffer[], int Pos, int Bit) { - if (Bit < 0) Bit = 0; - if (Bit > 7) Bit = 7; + if (Bit < 0) + Bit = 0; + if (Bit > 7) + Bit = 7; return (Buffer[Pos] & Mask[Bit]) != 0; } - //**************************************************************************** // Set Bit position at buffer of bytes -void S7_SetBitAt ( byte Buffer[], int Pos, int Bit, bool Value) +void S7_SetBitAt(byte Buffer[], int Pos, int Bit, bool Value) { - if (Bit < 0) Bit = 0; - if (Bit > 7) Bit = 7; + if (Bit < 0) + Bit = 0; + if (Bit > 7) + Bit = 7; if (Value) - Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]); + Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]); else - Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]); + Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]); } //**************************************************************************** @@ -199,18 +200,17 @@ void S7_SetBitAt ( byte Buffer[], int Pos, int Bit, bool Value) // Get Byte (0..255) at buffer of bytes uint8_t S7_GetByteAt(byte Buffer[], int Pos) { - return Buffer[Pos] ; + return Buffer[Pos]; } //**************************************************************************** // Set Byte (0..255) at buffer of bytes -void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value ) +void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value) { - Buffer [Pos] = Value; + Buffer[Pos] = Value; } - //**************************************************************************** // Get SInt (-128..127) at buffer of bytes @@ -218,9 +218,9 @@ int8_t S7_GetSIntAt(byte Buffer[], int Pos) { int Value = Buffer[Pos]; if (Value < 128) - return Value; + return Value; else - return (int8_t) (Value - 256); + return (int8_t)(Value - 256); } //**************************************************************************** @@ -228,24 +228,26 @@ int8_t S7_GetSIntAt(byte Buffer[], int Pos) // Set SInt (-128..127) at buffer of bytes void S7_SetSIntAt(byte Buffer[], int Pos, int8_t Value) { - if (Value < -128) Value = -128; - if (Value > 127) Value = 127; + if (Value < -128) + Value = -128; + if (Value > 127) + Value = 127; Buffer[Pos] = (byte)Value; } //**************************************************************************** // Get 16 bit unsigned value (S7 UInt) 0..65535 - uint16_t S7_GetUIntAt(byte Buffer[], int Pos) +uint16_t S7_GetUIntAt(byte Buffer[], int Pos) { - return (uint16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); - } + return (uint16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); +} - //**************************************************************************** +//**************************************************************************** // Set 16 bit unsigned value (S7 UInt) 0..65535 -void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value ) +void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value) { Buffer[Pos] = (byte)(Value >> 8); Buffer[Pos + 1] = (byte)(Value & 0x00FF); @@ -253,27 +255,26 @@ void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value ) //**************************************************************************** - // Get 16 bit unsigned value (S7 Word) 0..65535 +// Get 16 bit unsigned value (S7 Word) 0..65535 uint16_t S7_GetWordAt(byte Buffer[], int Pos) { - return S7_GetUIntAt(Buffer, Pos) ; + return S7_GetUIntAt(Buffer, Pos); } //**************************************************************************** // Set 16 bit unsigned value (S7 Word) 0..65535 - void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value ) +void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value) { S7_SetUIntAt(Buffer, Pos, Value); - } - +} //**************************************************************************** // Get 16 bit signed value (S7 int) -32768..32767 at buffer of bytes int16_t S7_GetIntAt(byte Buffer[], int Pos) { - return (int16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); + return (int16_t)((Buffer[Pos] << 8) | Buffer[Pos + 1]); } //**************************************************************************** @@ -292,9 +293,12 @@ void S7_SetIntAt(byte Buffer[], int Pos, int16_t Value) long S7_GetDIntAt(byte Buffer[], int Pos) { long Result; - Result = Buffer[Pos]; Result <<= 8; - Result += Buffer[Pos + 1]; Result <<= 8; - Result += Buffer[Pos + 2]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result += Buffer[Pos + 1]; + Result <<= 8; + Result += Buffer[Pos + 2]; + Result <<= 8; Result += Buffer[Pos + 3]; return Result; } @@ -317,9 +321,12 @@ void S7_SetDIntAt(byte Buffer[], int Pos, long Value) uint32_t S7_GetUDIntAt(byte Buffer[], int Pos) { uint32_t Result; - Result = Buffer[Pos]; Result <<= 8; - Result |= Buffer[Pos + 1]; Result <<= 8; - Result |= Buffer[Pos + 2]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result |= Buffer[Pos + 1]; + Result <<= 8; + Result |= Buffer[Pos + 2]; + Result <<= 8; Result |= Buffer[Pos + 3]; return Result; } @@ -336,13 +343,12 @@ void S7_SetUDIntAt(byte Buffer[], int Pos, uint32_t Value) Buffer[Pos] = (byte)((Value >> 24) & 0xFF); } - //**************************************************************************** // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 uint32_t S7_GetDWordAt(byte Buffer[], int Pos) { - return S7_GetUDIntAt (Buffer, Pos); + return S7_GetUDIntAt(Buffer, Pos); } //**************************************************************************** @@ -360,13 +366,20 @@ void S7_SetDWordAt(byte Buffer[], int Pos, uint32_t Value) uint64_t S7_GetULIntAt(byte Buffer[], int Pos) { uint64_t Result; - Result = Buffer[Pos]; Result <<= 8; - Result |= Buffer[Pos + 1]; Result <<= 8; - Result |= Buffer[Pos + 2]; Result <<= 8; - Result |= Buffer[Pos + 3]; Result <<= 8; - Result |= Buffer[Pos + 4]; Result <<= 8; - Result |= Buffer[Pos + 5]; Result <<= 8; - Result |= Buffer[Pos + 6]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result |= Buffer[Pos + 1]; + Result <<= 8; + Result |= Buffer[Pos + 2]; + Result <<= 8; + Result |= Buffer[Pos + 3]; + Result <<= 8; + Result |= Buffer[Pos + 4]; + Result <<= 8; + Result |= Buffer[Pos + 5]; + Result <<= 8; + Result |= Buffer[Pos + 6]; + Result <<= 8; Result |= Buffer[Pos + 7]; return Result; } @@ -374,7 +387,7 @@ uint64_t S7_GetULIntAt(byte Buffer[], int Pos) //**************************************************************************** // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - void S7_SetULIntAt(byte Buffer[], int Pos, uint64_t Value) +void S7_SetULIntAt(byte Buffer[], int Pos, uint64_t Value) { Buffer[Pos + 7] = (byte)(Value & 0xFF); Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF); @@ -384,24 +397,23 @@ uint64_t S7_GetULIntAt(byte Buffer[], int Pos) Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF); Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF); Buffer[Pos] = (byte)((Value >> 56) & 0xFF); - } - - //**************************************************************************** - // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +} - uint64_t S7_GetLWordAt(byte Buffer[], int Pos) - { - return S7_GetULIntAt (Buffer, Pos) ; - } +//**************************************************************************** +// Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - //**************************************************************************** - // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +uint64_t S7_GetLWordAt(byte Buffer[], int Pos) +{ + return S7_GetULIntAt(Buffer, Pos); +} - void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value) - { - S7_SetULIntAt ( Buffer, Pos, Value) ; - } +//**************************************************************************** +// Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value) +{ + S7_SetULIntAt(Buffer, Pos, Value); +} //**************************************************************************** @@ -409,13 +421,20 @@ uint64_t S7_GetULIntAt(byte Buffer[], int Pos) int64_t S7_GetLIntAt(byte Buffer[], int Pos) { int64_t Result; - Result = Buffer[Pos]; Result <<= 8; - Result += Buffer[Pos + 1]; Result <<= 8; - Result += Buffer[Pos + 2]; Result <<= 8; - Result += Buffer[Pos + 3]; Result <<= 8; - Result += Buffer[Pos + 4]; Result <<= 8; - Result += Buffer[Pos + 5]; Result <<= 8; - Result += Buffer[Pos + 6]; Result <<= 8; + Result = Buffer[Pos]; + Result <<= 8; + Result += Buffer[Pos + 1]; + Result <<= 8; + Result += Buffer[Pos + 2]; + Result <<= 8; + Result += Buffer[Pos + 3]; + Result <<= 8; + Result += Buffer[Pos + 4]; + Result <<= 8; + Result += Buffer[Pos + 5]; + Result <<= 8; + Result += Buffer[Pos + 6]; + Result <<= 8; Result += Buffer[Pos + 7]; return Result; } @@ -425,55 +444,57 @@ int64_t S7_GetLIntAt(byte Buffer[], int Pos) // Set 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 void S7_SetLIntAt(byte Buffer[], int Pos, int64_t Value) { - Buffer[Pos + 7] = (byte)(Value & 0xFF); - Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF); - Buffer[Pos + 5] = (byte)((Value >> 16) & 0xFF); - Buffer[Pos + 4] = (byte)((Value >> 24) & 0xFF); - Buffer[Pos + 3] = (byte)((Value >> 32) & 0xFF); - Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF); - Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF); - Buffer[Pos] = (byte)((Value >> 56) & 0xFF); + Buffer[Pos + 7] = (byte)(Value & 0xFF); + Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF); + Buffer[Pos + 5] = (byte)((Value >> 16) & 0xFF); + Buffer[Pos + 4] = (byte)((Value >> 24) & 0xFF); + Buffer[Pos + 3] = (byte)((Value >> 32) & 0xFF); + Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF); + Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF); + Buffer[Pos] = (byte)((Value >> 56) & 0xFF); } //**************************************************************************** // Get 32 bit floating point number (S7 Real) (Range of float) float S7_GetRealAt(byte Buffer[], int Pos) { - uint32_t Pack = S7_GetUDIntAt(Buffer, Pos); - float Res; memcpy (&Res, &Pack, 4); - return Res; + uint32_t Pack = S7_GetUDIntAt(Buffer, Pos); + float Res; + memcpy(&Res, &Pack, 4); + return Res; } //**************************************************************************** // Set 32 bit floating point number (S7 Real) (Range of float) - void S7_SetRealAt(byte Buffer[], int Pos, float Value) - { +void S7_SetRealAt(byte Buffer[], int Pos, float Value) +{ - uint32_t Pack; - memcpy (&Pack, &Value, 4); - S7_SetUDIntAt (Buffer, Pos, Pack); - } + uint32_t Pack; + memcpy(&Pack, &Value, 4); + S7_SetUDIntAt(Buffer, Pos, Pack); +} - //**************************************************************************** +//**************************************************************************** - // Get 64 bit floating point number (S7 LReal) (Range of double) - double S7_GetLRealAt(byte Buffer[], int Pos) - { - uint64_t Pack = S7_GetULIntAt(Buffer, Pos) ; - double Res; memcpy (&Res, &Pack, 8); - return Res; - } +// Get 64 bit floating point number (S7 LReal) (Range of double) +double S7_GetLRealAt(byte Buffer[], int Pos) +{ + uint64_t Pack = S7_GetULIntAt(Buffer, Pos); + double Res; + memcpy(&Res, &Pack, 8); + return Res; +} - //**************************************************************************** +//**************************************************************************** - // Set 64 bit floating point number (S7 LReal) (Range of double) - void S7_SetLRealAt(byte Buffer[], int Pos, double Value) - { - uint64_t Pack; - memcpy (&Pack, &Value, 8); - S7_SetULIntAt (Buffer, Pos, Pack); - } +// Set 64 bit floating point number (S7 LReal) (Range of double) +void S7_SetLRealAt(byte Buffer[], int Pos, double Value) +{ + uint64_t Pack; + memcpy(&Pack, &Value, 8); + S7_SetULIntAt(Buffer, Pos, Pack); +} //**************************************************************************** // Get String (S7 String) @@ -482,232 +503,226 @@ float S7_GetRealAt(byte Buffer[], int Pos) // - 2nd byte: Current Length // - 3rd ... n byte: string characters - string S7_GetStringAt(byte Buffer[], int Pos) - { - string res; +string S7_GetStringAt(byte Buffer[], int Pos) +{ + string res; - int size = (int) Buffer[Pos + 1]; + int size = (int)Buffer[Pos + 1]; - res.insert (0, (char*) &Buffer[Pos+2],size); + res.insert(0, (char *)&Buffer[Pos + 2], size); - return res; - } + return res; +} - //**************************************************************************** - // Set String (S7 String) - // In Siemens the standard string has format: - // - 1st byte: Max Length - // - 2nd byte: Current Length - // - 3rd ... n byte: string characters +//**************************************************************************** +// Set String (S7 String) +// In Siemens the standard string has format: +// - 1st byte: Max Length +// - 2nd byte: Current Length +// - 3rd ... n byte: string characters - void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value) - { - int size = Value.size(); +void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value) +{ + int size = Value.size(); - Buffer[Pos] = (byte)MaxLen; - Buffer[Pos + 1] = (byte)size; + Buffer[Pos] = (byte)MaxLen; + Buffer[Pos + 1] = (byte)size; - Value.copy ((char*) &Buffer[Pos+2],size); - } + Value.copy((char *)&Buffer[Pos + 2], size); +} - //**************************************************************************** - //Get Array of char (S7 ARRAY OF CHARS) - string S7_GetCharsAt(byte Buffer[], int Pos, int Size) - { - string res; +//**************************************************************************** +// Get Array of char (S7 ARRAY OF CHARS) +string S7_GetCharsAt(byte Buffer[], int Pos, int Size) +{ + string res; - res.insert (0, (char*) &Buffer[Pos],Size); + res.insert(0, (char *)&Buffer[Pos], Size); - return res; - } + return res; +} #include - //**************************************************************************** - //Set Array of char (S7 ARRAY OF CHARS) - void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value) - { - int MaxLen = BufferLen - Pos; - int Size = Value.size(); - - cout << " Max Len: " << MaxLen << " Size: " << Size << endl; - - // Truncs the string if there's no room enough - if (Size > MaxLen) Size = MaxLen; +//**************************************************************************** +// Set Array of char (S7 ARRAY OF CHARS) +void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value) +{ + int MaxLen = BufferLen - Pos; + int Size = Value.size(); + cout << " Max Len: " << MaxLen << " Size: " << Size << endl; + // Truncs the string if there's no room enough + if (Size > MaxLen) + Size = MaxLen; - Value.copy ((char*) &Buffer[Pos],Size); - } + Value.copy((char *)&Buffer[Pos], Size); +} - //**************************************************************************** - // Get TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) - // TOD#0:0:0.0 to TOD#23:59 : 59.999 - // Time in steps of 1 ms - //https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW - TOD S7_GetTODAt(byte Buffer[], int Pos) - {// UNDONE: check result - uint32_t time = S7_GetUDIntAt(Buffer, Pos); - uint32_t msec = time % 1000; - time = (time - msec) / 1000; - uint32_t second = time % 60; - time = (time - second) / 60; - uint32_t minute = time % 60; - uint32_t hour = (time - minute) / 60; - - return TOD{ hour,minute,second,msec }; - } +//**************************************************************************** +// Get TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) +// TOD#0:0:0.0 to TOD#23:59 : 59.999 +// Time in steps of 1 ms +// https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW +TOD S7_GetTODAt(byte Buffer[], int Pos) +{ + uint32_t time = S7_GetUDIntAt(Buffer, Pos); + uint32_t msec = time % 1000; + time = (time - msec) / 1000; + uint32_t second = time % 60; + time = (time - second) / 60; + uint32_t minute = time % 60; + uint32_t hour = (time - minute) / 60; + + return TOD{hour, minute, second, msec}; +} - //**************************************************************************** - // Set TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) - // TOD#0:0:0.0 to TOD#23:59 : 59.999 - // Time in steps of 1 ms - //https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW - void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec ) - {// UNDONE: check result - uint32_t time = msec; - time += 1000 * second; - time += 60 * 1000 * minute; - time += 60 * 60 * 1000 * hour; - S7_SetUDIntAt(Buffer,Pos,time); - } +//**************************************************************************** +// Set TIME_OF_DAY hour:minute:second:millisecond (S7 TOD) +// TOD#0:0:0.0 to TOD#23:59 : 59.999 +// Time in steps of 1 ms +// https://support.industry.siemens.com/cs/mdm/109773506?c=64869849355&lc=en-WW +void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec) +{ + uint32_t time = msec; + time += 1000 * second; + time += 60 * 1000 * minute; + time += 60 * 60 * 1000 * hour; + S7_SetUDIntAt(Buffer, Pos, time); +} - //**************************************************************************** - // Get (Year-Month-Day) (S7 DATE) - // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. - // D#1990-1-1 to D#2168 - 12 - 31 - // IEC date in steps of 1 day - //https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL - //http://howardhinnant.github.io/date_algorithms.html#civil_from_days - DATE S7_GetDATEAt(byte Buffer[], int Pos) - {// UNDONE: check result - const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 - const unsigned era = z / 146097; - const unsigned doe = (z - era * 146097); // [0, 146096] - const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] - const unsigned y = yoe + era * 400; - const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] - const unsigned mp = (5 * doy + 2) / 153; // [0, 11] - const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] - const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] - - return DATE{ y + (m <= 2), m, d }; - } +//**************************************************************************** +// Get (Year-Month-Day) (S7 DATE) +// The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. +// D#1990-1-1 to D#2168 - 12 - 31 +// IEC date in steps of 1 day +// https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL +// http://howardhinnant.github.io/date_algorithms.html#civil_from_days +DATE S7_GetDATEAt(byte Buffer[], int Pos) +{ + const unsigned z = S7_GetUIntAt(Buffer, Pos) + 726773; //(offset) days from 0000-03-01 to 1990-01-01 + const unsigned era = z / 146097; + const unsigned doe = (z - era * 146097); // [0, 146096] + const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] + const unsigned y = yoe + era * 400; + const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] + const unsigned mp = (5 * doy + 2) / 153; // [0, 11] + const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] + const unsigned m = mp < 10 ? mp + 3 : mp - 9; // [1, 12] + + return DATE{y + (m <= 2), m, d}; +} - //**************************************************************************** - // Set (Year-Month-Day) (S7 DATE) - // The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. - // D#1990-1-1 to D#2168 - 12 - 31 - // IEC date in steps of 1 day - //https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL - //http://howardhinnant.github.io/date_algorithms.html#days_from_civil - void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day) - {// UNDONE: check result - year -= month <= 2; - const unsigned era = year / 400; - const unsigned yoe = static_cast(year - era * 400); // [0, 399] - const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] - const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - uint32_t Value= era * 146097 + static_cast(doe) - 726773; //[726773] (offset) days from 0000-03-01 to 1990-01-01 - S7_SetUIntAt(Buffer, Pos, Value); - } +//**************************************************************************** +// Set (Year-Month-Day) (S7 DATE) +// The DATE data type saves the date as an unsigned integer. The representation contains the year, the month, and the day. +// D#1990-1-1 to D#2168 - 12 - 31 +// IEC date in steps of 1 day +// https://support.industry.siemens.com/cs/mdm/109773506?c=104323664139&lc=en-PL +// http://howardhinnant.github.io/date_algorithms.html#days_from_civil +void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day) +{ + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t Value = era * 146097 + static_cast(doe) - 726773; //[726773] (offset) days from 0000-03-01 to 1990-01-01 + S7_SetUIntAt(Buffer, Pos, Value); +} - //**************************************************************************** - // Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) - // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. - // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 - //https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL - DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) - {// UNDONE: check result - uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 99] - year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 - uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] - uint16_t day = S7_BDCToByte(Buffer[Pos + 2]); // [1, 31] - uint16_t hour = S7_BDCToByte(Buffer[Pos + 3]); // [0, 23] - uint16_t minute = S7_BDCToByte(Buffer[Pos + 4]); // [0, 59] - uint16_t second = S7_BDCToByte(Buffer[Pos + 5]); // [0, 59] - uint16_t msec = S7_BDCToByte(Buffer[Pos + 6]) * 10 + ((Buffer[Pos + 7] >> 4) & 0x0F); // [0, 999] 7 (4MSB) - uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) - - return DATE_AND_TIME{ year, month, day, hour, minute, second, msec, weekday }; - } +//**************************************************************************** +// Get year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) +// The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. +// Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 +// https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL +DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos) +{ + uint16_t year = S7_BDCToByte(Buffer[Pos]); // [0, 99] + year += (year >= 90 ? 1900 : 2000); //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 + uint16_t month = S7_BDCToByte(Buffer[Pos + 1]); // [1, 12] + uint16_t day = S7_BDCToByte(Buffer[Pos + 2]); // [1, 31] + uint16_t hour = S7_BDCToByte(Buffer[Pos + 3]); // [0, 23] + uint16_t minute = S7_BDCToByte(Buffer[Pos + 4]); // [0, 59] + uint16_t second = S7_BDCToByte(Buffer[Pos + 5]); // [0, 59] + uint16_t msec = S7_BDCToByte(Buffer[Pos + 6]) * 10 + ((Buffer[Pos + 7] >> 4) & 0x0F); // [0, 999] 7 (4MSB) + uint16_t weekday = (Buffer[Pos + 7] & 0x0F); //[1, 7]; #1 = Sunday; #7 = Saturday 7 (4LSB) + + return DATE_AND_TIME{year, month, day, hour, minute, second, msec, weekday}; +} - //**************************************************************************** - // Set year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) - // The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. - // Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 - //https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL - void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) - {// UNDONE: check result - //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 - Buffer[Pos] = S7_ByteToBDC(year%100); // [0, 89] - Buffer[Pos + 1] = S7_ByteToBDC(month); // [1, 12] - Buffer[Pos + 2] = S7_ByteToBDC(day); // [1, 31] - Buffer[Pos + 3] = S7_ByteToBDC(hour); // [0, 23] - Buffer[Pos + 4] = S7_ByteToBDC(minute); // [0, 59] - Buffer[Pos + 5] = S7_ByteToBDC(second); // [0, 59] - Buffer[Pos + 6] = S7_ByteToBDC(msec/10); // [0, 99] - - - //weekday calculation - year -= month <= 2; - const unsigned era = year / 400; - const unsigned yoe = static_cast(year - era * 400); // [0, 399] - const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] - const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - uint32_t days = era * 146097 + static_cast(doe) - 726773; - uint8_t weekday = ((days + 1) % 7) + 1; //1990-01-01[Monday(1)] [1,7] - - Buffer[Pos + 7] = weekday; // [1, 7] - Buffer[Pos + 7] |= ((msec % 10) << 4); // [0, 9] - - - - } +//**************************************************************************** +// Set year - month - day - hour:minute:second:millisecond (S7 DATE_AND_TIME) +// The DT (DATE_AND_TIME) data type saves the information on date and time of day in BCD format. +// Min.: DT#1990-01-01-00:00:00.000 Max.: DT#2089 - 12 - 31 - 23:59 : 59.999 +// https://support.industry.siemens.com/cs/mdm/109773506?c=85672757259&lc=en-PL +void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec) +{ + //(Years // [1990, 2089]); BCD#90 = 1990; (...) BCD#0 = 2000; (...) BCD#89 = 2089 + Buffer[Pos] = S7_ByteToBDC(year % 100); // [0, 89] + Buffer[Pos + 1] = S7_ByteToBDC(month); // [1, 12] + Buffer[Pos + 2] = S7_ByteToBDC(day); // [1, 31] + Buffer[Pos + 3] = S7_ByteToBDC(hour); // [0, 23] + Buffer[Pos + 4] = S7_ByteToBDC(minute); // [0, 59] + Buffer[Pos + 5] = S7_ByteToBDC(second); // [0, 59] + Buffer[Pos + 6] = S7_ByteToBDC(msec / 10); // [0, 99] + + // weekday calculation + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t days = era * 146097 + static_cast(doe) - 726773; + uint8_t weekday = ((days + 1) % 7) + 1; // 1990-01-01[Monday(1)] [1,7] + + Buffer[Pos + 7] = weekday; // [1, 7] + Buffer[Pos + 7] |= ((msec % 10) << 4); // [0, 9] +} - //**************************************************************************** - // Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) - // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. - // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - //https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL - DTL S7_GetDTLAt(byte Buffer[], int Pos) - {// UNDONE: check result - uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] - uint16_t month = static_cast(S7_GetByteAt(Buffer, Pos + 2)); // [1, 12] - uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] - uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] - uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] - uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] - uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] - uint32_t nanosec = S7_GetUDIntAt(Buffer, Pos + 8); // [0, 999999999] - - return DTL{ year, month, day, weekday, hour, minute, second, nanosec }; - } +//**************************************************************************** +// Get Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) +// An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. +// Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 +// https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL +DTL S7_GetDTLAt(byte Buffer[], int Pos) +{ + uint16_t year = S7_GetUIntAt(Buffer, Pos); // 1970, 2262] + uint16_t month = static_cast(S7_GetByteAt(Buffer, Pos + 2)); // [1, 12] + uint16_t day = static_cast(S7_GetByteAt(Buffer, Pos + 3)); // [1, 31] + uint16_t weekday = static_cast(S7_GetByteAt(Buffer, Pos + 4)); // [1, 7] + uint16_t hour = static_cast(S7_GetByteAt(Buffer, Pos + 5)); // [0, 23] + uint16_t minute = static_cast(S7_GetByteAt(Buffer, Pos + 6)); // [0, 59] + uint16_t second = static_cast(S7_GetByteAt(Buffer, Pos + 7)); // [0, 59] + uint32_t nanosec = S7_GetUDIntAt(Buffer, Pos + 8); // [0, 999999999] + + return DTL{year, month, day, weekday, hour, minute, second, nanosec}; +} - //**************************************************************************** - // Set Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) - // An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. - // Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 - //https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL - void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec) - {// UNDONE: check result - S7_SetUIntAt(Buffer,Pos,year); // 1970, 2262] - S7_SetByteAt(Buffer,Pos + 2,month); // [1, 12] - S7_SetByteAt(Buffer, Pos + 3,day); // [1, 31] - - //weekday calculation - year -= month <= 2; - const unsigned era = year / 400; - const unsigned yoe = static_cast(year - era * 400); // [0, 399] - const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] - const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] - uint32_t days = era * 146097 + static_cast(doe) - 726773; - uint8_t weekday = ((days + 1) % 7) + 1; //1990-01-01[Monday(1)] [1,7] - - S7_SetByteAt(Buffer, Pos + 4, weekday); // [1, 7] - S7_SetByteAt(Buffer, Pos + 5,hour); // [0, 23] - S7_SetByteAt(Buffer, Pos + 6,minute); // [0, 59] - S7_SetByteAt(Buffer, Pos + 7,second); // [0, 59] - S7_SetUDIntAt(Buffer,Pos + 8,nanosec); // [0, 999999999] - - } \ No newline at end of file +//**************************************************************************** +// Set Year-Month-Day-Hour:Minute:Second.Nanoseconds (S7 DTL) +// An operand of data type DTL has a length of 12 bytes and stores date and time information in a predefined structure. +// Min.: DTL#1970-01-01-00:00:00.0 Max.: DTL#2262 - 04 - 11 - 23:47 : 16.854775807 +// https://support.industry.siemens.com/cs/mdm/109773506?c=93833257483&lc=en-PL +void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec) +{ + S7_SetUIntAt(Buffer, Pos, year); // 1970, 2262] + S7_SetByteAt(Buffer, Pos + 2, month); // [1, 12] + S7_SetByteAt(Buffer, Pos + 3, day); // [1, 31] + + // weekday calculation + year -= month <= 2; + const unsigned era = year / 400; + const unsigned yoe = static_cast(year - era * 400); // [0, 399] + const unsigned doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; // [0, 365] + const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + uint32_t days = era * 146097 + static_cast(doe) - 726773; + uint8_t weekday = ((days + 1) % 7) + 1; // 1990-01-01[Monday(1)] [1,7] + + S7_SetByteAt(Buffer, Pos + 4, weekday); // [1, 7] + S7_SetByteAt(Buffer, Pos + 5, hour); // [0, 23] + S7_SetByteAt(Buffer, Pos + 6, minute); // [0, 59] + S7_SetByteAt(Buffer, Pos + 7, second); // [0, 59] + S7_SetUDIntAt(Buffer, Pos + 8, nanosec); // [0, 999999999] +} \ No newline at end of file diff --git a/s7.h b/s7.h index 2230d62..0c3333a 100644 --- a/s7.h +++ b/s7.h @@ -16,138 +16,169 @@ using namespace std; // Define different PLC Types -#define S7_PLC_300_400 0 // for PLC S7 300/400 -#define S7_PLC_1200_1500 1 // for PLC S7 1200/1500 -#define S7_PLC_LOGO_200 2 // for PLC S7 LOGO / 200 -#define S7_PLC_SINAMICS 3 // for SINAMICS Driver +#define S7_PLC_300_400 0 // for PLC S7 300/400 +#define S7_PLC_1200_1500 1 // for PLC S7 1200/1500 +#define S7_PLC_LOGO_200 2 // for PLC S7 LOGO / 200 +#define S7_PLC_SINAMICS 3 // for SINAMICS Driver // Define different Area sources -#define S7_AREA_SOURCE_I 0 // Inputs -#define S7_AREA_SOURCE_Q 1 // Outputs -#define S7_AREA_SOURCE_M 2 // Memory Marks -#define S7_AREA_SOURCE_DB 3 // Data Blocks +#define S7_AREA_SOURCE_I 0 // Inputs +#define S7_AREA_SOURCE_Q 1 // Outputs +#define S7_AREA_SOURCE_M 2 // Memory Marks +#define S7_AREA_SOURCE_DB 3 // Data Blocks // Define different S7 data types -#define S7_TYPE_BOOL 1 -#define S7_TYPE_BYTE 2 -#define S7_TYPE_SINT 3 -#define S7_TYPE_WORD 4 -#define S7_TYPE_UINT 5 -#define S7_TYPE_INT 6 -#define S7_TYPE_DWORD 7 -#define S7_TYPE_UDINT 8 -#define S7_TYPE_DINT 9 -#define S7_TYPE_LWORD 10 -#define S7_TYPE_ULINT 11 -#define S7_TYPE_LINT 12 -#define S7_TYPE_REAL 13 -#define S7_TYPE_LREAL 14 - -#define S7_TYPE_STRING 15 +#define S7_TYPE_BOOL 1 +#define S7_TYPE_BYTE 2 +#define S7_TYPE_SINT 3 +#define S7_TYPE_WORD 4 +#define S7_TYPE_UINT 5 +#define S7_TYPE_INT 6 +#define S7_TYPE_DWORD 7 +#define S7_TYPE_UDINT 8 +#define S7_TYPE_DINT 9 +#define S7_TYPE_LWORD 10 +#define S7_TYPE_ULINT 11 +#define S7_TYPE_LINT 12 +#define S7_TYPE_REAL 13 +#define S7_TYPE_LREAL 14 + +#define S7_TYPE_STRING 15 #define S7_TYPE_ARRAYCHAR 16 -#define S7_TYPE_TOD 17 -#define S7_TYPE_DATE 18 -#define S7_TYPE_DATE_AND_TIME 19 -#define S7_TYPE_DTL 20 +#define S7_TYPE_TOD 17 +#define S7_TYPE_DATE 18 +#define S7_TYPE_DATE_AND_TIME 19 +#define S7_TYPE_DTL 20 -struct TOD { uint32_t h; uint32_t m; uint32_t s; uint32_t ms; }; +struct TOD +{ + uint32_t h; + uint32_t m; + uint32_t s; + uint32_t ms; +}; -struct DATE { uint32_t year; uint32_t month; uint32_t day; }; +struct DATE +{ + uint32_t year; + uint32_t month; + uint32_t day; +}; -struct DATE_AND_TIME { uint16_t year; uint16_t month; uint16_t day; uint16_t hour; uint16_t minute; uint16_t second; uint16_t msec; uint16_t weekday; }; +struct DATE_AND_TIME +{ + uint16_t year; + uint16_t month; + uint16_t day; + uint16_t hour; + uint16_t minute; + uint16_t second; + uint16_t msec; + uint16_t weekday; +}; -struct DTL { uint16_t year; uint16_t month; uint16_t day; uint16_t weekday; uint16_t hour; uint16_t minute; uint16_t second; uint32_t nanosec; }; +struct DTL +{ + uint16_t year; + uint16_t month; + uint16_t day; + uint16_t weekday; + uint16_t hour; + uint16_t minute; + uint16_t second; + uint32_t nanosec; +}; - string S7_GetTxtPLCType (short int plcType); // Get Text description of PLC Type +string S7_GetTxtPLCType(short int plcType); // Get Text description of PLC Type - int S7_GetDataTypeSize (int type); // Get data type size +int S7_GetDataTypeSize(int type); // Get data type size - uint16_t S7_GetWordFromTSAP ( string TSAP); // Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams +uint16_t S7_GetWordFromTSAP(string TSAP); // Get the word from Transport Service Access Point (TSAP) in hex format, e.g: 10.02 => 0x1002, used by Cli_SetConnectionParams - string S7_GetTxtAreaSource (int areaSource); // Get Text message of Area Source +string S7_GetTxtAreaSource(int areaSource); // Get Text message of Area Source - int S7_BDCToByte (byte B); // Get BDC and convert to byte +int S7_BDCToByte(byte B); // Get BDC and convert to byte - byte S7_ByteToBDC (int Value); // Convert Byte to BDC +byte S7_ByteToBDC(int Value); // Convert Byte to BDC - bool S7_GetBitAt ( byte Buffer[], int Pos, int Bit); // Get Bit position at buffer of bytes +bool S7_GetBitAt(byte Buffer[], int Pos, int Bit); // Get Bit position at buffer of bytes - void S7_SetBitAt ( byte Buffer[], int Pos, int Bit, bool Value); // Set Bit position at buffer of bytes +void S7_SetBitAt(byte Buffer[], int Pos, int Bit, bool Value); // Set Bit position at buffer of bytes - uint8_t S7_GetByteAt(byte Buffer[], int Pos); // Get Byte (0..255) at buffer of bytes +uint8_t S7_GetByteAt(byte Buffer[], int Pos); // Get Byte (0..255) at buffer of bytes - void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value ); // Set Byte (0..255) at buffer of bytes +void S7_SetByteAt(byte Buffer[], int Pos, uint8_t Value); // Set Byte (0..255) at buffer of bytes - int8_t S7_GetSIntAt(byte Buffer[], int Pos); // Get SInt (-128..127) at buffer of bytes +int8_t S7_GetSIntAt(byte Buffer[], int Pos); // Get SInt (-128..127) at buffer of bytes - void S7_SetSIntAt(byte Buffer[], int Pos, int8_t Value); // Set SInt (-128..127) at buffer of bytes +void S7_SetSIntAt(byte Buffer[], int Pos, int8_t Value); // Set SInt (-128..127) at buffer of bytes - uint16_t S7_GetUIntAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 +uint16_t S7_GetUIntAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 - void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value ); // Set 16 bit unsigned value (S7 UInt) 0..65535 +void S7_SetUIntAt(byte Buffer[], int Pos, uint16_t Value); // Set 16 bit unsigned value (S7 UInt) 0..65535 - uint16_t S7_GetWordAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 +uint16_t S7_GetWordAt(byte Buffer[], int Pos); // Get 16 bit unsigned value (S7 UInt) 0..65535 - void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value ); // Set 16 bit unsigned value (S7 UInt) 0..65535 +void S7_SetWordAt(byte Buffer[], int Pos, uint16_t Value); // Set 16 bit unsigned value (S7 UInt) 0..65535 - int16_t S7_GetIntAt(byte Buffer[], int Pos); // Get 16 bit signed value (S7 int) -32768..32767 at buffer of bytes +int16_t S7_GetIntAt(byte Buffer[], int Pos); // Get 16 bit signed value (S7 int) -32768..32767 at buffer of bytes - void S7_SetIntAt(byte Buffer[], int Pos, int16_t Value); // Set 16 bit signed value (S7 int) -32768..32767 at buffer of bytes +void S7_SetIntAt(byte Buffer[], int Pos, int16_t Value); // Set 16 bit signed value (S7 int) -32768..32767 at buffer of bytes - uint32_t S7_GetUDIntAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 +uint32_t S7_GetUDIntAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 - void S7_SetUDIntAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 +void S7_SetUDIntAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 - uint32_t S7_GetDWordAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 +uint32_t S7_GetDWordAt(byte Buffer[], int Pos); // Get 32 bit unsigned value (S7 UDInt) 0..4294967295 - void S7_SetDWordAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 +void S7_SetDWordAt(byte Buffer[], int Pos, uint32_t Value); // Set 32 bit unsigned value (S7 UDInt) 0..4294967295 - long S7_GetDIntAt(byte Buffer[], int Pos); // Get 32 bit signed value (S7 DInt) -2147483648..2147483647 +long S7_GetDIntAt(byte Buffer[], int Pos); // Get 32 bit signed value (S7 DInt) -2147483648..2147483647 - void S7_SetDIntAt(byte Buffer[], int Pos, long Value); // Set 32 bit signed value (S7 DInt) -2147483648..2147483647 +void S7_SetDIntAt(byte Buffer[], int Pos, long Value); // Set 32 bit signed value (S7 DInt) -2147483648..2147483647 - uint64_t S7_GetULIntAt(byte Buffer[], int Pos); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +uint64_t S7_GetULIntAt(byte Buffer[], int Pos); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - void S7_SetULIntAt(byte Buffer[], int Pos, uint64_t Value); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +void S7_SetULIntAt(byte Buffer[], int Pos, uint64_t Value); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - uint64_t S7_GetLWordAt(byte Buffer[], int Pos); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +uint64_t S7_GetLWordAt(byte Buffer[], int Pos); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 +void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value); // Set 64 bit unsigned value (S7 ULint) 0..18446744073709551615 - int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 +int64_t S7_GetLIntAt(byte Buffer[], int Pos); // Get 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 - void S7_SetLIntAt(byte Buffer[], int Pos, int64_t Value); // Set 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 +void S7_SetLIntAt(byte Buffer[], int Pos, int64_t Value); // Set 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807 - float S7_GetRealAt(byte Buffer[], int Pos); // Get 32 bit floating point number (S7 Real) (Range of float) +float S7_GetRealAt(byte Buffer[], int Pos); // Get 32 bit floating point number (S7 Real) (Range of float) - void S7_SetRealAt(byte Buffer[], int Pos, float Value); // Set 32 bit floating point number (S7 Real) (Range of float) +void S7_SetRealAt(byte Buffer[], int Pos, float Value); // Set 32 bit floating point number (S7 Real) (Range of float) - double S7_GetLRealAt(byte Buffer[], int Pos); // Get 64 bit floating point number (S7 LReal) (Range of double) +double S7_GetLRealAt(byte Buffer[], int Pos); // Get 64 bit floating point number (S7 LReal) (Range of double) - void S7_SetLRealAt(byte Buffer[], int Pos, double Value); // Set 64 bit floating point number (S7 LReal) (Range of double) +void S7_SetLRealAt(byte Buffer[], int Pos, double Value); // Set 64 bit floating point number (S7 LReal) (Range of double) - string S7_GetStringAt(byte Buffer[], int Pos); // Get String (S7 String) +string S7_GetStringAt(byte Buffer[], int Pos); // Get String (S7 String) - void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value); // Set String (S7 String) +void S7_SetStringAt(byte Buffer[], int Pos, int MaxLen, string Value); // Set String (S7 String) - string S7_GetCharsAt(byte Buffer[], int Pos, int Size); //Get Array of char (S7 ARRAY OF CHARS) +string S7_GetCharsAt(byte Buffer[], int Pos, int Size); // Get Array of char (S7 ARRAY OF CHARS) - void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value); //Set Array of char (S7 ARRAY OF CHARS) +void S7_SetCharsAt(byte Buffer[], int BufferLen, int Pos, string Value); // Set Array of char (S7 ARRAY OF CHARS) - TOD S7_GetTODAt(byte Buffer[], int Pos); // Get struct of TOD (S7 TOD) +TOD S7_GetTODAt(byte Buffer[], int Pos); // Get struct of TOD (S7 TOD) - void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec); // Set struct of TOD(S7 TOD) +void S7_SetTODAt(byte Buffer[], int Pos, uint32_t hour, uint32_t minute, uint32_t second, uint32_t msec); // Set struct of TOD(S7 TOD) - DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get struct of DATE (S7 DATE) +DATE S7_GetDATEAt(byte Buffer[], int Pos); // Get struct of DATE (S7 DATE) - void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day); // Set struct of DATE (S7 DATE) +void S7_SetDATEAt(byte Buffer[], int Pos, uint32_t year, uint32_t month, uint32_t day); // Set struct of DATE (S7 DATE) - DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos); // Get struct of DATE_AND_TIME (S7 DATE_AND_TIME) +DATE_AND_TIME S7_GetDATE_AND_TIMEAt(byte Buffer[], int Pos); // Get struct of DATE_AND_TIME (S7 DATE_AND_TIME) - void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec); // Set struct of DATE_AND_TIME (S7 DATE_AND_TIME) +void S7_SetDATE_AND_TIMEAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t msec); // Set struct of DATE_AND_TIME (S7 DATE_AND_TIME) - DTL S7_GetDTLAt(byte Buffer[], int Pos); // Get struct of DTL (S7 DTL) +DTL S7_GetDTLAt(byte Buffer[], int Pos); // Get struct of DTL (S7 DTL) - void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec); // Set struct of DTL (S7 DTL) +void S7_SetDTLAt(byte Buffer[], int Pos, uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint32_t nanosec); // Set struct of DTL (S7 DTL) #endif // S7_H From 168d29b016477e7427cc891d84736e6f66a3d347 Mon Sep 17 00:00:00 2001 From: PiotrBzdrega Date: Mon, 15 May 2023 06:40:51 +0200 Subject: [PATCH 13/13] goback with some autoformat --- s7.cpp | 78 ++++++++++++++++++++-------------------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/s7.cpp b/s7.cpp index 0aac226..99ec965 100644 --- a/s7.cpp +++ b/s7.cpp @@ -170,10 +170,8 @@ byte S7_ByteToBDC(int Value) // Get Bit position at buffer of bytes, bits 0..7 bool S7_GetBitAt(byte Buffer[], int Pos, int Bit) { - if (Bit < 0) - Bit = 0; - if (Bit > 7) - Bit = 7; + if (Bit < 0) Bit = 0; + if (Bit > 7) Bit = 7; return (Buffer[Pos] & Mask[Bit]) != 0; } @@ -184,10 +182,8 @@ bool S7_GetBitAt(byte Buffer[], int Pos, int Bit) void S7_SetBitAt(byte Buffer[], int Pos, int Bit, bool Value) { - if (Bit < 0) - Bit = 0; - if (Bit > 7) - Bit = 7; + if (Bit < 0) Bit = 0; + if (Bit > 7) Bit = 7; if (Value) Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]); @@ -228,10 +224,8 @@ int8_t S7_GetSIntAt(byte Buffer[], int Pos) // Set SInt (-128..127) at buffer of bytes void S7_SetSIntAt(byte Buffer[], int Pos, int8_t Value) { - if (Value < -128) - Value = -128; - if (Value > 127) - Value = 127; + if (Value < -128) Value = -128; + if (Value > 127) Value = 127; Buffer[Pos] = (byte)Value; } @@ -293,12 +287,9 @@ void S7_SetIntAt(byte Buffer[], int Pos, int16_t Value) long S7_GetDIntAt(byte Buffer[], int Pos) { long Result; - Result = Buffer[Pos]; - Result <<= 8; - Result += Buffer[Pos + 1]; - Result <<= 8; - Result += Buffer[Pos + 2]; - Result <<= 8; + Result = Buffer[Pos]; Result <<= 8; + Result += Buffer[Pos + 1]; Result <<= 8; + Result += Buffer[Pos + 2]; Result <<= 8; Result += Buffer[Pos + 3]; return Result; } @@ -321,12 +312,9 @@ void S7_SetDIntAt(byte Buffer[], int Pos, long Value) uint32_t S7_GetUDIntAt(byte Buffer[], int Pos) { uint32_t Result; - Result = Buffer[Pos]; - Result <<= 8; - Result |= Buffer[Pos + 1]; - Result <<= 8; - Result |= Buffer[Pos + 2]; - Result <<= 8; + Result = Buffer[Pos]; Result <<= 8; + Result |= Buffer[Pos + 1]; Result <<= 8; + Result |= Buffer[Pos + 2]; Result <<= 8; Result |= Buffer[Pos + 3]; return Result; } @@ -366,20 +354,13 @@ void S7_SetDWordAt(byte Buffer[], int Pos, uint32_t Value) uint64_t S7_GetULIntAt(byte Buffer[], int Pos) { uint64_t Result; - Result = Buffer[Pos]; - Result <<= 8; - Result |= Buffer[Pos + 1]; - Result <<= 8; - Result |= Buffer[Pos + 2]; - Result <<= 8; - Result |= Buffer[Pos + 3]; - Result <<= 8; - Result |= Buffer[Pos + 4]; - Result <<= 8; - Result |= Buffer[Pos + 5]; - Result <<= 8; - Result |= Buffer[Pos + 6]; - Result <<= 8; + Result = Buffer[Pos]; Result <<= 8; + Result |= Buffer[Pos + 1]; Result <<= 8; + Result |= Buffer[Pos + 2]; Result <<= 8; + Result |= Buffer[Pos + 3]; Result <<= 8; + Result |= Buffer[Pos + 4]; Result <<= 8; + Result |= Buffer[Pos + 5]; Result <<= 8; + Result |= Buffer[Pos + 6]; Result <<= 8; Result |= Buffer[Pos + 7]; return Result; } @@ -421,20 +402,13 @@ void S7_SetLWordAt(byte Buffer[], int Pos, uint64_t Value) int64_t S7_GetLIntAt(byte Buffer[], int Pos) { int64_t Result; - Result = Buffer[Pos]; - Result <<= 8; - Result += Buffer[Pos + 1]; - Result <<= 8; - Result += Buffer[Pos + 2]; - Result <<= 8; - Result += Buffer[Pos + 3]; - Result <<= 8; - Result += Buffer[Pos + 4]; - Result <<= 8; - Result += Buffer[Pos + 5]; - Result <<= 8; - Result += Buffer[Pos + 6]; - Result <<= 8; + Result = Buffer[Pos]; Result <<= 8; + Result += Buffer[Pos + 1]; Result <<= 8; + Result += Buffer[Pos + 2]; Result <<= 8; + Result += Buffer[Pos + 3]; Result <<= 8; + Result += Buffer[Pos + 4]; Result <<= 8; + Result += Buffer[Pos + 5]; Result <<= 8; + Result += Buffer[Pos + 6]; Result <<= 8; Result += Buffer[Pos + 7]; return Result; }