PDA

View Full Version : Using Counters


Darren
05 Jul 05, 04:54 PM
Logic does not require the concept of independent "counters", since they can be easily implemented using integer variables.

To use a variable as a counter, it first needs to be declared in the "variables" section. It should then be set to an initial value in the "initialisation" section. It can then have its value used or changed.

For example, to increment a variable called "counter" in your code and then do something if the value gets to 10 :

{ variables }
counter : integer;

{ initialisation }
counter := 0;

{ module code }
...
counter := counter + 1;
if counter = 10 then
begin
{ do stuff here }
end;

It is as simple as that :)



For a more complex example, we want to control the toilet light in steps by using another group address to trigger increments in the toilet light :

{ constants }
ToiletLightGroup = 33;
ToiletControlGroup = 32;

{ variables }
CounterToilet : integer;

{ initialisation }
CounterToilet := 0;
SetLightingState(ToiletControlGroup, OFF);

{ module code }
if GetLightingState(ToiletControlGroup) = ON then
begin
{ increment the counter }
CounterToilet := CounterToilet + 1;

{ set the new level }
if CounterToilet = 1 then
SetLightingLevel(ToiletLightGroup, 30%, "0s");
if CounterToilet = 2 then
SetLightingLevel(ToiletLightGroup, 50%, "0s");
if CounterToilet = 3 then
SetLightingLevel(ToiletLightGroup, 70%, "0s");

{ switch off the trigger }
SetLightingState(ToiletControlGroup, OFF);
end;

once GetLightingState(ToiletLightGroup) = OFF then
CounterToilet := 0;

scottmurphy
31 Jul 05, 02:15 PM
I am a bit lost on your code here. Are you trying to acheive 3 different lighting levels? The was I am looking at it ( from a plc user point of view ) is that the counter will never get above 1, as it is always reset to 0 when the group is switched off?

Richo
01 Aug 05, 10:29 AM
I am a bit lost on your code here. Are you trying to acheive 3 different lighting levels? The was I am looking at it ( from a plc user point of view ) is that the counter will never get above 1, as it is always reset to 0 when the group is switched off?

In the example there is ONE light whose level is set by the group "ToiletLightGroup". The group has 3 levels which are cycled though each time the group "ToiletControlGroup" is turned on.

This is achieved by counting each time the control group is turned on. The code sees the control group go on, increments the counter. Checks the value of the counter and set the lighting group to the appropraite level for that counter value. if the counter goes higher than the number of options it is set to zero. Finally the control group is turned off to wait for the next time it is set to on.

scottmurphy
01 Aug 05, 11:51 AM
I have tried copying this code into the logic engine, but am getting declaration errors etc, I am using the trial version of the PICED software, is this limiting me in anyway?

Richo
01 Aug 05, 12:03 PM
I have tried copying this code into the logic engine, but am getting declaration errors etc, I am using the trial version of the PICED software, is this limiting me in anyway?

Sorry, have to wait for Darren to help. I don't have PICED installed and have never used it.

Phil.H
01 Aug 05, 01:36 PM
Scott,

The trial version of PICED has a fully functional logic engine. Trial versions will expire in time so why not download the full release seeing as it is FREE.

PICED Download (http://www.clipsal.com/cis/downloads.php3#PICED)

Make sure that where Darren has given example code that the declarations like:
{ constants }
ToiletLightGroup = 33;
ToiletControlGroup = 32;

{ variables }
CounterToilet : integer;

{ initialisation }
CounterToilet := 0;
SetLightingState(ToiletControlGroup, OFF);

These go in the respective sections under the Advanced area on the program manager tree (left) Note: {variables} goes in the 'Global Variables' area.
Note2: Constants are used instead of group address tags so your code will work without having to have a specific C-Bus project.

Hope this helps :)


I have tried copying this code into the logic engine, but am getting declaration errors etc, I am using the trial version of the PICED software, is this limiting me in anyway?

coppo
17 Nov 05, 04:36 PM
A minor variation to darrens code can provide the folllowing

{ constants }
ToiletLightGroup = 33;
ToiletControlGroup = 32;

{ variables }
CounterToilet : integer;

{ initialisation }
CounterToilet := 0;
SetLightingState(ToiletControlGroup, OFF);

{ module code }
if getlightingstate(toiletcontrolgroup) = ON then
begin
{increment the counter}
countertoilet := countertoilet + 1;

{ set the new output light level based upon the counter value }
if CounterToilet = 1 then
SetLightingLevel(ToiletLightGroup, 25%, "0s");
if CounterToilet = 2 then
SetLightingLevel(ToiletLightGroup, 50%, "0s");
if CounterToilet = 3 then
SetLightingLevel(ToiletLightGroup, 75%, "0s");
{ switch off the trigger automatically when pressed,
ie : the button acts like a momentary/bell press switch }
SetLightingState(ToiletControlGroup, OFF);
end;

{ Reset all of the components when the "toiletcontrolgroup" button
is pressed a 4th time }
if CounterToilet >3 then
begin
CounterToilet := 0; { counter reset }
SetLightingLevel(ToiletLightGroup, 0%, "0s");
SetLightingState(ToiletControlGroup, OFF);
end;


In the example there is a load group called "toiletlightgroup" , its light level is set by a combination of "ToiletcontrolGroup" and the counter toilet value. Every time the "toiletcontrolgroup" is turned "ON" it increments the counter timer, then depending on the counter value the "toiletlightgroup" is set to 0/25/50/75%.

Once the command has set the light to the specific level, the "toiletcontrolgroup" is reset, ready for the next time the button is pressed.

Once the button has button has been pressed 4 times it will;
reset the counter, turn off light, turn off control group.

pressed button 1 time = light @ 25%, counter = 1
pressed button 2 times = light @ 50%, counter = 2
pressed button 3 times = light @ 75%, counter = 3
pressed button 4 times = light reset to 0%, counter = 4 briefly, then instantly reset to 0

RossW
27 Nov 05, 06:50 PM
A minor variation to darrens code can provide the folllowing

... snip....

{ set the new output light level based upon the counter value }
if CounterToilet = 1 then
SetLightingLevel(ToiletLightGroup, 25%, "0s");
if CounterToilet = 2 then
SetLightingLevel(ToiletLightGroup, 50%, "0s");
if CounterToilet = 3 then
SetLightingLevel(ToiletLightGroup, 75%, "0s");
{ switch off the trigger automatically when pressed,
ie : the button acts like a momentary/bell press switch }
SetLightingState(ToiletControlGroup, OFF);
end;


Forgive me for this, but this kind of *horribly clunky* code always makes me squirm. Multiple if-then-else type statements are very ineffecient, especially when you have LOTS of them. They're hard to read, they're easy to have errors in, they take lots of space and CPU cycles.

Does the logic engine allow for much more practical code like:

{ set the new output light level based upon the counter value }
SetLightingLevel(ToiletLightGroup, CounterToilet*25%, "0s");

One statement, easy to read and follow, low overheads etc?

(If the statement can't do it in one step, perhaps the calculation needs to be done outside the SetLightingLevel statement - because surely it can't be that someone made parameter 2 require a constant?!)

My 2c worth,
RossW

Darren
28 Nov 05, 11:40 AM
SetLightingLevel(ToiletLightGroup, CounterToilet*25%, "0s");

The logic engine does support this, and as you say, this is a much better way of writing the code.

MiniMe
01 Mar 06, 05:25 PM
is it possible to display the counter on only one page

Phil.H
17 Mar 06, 07:33 PM
is it possible to display the counter on only one page

What Da !

johnl
26 Mar 06, 10:09 PM
MiniMe,

If you wish to display the value of the counter on one page only, use 'if ShowingPage ...' as per the code below.

{Display the Counter Value - Maximum of 3 digits}
if ShowingPage ("Counter") then
begin
ClearScreen;
TextPos (230,200);
DrawText ('Counter = ', Counter1 : 3) ;
end;

John

pargy
27 Aug 06, 11:29 PM
I haven't tried this, but can the label on a DLT switch be toggled?

Simplest example is a "Goodbye" label that when pressed executes an all off and sets the security alarm and then changes the label to "Welcome home" so that next tome that button is pressed a different logic sequence is executed (that will end by toggling the label for that button back to "Goodbye").

Philip

ashleigh
28 Aug 06, 12:21 PM
Not yet. Support for changing the labels on DLT is coming......

5coobyd00
21 Aug 07, 08:42 AM
Not yet. Support for changing the labels on DLT is coming......

Can this be done yet by using the PAC?

I guess there is similar logic in the Matrix Switcher to do this, but was wondering if code can be written to achieve this from a PAC or Colour C-Touch?

Thanks :)