Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Interfacing LDR with PIC12F675 output jitter @ saturation point

Status
Not open for further replies.

asking

Full Member level 5
Joined
Sep 21, 2010
Messages
279
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,298
Activity points
3,377
Hi,

I am trying to make one Time Switch which enables only after specific light conditions and keep running for predefine timer (Free running counter).

I have used 2 ADC Channels 1 for Adj for POT (Preset for light sensing) and 2nd ADC channel for LDR input from a low pass filter of 75HZ (to avoid noise). Now issue is when i set something value to near to the actualy lighting condition. The output jitter's small flicker.. How to avoid jittering ? i just want to keep that about preset of around 7pm at night the output should energize the relay direction no jittering.... how to do that.

mikroc code by me for my LDR Light switch. Please suggest some solution.

Thanks

Code:
unsigned int ADC_LUX, ADC_ADJ;
unsigned long int TCOUNT;
unsigned short var1, var2;

// Interrupt Handler
void interrupt()
{
  // Timer0 Interrupt - Freq = 15.26 Hz - Period = 0.065536 seconds
  if (INTCON.TMR0IF == 1) // timer 0 interrupt flag
  {
    TCOUNT = TCOUNT + 1;
    if (TCOUNT > 100)            //332300 COUNT EQUALS TO 8 HOURS
    //var1 = 0;
    TCOUNT = 0;
   // GPIO.GP4 = ~GPIO.GP4;      // Toggle PORTB bit0 LED
    INTCON.TMR0IF = 0;         // clear the flag
    INTCON.TMR0IE = 1;         // reenable the interrupt
    TMR0 = 0;           // reset the timer preset count
  }

}


void main() {
ADC_Init();
ADCON0 = 0x00;
ANSEL = 0X03; // AN0 & AN1 CONFIGURED AS ANALOGUE INPUT
TRISIO = 0b00000011;
//GPIO = 0X00;
CMCON = 0x07;
var1 = 0;
var2 = 0;

//Timer0 Registers Prescaler= 256 - TMR0 Preset = 0 - Freq = 15.26 Hz - Period = 0.065536 seconds
OPTION_REG.T0CS = 0;  // bit 5  TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
OPTION_REG.T0SE = 0;  // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
OPTION_REG.PSA = 0;   // bit 3  Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
OPTION_REG.PS2 = 1;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits
OPTION_REG.PS1 = 1;
OPTION_REG.PS0 = 1;
TMR0 = 0;             // preset for timer register


// Interrupt Registers
  INTCON = 0;           // clear the interrpt control register
  INTCON.TMR0IE = 1;        // bit5 TMR0 Overflow Interrupt Enable bit...1 = Enables the TMR0 interrupt
  INTCON.TMR0IF = 0;        // bit2 clear timer 0 interrupt flag
  INTCON.GIE = 1;           // bit7 global interrupt enable


while(1)
{

ADC_ADJ = ADC_READ(0);
ADC_ADJ = ADC_ADJ/1;           // divide by 1 for maximum sensitivity @ 10 bit resolution
ADC_LUX = ADC_Read(1);
ADC_LUX = ADC_LUX/1;


}

- - - Updated - - -

24n1tgj.png
 

I don't see how the analog inputs would be processed in your code. Comparator module is disabled and ADC measurements are nowhere read.

Apart from this point, I presume you'll need to implement some hysteresis to avoid unwanted switching.
 

Code:
unsigned int ADC_LUX, ADC_ADJ;
unsigned long int TCOUNT;
unsigned short int var1,var2,var3;

// Interrupt Handler
void interrupt()
{
  // Timer0 Interrupt - Freq = 15.26 Hz - Period = 0.065536 seconds
  if (INTCON.TMR0IF == 1) // timer 0 interrupt flag
  {
    TCOUNT = TCOUNT + 1;
    if (TCOUNT == 100000)            //332300 COUNT EQUALS TO 8 HOURS
    TCOUNT = 0;
   // GPIO.GP4 = ~GPIO.GP4;      // Toggle PORTB bit0 LED
    INTCON.TMR0IF = 0;         // clear the flag
    INTCON.TMR0IE = 1;         // reenable the interrupt
    TMR0 = 0;           // reset the timer preset count
  }

}


void main() {
ADC_Init();
ADCON0 = 0x00;
ANSEL = 0X03; // AN0 & AN1 CONFIGURED AS ANALOGUE INPUT
TRISIO = 0b00000011;
//GPIO = 0X00;
CMCON = 0x07;
var1 = 0;
var2 = 0;
var3 = 0;

//Timer0 Registers Prescaler= 256 - TMR0 Preset = 0 - Freq = 15.26 Hz - Period = 0.065536 seconds
OPTION_REG.T0CS = 0;  // bit 5  TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
OPTION_REG.T0SE = 0;  // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
OPTION_REG.PSA = 0;   // bit 3  Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
OPTION_REG.PS2 = 1;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits
OPTION_REG.PS1 = 1;
OPTION_REG.PS0 = 1;
TMR0 = 0;             // preset for timer register


// Interrupt Registers
  INTCON = 0;           // clear the interrpt control register
  INTCON.TMR0IE = 1;        // bit5 TMR0 Overflow Interrupt Enable bit...1 = Enables the TMR0 interrupt
  INTCON.TMR0IF = 0;        // bit2 clear timer 0 interrupt flag
  INTCON.GIE = 1;           // bit7 global interrupt enable


while(1)
{

ADC_ADJ = ADC_READ(0);
ADC_ADJ = ADC_ADJ/1;           // divide by 1 for maximum sensitivity @ 10 bit resolution
ADC_LUX = ADC_Read(1);
ADC_LUX = ADC_LUX/1;



if (ADC_LUX <= 540 && var1 == 0)
{
GPIO.GP5 = 1;
TCOUNT = 0;
}

if (TCOUNT >= 980 || ADC_LUX >= 710)
{
GPIO.GP5 = 0;
var1 = 1;
}

if (ADC_LUX >= 710)
{
var1 = 0;
}
}
}


sorry i don't know by mistake i posted the wrong code. I have reposted the original code. i have tried to implement turn on / off point at different levels (hysteresis). here i want to count upto 332300 counts using TCOUNT = TCOUNT + 1; frequency 15.26HZ every 0.06 it will keep on incrementing. I want to generate 6 or 8 hours delay. but i am afraid its 8 bit microcontroller and 332300 is 16 bit value how can i achieve that ?

Please guide me.
 

332300 is actually beyond 16 bit range. But most 8 bit compilers support 32 bit types like unsigned long as well. Otherwise you can use cascaded counters.
 
  • Like
Reactions: asking

    asking

    Points: 2
    Helpful Answer Positive Rating
Thanks for your help. Finally i found instead of using (TCOUNT == 100000) if i use (TCOUNT > 100000) the 2nd case works perfect. i think = too might be too fast to catch and it misses. Problem seems to be solved :)
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top