CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

On/Off actions delay with timers [SOLVED]

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

On/Off actions delay with timers [SOLVED]
PostPosted: Mon Nov 28, 2022 2:43 pm     Reply with quote

Hello everyone, long time no see, seems I'm back to the origin's Wink
I build myself for my home a climatic environment from some electronic broken air conditioners with help of water condensation. The system work in server mode under Linux. The problem is sometimes the system going crazy, switching my relays way faster than i programmed (i want to have min/max 3 min delay between actions. So i want to put in series with my relays a PIC like safety thing (any PIC can do the job).
I don't have any idea how to do that Embarassed I'm lost, really. I didn't touch programming for years.
My stupid test code below, don't work so well.
Code:

#include <main.h>

int16 timp_motor_on = 0;
int16 timp_motor_off = 0;
int16 timp_normal_run = 0;
int16 timp_normal_pause = 0;

int1 flag_motor_on = FALSE;
int1 flag_motor_off = TRUE;
int1 flag_int_fan = FALSE;
int1 flag_ext_fan = FALSE;

int1 flag_normal_run = FALSE;
int1 flag_normal_pause = FALSE;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void motor()
{
   if(timp_motor_on >= 180)
   {
   output_high(pin_d0);
   flag_motor_on = FALSE;   
   flag_motor_off = TRUE;
   }

//delay_ms(100);

   if(timp_motor_off >= 180)
   {
   output_low(pin_d0);
   timp_motor_off = 0;
   flag_motor_off = FALSE;
   
   }   
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#INT_TIMER0
void  TIMER0_isr(void)
{
    timp_motor_on++;   // 1 sec
    timp_motor_off++;   // 1 sec

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#INT_TIMER1
void  TIMER1_isr(void)
{
   if((timp_motor_on || timp_motor_off) > 6000)
   {
      timp_motor_on = 0;
      timp_motor_off = 0;
   }
//~~~~~~~~~~~~
   if(!input_state(pin_b0))
   {
      if(flag_motor_off == FALSE)
      {
      flag_motor_off = FALSE;
      flag_motor_on = TRUE;
      timp_motor_on = 0;
      set_timer0(0);
      output_high(pin_d0);
      }
   }   
   else if(flag_motor_on == TRUE)
   {      
      timp_motor_off = 0;
//      set_timer0(0);
   }
   else if(flag_motor_off == TRUE)
   {
//      flag_motor_off = TRUE;
      output_low(pin_d0);
      timp_motor_on = 0;
   }
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void main()
{
   port_b_pullups(0xFF);

   setup_adc_ports(NO_ANALOGS, VSS_VDD);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);      //1.0 s overflow
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);      //32.7 ms overflow


   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

//output_high(pin_d1);

   while(TRUE)
   {

   motor();

   }

}

I change the code in different ways, of course without "delay " function.
This one work but at each 180 sec, in off mode, the On function start for a second. Mess me up, really.
The goal is, when the input pin is true the output should be true. Even the input change his state, the output need to stay true 3 minutes. On every input state change from true to false and true again (in that 3 min interval), the counter should be reset to count from 0.
For Off function is the same story. If the output was false, the input
don't need to be able to start it below 3 min.
Any suggestions are welcome.
Thanks to everyone, the beer come after.
Very Happy
_________________
patience is key


Last edited by wangine on Thu Dec 01, 2022 11:08 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Tue Nov 29, 2022 10:57 am     Reply with quote

You seem to be describing something vastly simpler than your code tries
to be.
Input signal, and an output signal.
If the input changes high, turn on the output, and ignore the input for
180 seconds.
If the input changes low, turn off the output, and again ignore the input
for 180 seconds.

Now the key is that since both times are the same and can only happen
one at a time, a single timer is all that is needed.
So, something like:
Code:

#include <main.h>

int16 timer = 0;
int1 last_input=0;

#define INPUT_PIN pin_b0
#define MOTOR_OUT pin_d0

#INT_TIMER0
void  TIMER0_isr(void)
{
    if (timer>0)
       --timer; //only decrement timer when non zero
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void main()
{
   port_b_pullups(0xFF);

   setup_adc_ports(NO_ANALOGS, VSS_VDD);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);      //1.0 s overflow

   enable_interrupts(INT_TIMER0); //1Hz tick
   enable_interrupts(GLOBAL);

   last_input=!input(INPUT_PIN); //this makes input test happen at boot.
   //If you don't want this then set last_input=input(INPUT_PIN)

   while(TRUE)
   {
       if (timer==0)
       { //Do not look at the inputs if the timer is running
           if (input(INPUT_PIN)==1 && last_input==0)
           {  //here pin has changed to low since last test.
                last_input=1;
                output_high(MOTOR_OUT);
                timer=179;
           }
           if (input(INPUT_PIN)==0 && last_input==1)
           {  //here pin has changed to high.
                last_input=0;
                output_low(MOTOR_OUT);
                timer=179;
           }
       }   
   }
}


Your code as posted, inverted the output pin. If this is what you want
then just invert the outputs here.
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Tue Nov 29, 2022 7:49 pm     Reply with quote

Well .... ok, simple and elegant. Thank you. I bet with my wife, you will answer first, i won Very Happy
The thing who mess me up, was : as scenario...
My system going crazy for some bug or just power grid fail, (happen some weeks ago) and the command to my motor start on/off twice as second, fortunately was a analog timer in series with my relays set on 100sec (max on that timer) and at on command the big relay was unable to turn on the motor, otherwise motor was broken for sure.
When i start to write the little fail safe code, i was thinking on same solution to ignore the input for some time, but after idea become "input is on, the motor is on and the input going off for 100 sec, and after on again for 100 sec, i was trying to reset the timer at default count from last input state (180sec as example)."
And in that moment mess me up. Usual simple things destroy anyone's world.
Embarassed

For the moment i don't have the rs485 connected from my ambient thermostat to the system (no time to code). I use the relay output of thermostat in the system, and the PID of the system decide when to turn off and on the motor.
Thats why i was thinking, resetting the timer on last input condition ++180sec will help me at PID control. If i open two windows twice at 5 min the PID going crazy.
Laughing
Thank you man Very Happy
_________________
patience is key
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Wed Nov 30, 2022 2:42 am     Reply with quote

Glad I won your bet for you!... Very Happy

You could just look at a simple time delay relay. These are what is commonly
used to avoid this type of problem.

Have a look at this page, which shows the available types:
[url]
https://www.macromatic.com/support/knowledge-base-articles/understanding-time-delay-relay-functions
[/url]
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Dec 01, 2022 6:36 am     Reply with quote

His post reminds me of a 'one shot' function where once triggered, output stays high for a fixed period of time.
Microchip had a 'tips and tricks' booklet, eons ago......., that showed how to code in assembler, the various forms of relay functions that Mr. T's link talks about
Most PLCs have those relay functions built into them. I know the K-M ones did 3 decades ago. One PLC ($200 back then ) saved a client $14,000 in excess heating costs the 1st year !
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Dec 29, 2022 7:59 pm     Reply with quote

temtronic wrote:
his post reminds me of a 'one shot' function where once triggered, output stays high for a fixed period of time.
Microchip had a 'tips and tricks' booklet, eons ago......., that showed how to code in assembler, the various forms of relay functions that Mr. t's link talks about
Most PLCs have those relay functions built into them. I know the K-M ones did 3 decades ago. One PLC ($200 back then ) saved a client $14,000 in excess heating costs the 1st year !


Yes, I had got the same remembering after reading this thread, I'm agree with both regarding this.
Just I want to share the old "Tips & Tricks" from Microchip that should be a must in our data resource:

https://ww1.microchip.com/downloads/en/DeviceDoc/01146B.pdf

Best wishes
_________________
Humber
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Fri Dec 30, 2022 1:50 am     Reply with quote

I've stuck a link to this thread in the 'best of' forum, since like most
of the 'old hands' here, I know this is an invaluable resource.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group