How to evaluate if an integer value is odd or even in Step7 SCL

BNA

Member
Join Date
Sep 2003
Location
Give
Posts
117
Hi

I am having som problems evaluating if the value in an integer created in the Static area, is Odd or Even. As far as I remember, Odd integer values always have a "1" in the low order bit, but how do i access this bit in SCL.

I have tried the obvious (For me at least) Index.dbx1.0 , Index is the integer I have created in my Stat area.

Thanks.
Brian
 
Another option.

Code:
FUNCTION FC10 : Bool

// Returns true if even
VAR_INPUT
    // Input Parameters
iNumber : INT;
END_VAR

    IF iNumber MOD 2 = 1 THEN
        //ODD
     FC10 := false ;          
    ELSE
        //Even
       FC10 := true ;        
    END_IF;
END_FUNCTION
 
Another option.

Code:
FUNCTION FC10 : Bool

// Returns true if even
VAR_INPUT
    // Input Parameters
iNumber : INT;
END_VAR

    IF iNumber MOD 2 = 1 THEN
        //ODD
     FC10 := false ;          
    ELSE
        //Even
       FC10 := true ;        
    END_IF;
END_FUNCTION

This is lot slower to execute. If you dont want to use AT then even mask and compare if not zero would be better. You could even use S7 specific thing that WORD_TO_BOOL() only returns value of lsb.

But, first get the help working. Its pretty essential on s7;)
 
Last edited:
This is lot slower to execute. If you dont want to use AT then even mask and compare if not zero would be better. You could even use S7 specific thing that WORD_TO_BOOL() only returns value of lsb.

But, first get the help working. Its pretty essential on s7;)

Help is now working thanks to Bratt, and also my code.

I have tried finding something about the AT instruction, but haven't found anything usefull.

/Brian
 
Its in help of SCL. Basically you can alias variables with it.

For example:

Code:
MyInt : INT;
Bools AT MyInt : ARRAY[0..15] OF BOOL;
Bools array would point to same memory as MyInt.

How did you code it? Did you use MOD, Mask + compare or WORD_TO_BOOL?
 
Last edited:
Its in help of SCL. Basically you can alias variables with it.

For example:

Code:
MyInt : INT;
Bools AT MyInt : ARRAY[0..15] OF BOOL;
Bools array would point to same memory as MyInt.

How did you code it? Did you use MOD, Mask + compare or WORD_TO_BOOL?


I Used the MOD instruction, I am using the code to change between 3 delivery points. Every time I get a signal on my egde detection I count my index up with 1, when the index value is ODD use delivery point 1, when even use delivery point 2, and when i reach 7 on my index use delivery point 3.

Code:
// Statement Section
 
IF xEdgeDetected THEN
IF Index <= 7 THEN
Index := Index + 1;
ELSE Index:=1;
END_IF;
END_IF;
 
 
IF Index MOD 2 = 1 THEN
Point1 := 0;
ELSE
Point1 := 1;
END_IF; 
 
IF Index MOD 2 = 1 THEN
Point2 := 1;
ELSE
Point2 := 0;
END_IF; 
IF index = 7 THEN
Point3 := 1;
Point1 := 0;
Point2 := 0;
ELSE 
Point3 := 0;
END_IF;
/Brian
 
Last edited:
Was your point1 and point 2 reversed (point2 := 1 for odd) on purpose compared to your description?

In any case, try this:

Code:
(*Roll index trough 1 to 7*)
IF xEdgeDetect
THEN
    Index := Index MOD 7 + 1;
END_IF;

(*Select delivery point*)
CASE Index OF
    1,3,5 : Point1 := 1;
            Point2 := 0;
            Point3 := 0;

    2,4,5 : Point1 := 0;
            Point2 := 1;
            Point3 := 0;

    ELSE  : Point1 := 0;
            Point2 := 0;
            Point3 := 1;
END_CASE;
 
Last edited:
Was your point1 and point 2 reversed (point2 := 1 for odd) on purpose compared to your description?

In any case, try this:

Code:
(*Roll index trough 1 to 7*)
IF xEdgeDetect
THEN
    Index := Index MOD 7 + 1;
END_IF;
 
(*Select delivery point*)
CASE Index OF
    1,3,5 : Point1 := 1;
            Point2 := 0;
            Point3 := 0;
 
    2,4,5 : Point1 := 0;
            Point2 := 1;
            Point3 := 0;
 
    ELSE  : Point1 := 0;
            Point2 := 0;
            Point3 := 1;
END_CASE;

I wanted to change between delivery point 1 and 2 every second time, this means when index is odd use point 1 when even use point 2, and when index reached 7 use point 3.

I like your code, it is more "Straight Ahead" but is it possible to make it variable ? I wanted to make the value for using point 3 changeable from HMI, what I am thinking about is the Case instruction, can I just add more numbers, Like 1,3,5,7,9 and so on, or can I change it to ODD or Even.

Brian
 
If you want to vary point3 then case cannot be used, cases must be fixed.

This could work:
Code:
(*Roll index trough 1 to MaxIndex*) 
IF xEdgeDetect 
THEN
    Index := Index MOD MaxIndex + 1;
END_IF;

(*Select delivery point*)
IF (Index = p3Index) //variable changeable from hmi for point3
THEN
            Point1 := 0;
            Point2 := 0; 
            Point3 := 1; 
ELSIF WORD_TO_BOOL(INT_TO_WORD(Index)) //dont have step7 now, try if INT_TO_BOOL works
THEN
            Point1 := 1;    
            Point2 := 0;    
            Point3 := 0;
ELSE
            Point1 := 0;  
            Point2 := 1;   
            Point3 := 0;
[FONT=courier new]END_IF;
[/FONT]


MaxIndex can be variable, but it also can be constant. Which ever suits your needs better.
 
Last edited:
If you want to vary point3 then case cannot be used, cases must be fixed.

This could work:
Code:
(*Roll index trough 1 to MaxIndex*) 
IF xEdgeDetect 
THEN
    Index := Index MOD MaxIndex + 1;
END_IF;
 
(*Select delivery point*)
IF (Index = p3Index) //variable changeable from hmi for point3
THEN
            Point1 := 0;
            Point2 := 0; 
            Point3 := 1; 
ELSIF WORD_TO_BOOL(INT_TO_WORD(Index)) //dont have step7 now, try if INT_TO_BOOL works
THEN
            Point1 := 1;    
            Point2 := 0;    
            Point3 := 0;
ELSE
            Point1 := 0;  
            Point2 := 1;   
            Point3 := 0;
[FONT=courier new]END_IF;[/FONT]

MaxIndex can be variable, but it also can be constant. Which ever suits your needs better.

With some very small changes it worked like a charm, Thanks a lot.

By the way, where have you learned SCL, from Siemens providers or from PC programming ?

This is what came out of your code.

Code:
IF xEdgeDetected THEN
    Index := Index MOD P3Index + 1;
END_IF;
 
IF (Index = P3Index) THEN
            Point1 := 0;
            Point2 := 0;
            Point3 := 1;
            
ELSE IF INT_TO_BOOL(index) 
THEN 
            Point1 := 1;
            Point2 := 0;
            Point3 := 0;
ELSE  
            Point1 := 0;
            Point2 := 1;
            Point3 := 0;
END_IF;
END_IF;

Thanks Again.
Best Regards
Brian
 
Too much time at evening & night shifts, this forum & manuals and lots of hw to play with :)

ps. remember that x_to_bool in s7 does not work according to standard. Normally it works so that if <>0 then true. So I recommend commenting it in the code.
 
Last edited:
...
This is what came out of your code.

Code:
IF xEdgeDetected THEN
    Index := Index MOD P3Index + 1;
END_IF;
 
IF (Index = P3Index) THEN
            Point1 := 0;
            Point2 := 0;
            Point3 := 1;
            
ELSE IF INT_TO_BOOL(index) 
THEN 
            Point1 := 1;
            Point2 := 0;
            Point3 := 0;
ELSE  
            Point1 := 0;
            Point2 := 1;
            Point3 := 0;
END_IF;
END_IF;
Thanks Again.
Best Regards
Brian

That is not good way to write it, use ELSIF.
 

Similar Topics

Hi there, I have never used Citect before and have a few bugs to fix. I have 2 questions: 1. How can i view the tag database as a whole...
Replies
10
Views
3,449
Does anyone know how to do this logic in Contrologix?
Replies
3
Views
1,571
Hi all, I'd like to know your point of view on this aspect of PLC programming, the example I use is simple, but the concept can be applied to...
Replies
5
Views
2,475
Hello I need to know how many input are true from at 5-bit pattern. The True/False sequence is random. The evaluation has to be in every scan...
Replies
3
Views
1,686
Hello, I wrote some vba code for a Factorytalk View Studio SE application display. The code should be around 100 lines long using something...
Replies
2
Views
1,964
Back
Top Bottom