Puzzled by this code. Can any Genuis help me!

Join Date
Jul 2007
Location
Kiruna
Posts
600
Hi Guys,

I have a problem with this code and I have spent a week trying to figure it out( I didnt write it) . I am hoping someone can put me in the right direction.

The function basicially copies a PLC array of three words M1_HMI_Status_Tag[3] into a SCADA tag array of bools. Every once in a while element M1_HMI_Status[22] of the bool array gets set which in turns triggers an unwanted event. I am 100% sure this trigger does not occur in the PLC. From setting bits in the PLC INT array, the corresponding bits in the SCADA array are correct and the function behaves as expected. Its just this "random" bit that must get set which is causing the problem.

Note that the tags are quite similar to avoid confusion:
M1_HMI_Status_Tag[3] -PLC Array
M1_HMI_Status[63]- SCADA Booleen array tag.

The function is run of an event every 2 seconds.


INT DecNum2[16], Decode2[16];
DecNum2[0] = 32768;
DecNum2[1] = 16384;
DecNum2[2] = 8192;
DecNum2[3] = 4096;
DecNum2[4] = 2048;
DecNum2[5] = 1024;
DecNum2[6] = 512;
DecNum2[7] = 256;
DecNum2[8] = 128;
DecNum2[9] = 64;
DecNum2[10] = 32;
DecNum2[11] = 16;
DecNum2[12] = 8;
DecNum2[13] = 4;
DecNum2[14] = 2;
DecNum2[15] = 1;
Decode2[0] = 32768;
Decode2[1] = 16384;
Decode2[2] = 8192;
Decode2[3] = 4096;
Decode2[4] = 2048;
Decode2[5] = 1024;
Decode2[6] = 512;
Decode2[7] = 256;
Decode2[8] = 128;
Decode2[9] = 64;
Decode2[10] = 32;
Decode2[11] = 16;
Decode2[12] = 8;
Decode2[13] = 4;
Decode2[14] = 2;
Decode2[15] = 1;

FUNCTION
Mask_Status_M1()

INT wordind1, statNum, num1, temp_word1;

wordind1 = 0;
statNum = 15;
num1 = 0;

WHILE wordind1 < 3 DO

temp_word1 = M1_HMI_Status_Tag[wordind1];

IF temp_word1 < 0 THEN
temp_word1 = 65536 - Abs(temp_word1);
ELSE
temp_word1 = temp_word1;
END

WHILE num1 < 16 DO
IF temp_word1 >= Decode2[num1] THEN
M1_HMI_Status[statNum] = 1;
temp_word1 = temp_word1 -Decode2[num1];
ELSE
M1_HMI_Status[statNum] = 0;
END;

statNum = statNum - 1;
num1 = num1 + 1;
END;

IF wordind1 = 0 THEN
statNum = 31;END;
IF wordind1 = 1 THEN
statNum = 47;END;
IF wordind1 = 2 THEN
statNum = 63;END;
IF wordind1 = 3 THEN
statNum = 79;END;
IF wordind1 = 4 THEN
statNum = 95;END;
IF wordind1 = 5 THEN
statNum = 111;END;
IF wordind1 = 6 THEN
statNum = 127;END;
IF wordind1 = 7 THEN
statNum = 143;END;
IF wordind1 = 8 THEN
statNum = 159;END;
IF wordind1 = 9 THEN
statNum = 175;END;
IF wordind1 = 10 THEN
statNum = 191;END

wordind1 = wordind1 + 1;
num1 = 0;

END;

Can anyone see the bug which is causing me problems. I cannot trace it.

Thanks in advance.
 
Last edited:
I am not a genius, but I think the problem is happening with the second word.

When wordind1 is 0, statnum ranges from 15 down to 0.
After that, statnum is set to 31 and wordind 1 is set to 1.

So, for the second iteration of this while
Code:
WHILE num1 < 16 DO 
IF temp_word1 >= Decode2[num1] THEN
M1_HMI_Status[statNum] = 1;	
temp_word1 = temp_word1 -Decode2[num1];
ELSE
M1_HMI_Status[statNum] = 0;
END;
statnum ranges from 31 down to 16 and wordind1 is 1.
When num1 is 9, statNum is 22. At that point, if tempword1 is greater than 64 (decode2[9]) then M1_HMI_Status[22] is set to 1.

I would check to see if your HMI allows you to use a MsgBox so that you can continually see the values as the code executes. Add the MsgBox inside the code and have it show the values you choose.
 
I assume this HMI is priced based on IO tag count, and this script is a way of getting 48 bit IO tags for the price of 3 int IO tags.

The code should produce a map of M1_HMI_Status_Tag[0-2] into M1_HMI_Status[0-47].

If your "events" unwanted or not are triggered off individual bits in M1_HMI_Status[x], you should not have any issues. However, if those events are triggered by combinations of those bits then the "one bit at a time" nature of the update may cause a problem.

For example, if your logic uses bit0 and bit1 like this:
00 = idle
01 = run left
10 = run right
11 = invalid

While the PLC may never have the 11 pattern, your HMI can. Any time it changes from 01 to 10, you will briefly see the 11.

The code seems to do what it should. It has some oddities, like:

What is the DecNum2 array for?

The set of IF statements that set statNum cause the bit array to be declared 16 bits bigger than the plc integer array because it is placed at the end of the loop instead of the beginning.

The set of IF statements that set statNum have values that can set your array index out of range, just seems sloppy.
statNum = (wordind1 * 16) + 15
at the beginning of the loop would be cleaner and gets rid of the funky initialize to 15.
 
WHILE wordind1 < 3 DO

temp_word1 = M1_HMI_Status_Tag[wordind1];

IF temp_word1 < 0 THEN
temp_word1 = 65536 - Abs(temp_word1);
ELSE
temp_word1 = temp_word1;
END
it will stick inhere as wordind is not added. so it stays below.
what is your goal with this?
if you want to pack a lot of booleans better to use PACK
or have a look at www.oscat.de for a nice lib.
 

Similar Topics

Anyone out there that can help? I need to be able to sort 54 numbers in ascending order along with a name which is associated with each of these...
Replies
14
Views
5,011
Hi All, Someone at work has put a PLC system on my desk, that's just been taken off an idle production line. He said "It's an S7 PLC. We don't...
Replies
8
Views
117
hello, I'm a student and for my final grade I have to repare a sepro robot. the only problem I have for now is that i have an error code 3...
Replies
0
Views
35
I received an email from a student with the following code attached. This is supposed to control a floodgate system, and supposed to be written...
Replies
23
Views
778
I have a machine which is undergoing upgradation. As part of the process two SEW drives are being replaced., existing Gen B with new Gen C. The...
Replies
3
Views
193
Back
Top Bottom