"once" statement not working within "for" loops (PAC)

Discussion in 'C-Bus Automation Controllers' started by gheezer, Jul 29, 2023.

  1. gheezer

    gheezer

    Joined:
    Feb 13, 2019
    Messages:
    5
    Likes Received:
    0
    Hi,
    I am iterating over a set of groups to see what their state is.
    Doing them individually in is fine but when I try to use in a loop the "once" statement keeps firing as if it were a simple "if" statement.

    Herer is a sample code

    for Group := 1 to 10 do
    begin
    Format(GroupIs, 'Group ', Group, ' is ON', #13#10);
    once GetCbusState(254, 56, Group) = ON then
    WriteSerial(1, GroupIs);
    end;

    I should only see that serial routine fire once I activate the group, but it keeps firing for every module run.

    Any clues? Ot if there is a better way of doing this?
     
    gheezer, Jul 29, 2023
    #1
  2. gheezer

    gheezer

    Joined:
    Feb 13, 2019
    Messages:
    5
    Likes Received:
    0
    .. scratch this .. just found it in the help file ... "don't use in a loop ..."
    Any ideas on how to loop through a group and detect a change?
     
    gheezer, Jul 29, 2023
    #2
  3. gheezer

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,536
    Likes Received:
    176
    Location:
    Adelaide, Australia
    The ONCE statement works by storing the last value of the variable internally and then comparing it with the new value. Since it only stores a single value, you can't compare it with multiple different groups. The way around this is to do your own ONCE instruction using an array of the previous values

    in Global Variables add:

    lastValues: array[1..10] of boolean;

    Code:
    for Group := 1 to 10 do
      if (GetCbusState(254, 56, Group) = ON) and (lastValues[Group] <> ON) then
      begin
        lastValues[Group] := ON;
        Format(GroupIs, 'Group ', Group, ' is ON', #13#10);
        WriteSerial(1, GroupIs);
      end
      else
        lastValues[group] := OFF;
    Note also you can simplify the first line to:

    if (GetCbusState(254, 56, Group) and not lastValues[Group] then
    etc.

    because both expressions are already booleans.
     
    Ashley, Jul 29, 2023
    #3
  4. gheezer

    gheezer

    Joined:
    Feb 13, 2019
    Messages:
    5
    Likes Received:
    0
    Thanks Ashley!
    I will give it a try.
     
    gheezer, Jul 31, 2023
    #4
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.