PIC12F629 Comparator with delay

Thread Starter

Twitch

Joined Jun 14, 2010
3
Hi, I am new to PIC programming, only started a couple of days ago. I am currently using the following comparator code:

/************************************************************************
* *
* Filename: MC_L6-Comp_LED-HTC.c *
* Date: 17/8/09 *
* File Version: 1.0 *
* *
* Author: David Meiklejohn *
* Company: Gooligum Electronics *
* *
*************************************************************************
* *
* Architecture: Midrange PIC *
* Processor: 12F629 *
* Compiler: HI-TECH C PRO v9.65PL1 Lite *
* *
*************************************************************************
* *
* Files required: none *
* *
*************************************************************************
* *
* Description: Lesson 6, example 1a *
* *
* Demonstrates basic comparator operation *
* *
* Turns on LED when voltage on CIN+ > voltage on CIN- *
* *
*************************************************************************
* *
* Pin assignments: *
* CIN+ - voltage to be measured (e.g. pot output or LDR) *
* CIN- - threshold voltage (set by voltage divider resistors) *
* GP5 - indicator LED *
* *
************************************************************************/

#include <htc.h>


/***** CONFIGURATION *****/
// ext reset, no code or data protect, no brownout detect,
// no watchdog, power-up timer enabled, 4MHz int clock
__CONFIG(MCLREN & UNPROTECT & BORDIS & WDTDIS & PWRTEN & INTIO);

// Pin assignments
#define LED GPIO5 // indicator LED on GP5
#define nLED 5 // (port bit 5)



/***** MAIN PROGRAM *****/
void main()
{
// Initialisation
TRISIO = ~(1<<nLED); // configure LED pin (only) as an output

// configure comparator
CMCON = 0b010; // select mode 2 (CM = 010):
// +ref is CIN+, -ref is CIN-,
// comparator on, no external output
CINV = 1; // output inverted
// -> COUT = 1 if CIN+ < CIN-

// Main loop
for (;;)
{


LED = COUT; // continually display comparator output
}
}
What I want do is to add a 2 second delay before the LED is ON and before the LED is OFF

In some pseudo-code:

If CIN+ < CIN- is true for a minimum of 2 seconds
Turn LED ON
Else, do nothing

If CIN+ > CIN- is true for a minimum of 2 seconds
Turn OFF LED
Else, do nothing

So the LED will only turn on if CIN+ < CIN- is true for more than 2 seconds. Once the LED is ON, if CIN+ > CIN- for a minimum of 2 seconds, it will turn the LED OFF.

Thanks for the help, I'm a newbie at this.
 

ELECTRONERD

Joined May 26, 2009
1,147
I'm not sure if your compiler will accept this delay command, but try it:

Rich (BB code):
Delay10KTCYx(Delay);
You'll have to include the header file "delays.h".
 

Thread Starter

Twitch

Joined Jun 14, 2010
3
I'm not sure if your compiler will accept this delay command, but try it:

Rich (BB code):
Delay10KTCYx(Delay);
You'll have to include the header file "delays.h".
Does this line mean "Wait a certain time" before continuing or does it mean " check if CIN+ < CIN- is true for a certain time before continuing"?

Sorry for my ignorance, I am new at this.
 

ELECTRONERD

Joined May 26, 2009
1,147
Does this line mean "Wait a certain time" before continuing or does it mean " check if CIN+ < CIN- is true for a certain time before continuing"?
Yes. It tells the processor to burn up clock cycles for however long you choose, or simply a delay. Your latter statement doesn't make sense if you think about it. Microcontrollers (uC) are very fast when it comes to processing, so it would only take a very short duration for your uC to test if that statement is true. Why have it test slower?

Sorry for my ignorance, I am new at this.
Don't worry about it, we all had to start from the ground up. Just keep working on it and you'll get better. ;)
 

eng1ne

Joined Dec 4, 2009
97
Which compiler are you using?

A delay is probably your best solution as Electronerd says. Bear in mind however, that if you check is A < B at time 0, then check again at t = 2s, you can't guarantee that A < B for the whole 2s.

A < B might begin at t = -0.1s and end at t = 0.1s, then might begin again at t = 1.9s and end at t = 2.1s; thus you have a false reading.

Are you trying to debounce a switch?

Like Electronerd says, you can read much faster than every 2 seconds.
 

Thread Starter

Twitch

Joined Jun 14, 2010
3
Which compiler are you using?

A delay is probably your best solution as Electronerd says. Bear in mind however, that if you check is A < B at time 0, then check again at t = 2s, you can't guarantee that A < B for the whole 2s.

A < B might begin at t = -0.1s and end at t = 0.1s, then might begin again at t = 1.9s and end at t = 2.1s; thus you have a false reading.

Are you trying to debounce a switch?

Like Electronerd says, you can read much faster than every 2 seconds.
I am using the HI-TECH compiler. Yes, I am trying to debounce a switch

There is a code in the tutorial:
/************************************************************************
* *
* Filename: stdmacros-HTC.h *
* Date: 28/9/08 *
* File Version: 1.0 *
* *
* Author: David Meiklejohn *
* Company: Gooligum Electronics *
* *
*************************************************************************
* *
* Architecture: Baseline or Midrange PIC *
* Processor: any *
* Compiler: HI-TECH C PRO v9.60PL3 *
* *
*************************************************************************
* *
* Files required: none *
* *
*************************************************************************
* *
* Description: Library of useful macros *
* *
* DelayS() - delay in seconds (wrapper for DelayMs function) *
* DbnceHi - debounce switch, wait for high input *
* DbnceLo - debounce switch, wait for low input *
* *
************************************************************************/


/***** DELAY MACROS *****/

// DelayS()
//
// Delay in seconds (max 25.5)
//
// Calls: __delay_ms() (requires definition of _XTAL_FREQ)
//
#define DelayS(T) {unsigned char i; for (i=0; i<T*10; i++) __delay_ms(100);}


/***** DEBOUNCE MACROS *****/

#define DEBOUNCE 10*1000/256 // switch debounce count = 10ms/(256us/tick)

// DbnceHi()
//
// Debounce switch on given input pin
// Waits for switch input to be high continuously for 10ms
//
// Uses: TMR0 Assumes: TMR0 running at 256 us/tick
//
#define DbnceHi(PIN) TMR0 = 0; /* reset timer */ \
while (TMR0 < DEBOUNCE) /* wait until debounce time */ \
if (PIN == 0) /* if input low, */ \
TMR0 = 0 /* restart wait */


// DbnceLo()
//
// Debounce switch on given input pin
// Waits for switch input to be high continuously for 10ms
//
// Uses: TMR0 Assumes: TMR0 running at 256 us/tick
//
#define DbnceLo(PIN) TMR0 = 0; /* reset timer */ \
while (TMR0 < DEBOUNCE) /* wait until debounce time */ \
if (PIN == 1) /* if input high, */ \
TMR0 = 0 /* restart wait */
But I do not know how to put it into my current code. My CIN- is set at 1.5V, the CIN+ will go to 0.00V then the LED turns on.

The reason for the "delay" prevent the LED from turning on and off quickly if the CIN+ suddenly flickers above 1.5V, it doesn't happen all the time, it's just a preventive measure. The the CIN+ must be lower than CIN- for more than 2 seconds before the LEd turns on
 
Top