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

Hysteresis for two thresholds
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
MDM1985



Joined: 16 Oct 2014
Posts: 14

View user's profile Send private message

Hysteresis for two thresholds
PostPosted: Sun Oct 19, 2014 7:55 am     Reply with quote

Hi. First of all very nice and useful forum. I am an electronic engineer and I need to add hysteresis for two thresholds in order to avoid the relay chattering. Here the pseudo code without hysteresis:

if a <= 100
Out = 01
Else if a > 100 and b <= 400
Out = 10
Else if b > 400
Out = 11
Else
Out = 11

I am reading a voltage value from a potentiometer using the adc channel of my pic16F886 and, when I am close to the thresholds, I would like to have a stable output. Here my solution but I don't know if it is right:

Hysteresis low = abs a - 100
Hysteresis high = abs b - 400
If a <= 100
Out = 01
If hysteresis low <= 30
Out = blind
Else if a >100 and a <= 400
Out = 10
If hysteresis low <= 30 or hysteresis high <= 30
Out = blind
Else if a > 400
Out = 11
If hysteresis high <30
Out = blind
Else
Out = 11
Thank you for your help

rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

PostPosted: Sun Oct 19, 2014 12:47 pm     Reply with quote

I can't grasp your code very well, but here is
Simple code that will handle hysteresis:

Code:

adc_val = read_adc();
if (adc_val > UPPER_ THRESHOLD)
{
   output_high(RELAY);
}
if (adc_val < LOWER_THRESHOLD)
{
    output_low(RELAY);
}

You must define your own values for both thresholds.
_________________
A person who never made a mistake never tried anything new.
MDM1985



Joined: 16 Oct 2014
Posts: 14

View user's profile Send private message

PostPosted: Sun Oct 19, 2014 1:25 pm     Reply with quote

Here the code:

Code:
#define  blind 0
...

int state;
adc_val = read_adc();
threshold_low = 100;
threshold_high = 400;

hysteresis_low = abs(adc_val - threshold_low);
hysteresis_high = abs(adc_val - threshold_high);

      if (adc_val <= threshold_low) {
          otpuput_high (relay 1);
          if (hysteresis_low <= 30)
          state = blind; //if the adc_val is close to the low threshold, don't do anything
         
      }
      else
      if (adc_val <= threshold_high && adc_val > threshold_low) {
          otpuput_high (relay 2);
          output_low (relay 1);
          if (hysteresis_high <= 30 || hysteresis_low <= 30)
          state = blind; // if the adc_val is close to the low threshold or high threshold, don't do anything
      }
     else
     if (adc_val > threshold_high) {
          otpuput_low (relay 1);
          otpuput_low (relay 2);
          if (hysteresis_high <= 30)
          state = blind; //if the adc_val is close to the high threshold, don't do anything
      }
      else {
          otpuput_low (relay 1);
          otpuput_low (relay 2);
      }

I would like to avoid the chattering of the relay1 when the value from potenziometer is close to the low threshold and the same for the relay 2 when the value from potenziometer is close to the high threshold; here an example:

relay 1 and 2 off
---------------------- relay 2 is still on
------------------------------- threshold_high
---------------------- relay 2 is still on

relay 2 on and 1 off

---------------------- relay 1 is still on
------------------------------- threshold_low
---------------------- relay 1 is still on

relay 1 on and 2 off
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Oct 19, 2014 2:55 pm     Reply with quote

OK. You've got one adc input, yet want to control two relays.

Please explain more clearly EXACTLY what you want to happen.
(Say as the adc_value increases then decreases.)

Like rikotech8 I can't decipher either your real or pseudo code.

Mike
MDM1985



Joined: 16 Oct 2014
Posts: 14

View user's profile Send private message

PostPosted: Mon Oct 20, 2014 12:01 am     Reply with quote

Yes,when the adc_value is changing close to the threshold, for example the low threshold, I would have a stable output. For example, when the adc_value is 101 relay is on but, when the adc_value step from 99 to 101 the relay is off on off on off on and then stable on... I would like to have a stable output without chattering. I would like to know how add two hysteresis since I have two thresholds.
Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Mon Oct 20, 2014 1:03 am     Reply with quote

This is a classic 'state' problem:
Code:

#define RELAY_1_ON (130)
#define RELAY_2_ON (160) //Set where you want
#define THRESHOLD (5) //threshold to turn off
#define OFF 0
#define R1 1
#define R2 2  //binary masks - place to suit the relay bits required

int8 state=OFF;
..........
    //Now, assume arrive here with variable 'volt' from the adc

    if (volt>RELAY_1_ON)
        state|=R1; //turn relay 1 on
    else
    {
        //only get here if _not_ above the 'on' point
        if (volt<(RELAY_1_ON-THRESHOLD))
           state&=(~R1); //turn relay 1 off if below ON-THRESHOLD 
    }     
    //Now the same for relay 2
    if (volt>RELAY_2_ON)
        state|=R2; //turn relay 2 on
    else
    {
        if (volt<(RELAY_2_ON-THRESHOLD))
           state&=(~R2); //turn relay 2 off if below ON-THRESHOLD
    }
    //then just output the bits to the relays
    output_b(state); //whatever port you are using


The individual bits (R1, and R2) get turned 'on' if above the specified 'ON' points, but then have to drop 'THRESHOLD' counts below this point, before they will turn off.
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

PostPosted: Mon Oct 20, 2014 7:44 am     Reply with quote

I would like to mention to put a mask on state, when applied to the port:
Code:
output_b(state & 0x03)

Only if you are using the rest of the port pins. Otherwize would be cleared.
Ttelmah, correct me if I am wrong Embarassed
_________________
A person who never made a mistake never tried anything new.
newguy



Joined: 24 Jun 2004
Posts: 1909

View user's profile Send private message

PostPosted: Mon Oct 20, 2014 8:57 am     Reply with quote

rikotech8 wrote:
I would like to mention to put a mask on state, when applied to the port:
Code:
output_b(state & 0x03)

Only if you are using the rest of the port pins. Otherwize would be cleared.
Ttelmah, correct me if I am wrong Embarassed


To set a particular port pin which leaves the state of the other pins alone, use | (OR). Specifically, either read the state of the port (or if you "remember" what it is), then OR that with a pattern corresponding to the pin(s) you want to set.

To clear a particular port pin which leaves the state of the other pins alone, you need to & (AND) with a suitable pattern that will leave the state of the other pins alone. If you wanted to clear bit 0, you'd and with 0xfe to ensure that the other pins weren't cleared by the operation.
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

PostPosted: Mon Oct 20, 2014 9:17 am     Reply with quote

Yes I see my mistake. Thank you.
So in this case
Code:

output_b(state | 0x03);

should be applied?
_________________
A person who never made a mistake never tried anything new.
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Mon Oct 20, 2014 9:32 am     Reply with quote

Not quite, that will always switch on bit 0 and 1.

What newguy meant if you were concerned about the other pins you would read back the port latches AND it with 0xfc and then OR it with state which will then only update the first 2 bits.

Must say I think I just confused myself Smile
Code:

output_b((input_b() & 0xfe) | state); //state must then never be more than 3

Regards
MDM1985



Joined: 16 Oct 2014
Posts: 14

View user's profile Send private message

PostPosted: Mon Oct 20, 2014 12:51 pm     Reply with quote

Ttelmah wrote:
This is a classic 'state' problem:
Code:

#define RELAY_1_ON (130)
#define RELAY_2_ON (160) //Set where you want
#define THRESHOLD (5) //threshold to turn off
#define OFF 0
#define R1 1
#define R2 2  //binary masks - place to suit the relay bits required

int8 state=OFF;
..........
    //Now, assume arrive here with variable 'volt' from the adc

    if (volt>RELAY_1_ON)
        state|=R1; //turn relay 1 on
    else
    {
        //only get here if _not_ above the 'on' point
        if (volt<(RELAY_1_ON-THRESHOLD))
           state&=(~R1); //turn relay 1 off if below ON-THRESHOLD 
    }     
    //Now the same for relay 2
    if (volt>RELAY_2_ON)
        state|=R2; //turn relay 2 on
    else
    {
        if (volt<(RELAY_2_ON-THRESHOLD))
           state&=(~R2); //turn relay 2 off if below ON-THRESHOLD
    }
    //then just output the bits to the relays
    output_b(state); //whatever port you are using


The individual bits (R1, and R2) get turned 'on' if above the specified 'ON' points, but then have to drop 'THRESHOLD' counts below this point, before they will turn off.



Sorry, but I don't understand.

When volt > RELAY_2_ON, we have also the condition volt > RELAY_1_ON thus relay 1 and relay 2 are ON? Is this correct?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Oct 21, 2014 5:41 am     Reply with quote

MDM1985 wrote:
Sorry, but I don't understand.

When volt > RELAY_2_ON, we have also the condition volt > RELAY_1_ON thus relay 1 and relay 2 are ON? Is this correct?


I asked several post ago for an EXACT description of what you want.
You have not responded, so I'll ask again in a different format.
(From the trend in the thread it appears that others like myself can't decipher what you want either.)

What do you want the relay states to be :-

1) Below the lower threshold?
2) Between the two thresholds?
3) Above the upper threshold?

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Tue Oct 21, 2014 7:37 am     Reply with quote

It is perhaps worth also pointing out that any layout you want can already be handled by just using 'state' as a value to test, rather than outputting it directly.

As written, state has four different possible value:

0 volt is below both levels
1 volt is above level1, but below level 2
2 volt is above level2 but below level 1
3 volt is above level1, and above level2

Simply test for these four values, and put out the relay pattern required for each.

Use switch(state), and just put the relay pattern for each state in the four possibilities.
MDM1985



Joined: 16 Oct 2014
Posts: 14

View user's profile Send private message

PostPosted: Tue Oct 21, 2014 2:13 pm     Reply with quote

Mike Walne wrote:
MDM1985 wrote:
Sorry, but I don't understand.

When volt > RELAY_2_ON, we have also the condition volt > RELAY_1_ON thus relay 1 and relay 2 are ON? Is this correct?


I asked several post ago for an EXACT description of what you want.
You have not responded, so I'll ask again in a different format.
(From the trend in the thread it appears that others like myself can't decipher what you want either.)

What do you want the relay states to be :-

1) Below the lower threshold?
2) Between the two thresholds?
3) Above the upper threshold?

Mike


I would like to have relay 1 ON below the lower threshold; when the voltage value is in the middle between the lower threshold and upper threshold, I would like to have relay 1 OFF and relay 2 ON but when the voltage is changing close to the lower threshold (for example TH_LOW + 5 or TH_LOW - 5) I would like to avoid the relay chattering. The same for the upper threshold: I would like to have relay 2 OFF when the voltage is higher than the upper threshold but when the voltage is changing close to the upper threshold, I would like to avoid the relay chattering.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Oct 22, 2014 4:36 am     Reply with quote

What you now have is a system with five states, as shown below:-

Code:
Max. ADC reading


Upper region. Set required relays state here


---------------------------------------
TH2 Do NOTHING in this region (dead-band)
---------------------------------------


Middle region. Set required relays state here



---------------------------------------
TH1 Do NOTHING in this region (dead-band)
---------------------------------------



Lower region. Set required relays state here



Min. ADC reading

There are three regions where you can change the relay states.
Make sure you do not change the relay states in either of the two dead-bands.
The width of the dead-band depends on your system (noise, jitter, etc).
How you program is up to you.

Mike
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
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