Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
November 28, 2024, 08:51:13 20:51


Login with username, password and session length


Pages: 1 [2]  All
Print
Author Topic: PIC Dimmer issue with LCD display  (Read 13627 times)
0 Members and 1 Guest are viewing this topic.
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #25 on: July 06, 2013, 04:12:31 16:12 »

Hi hate:

I contacted CCS and I just got the info that there is no such function in CCS to stop the timer. You can either reload the timer with 0 i.e. set_timerX(0) or reset the flag with clear_interrupt(timerX) which will in essence stop the timer. But CCS itself adds clear_interrupt(timerX) in INT routine at compilation time.

Seems I got a solution for LCD issue though I need more testing to conclude.
« Last Edit: July 06, 2013, 04:14:40 16:14 by leaveme » Logged
hate
Hero Member
*****
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #26 on: July 06, 2013, 04:55:25 16:55 »

From the CCS compiler reference located here http://www.ccsinfo.com/downloads/ccs_c_manual.pdf:

Quote
Timer1
These options lets the user configure and use timer1. The clock/counter is 16-bit on pic16s and pic18s. It
counts up and also provides interrupt on overflow. The options available differ and are listed in the device
header file.
Relevant Functions:
setup_timer_1(mode)  Disables or sets the source and prescale for timer1
set_timer1(value)  Initializes the timer1 clock/counter
value=get_timer1  Returns the value of the timer1 clock/counter
Relevant Preprocessor:
None
Relevant Interrupts:
INT_TIMER1  Interrupt fires when timer1 overflows
Relevant Include Files:
None, all functions built-in
Relevant getenv() parameters:
TIMER1  Returns 1 if the device has timer1
Example Code:
For PIC18F452
setup_timer_1(T1_DISABLED);  //disables timer1
or
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //sets the internal clock as source
//and prescale as 8. At 20Mhz timer1 will increment
//every 1.6us in this setup and overflows every
//104.896ms
set_timer1(0);  //this sets timer1 register to 0
time=get_timer1();  //this will read the timer1 register value

The code snippet:
Code:
setup_timer_1(T1_DISABLED);  //disables timer1
makes clear setup_timer_1() can stop timer1 as I predicted before. You are free to try it on a 16f mcu but I doubt it won't work. That gives 2 possibilities,

1- Either the CCS people are the dumbest guys ever to maintain a compiler,

2- You are still being careless.

I don't think it's option 1 so good luck with your project!
Logged

Regards...
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #27 on: July 06, 2013, 05:22:30 17:22 »

These are the options for setup_timer_1(). I do not see any constant to re-enable the Timer1. I'm not sure whether T1_INTERNAL...T1_EXTERNAL will serve the purpose.

Code:
// Constants used for SETUP_TIMER_1() are:
#define T1_DISABLED         0
#define T1_INTERNAL         5
#define T1_EXTERNAL         7
#define T1_EXTERNAL_SYNC    3

#define T1_CLK_OUT          8

#define T1_DIV_BY_1         0
#define T1_DIV_BY_2         0x10
#define T1_DIV_BY_4         0x20
#define T1_DIV_BY_8         0x30

Anyway, Thanks a lot for all your help. Take care.
Logged
Ichan
Hero Member
*****
Offline Offline

Posts: 833

Thank You
-Given: 312
-Receive: 392



WWW
« Reply #28 on: July 06, 2013, 07:51:31 19:51 »

I can not go to the detail as i do not use CCS, the concept that i am thinking of is something like this:

1. On external interrupt (zero cross) set the required timer value and enable the timer
2. On first timer interrupt turn on the triac, set the next timer value (for the delay) and set a flag to mark next timer interrupt
3. On the next timer interrupt turn off the triac, reset the flag and disable the timer

No delay required...  Cool.

Many times i can not avoid to use delay function on my program, that is why i hate it...

edit: change the word "second" with "next" to make it clear that only one timer used.

-ichan
« Last Edit: July 07, 2013, 08:32:42 08:32 by Ichan » Logged

There is Gray, not only Black or White.
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #29 on: July 07, 2013, 11:53:34 11:53 »

Thanks Ichan. I got it working.

Just a little issue with ADC data. I get ADC value from 0-1022 (to adjust the luminosity). But ADC value varies 1 or 2 digit. For instance, I set the pot to 500. But adc value fluctuates i.e. 499...501, which creates a very minor flickering. I used following logic.

Code:
   for(i = 0; i < 100; i++) { 
      adc_data += read_adc(ADC_START_AND_READ);
   }

   ref_data=adc_data/i;
   ...

Is there any other idea to improve?
Logged
h0nk
Senior Member
****
Offline Offline

Posts: 257

Thank You
-Given: 226
-Receive: 231



« Reply #30 on: July 07, 2013, 03:46:58 15:46 »

Hello,

perhaps:
for(i = 0; i < 256; i++) {
should do the job.

Or:
try a capacitor from AN0 to VSS. 10 uF should be fine.


Best Regards
Logged
robotai
Junior Member
**
Offline Offline

Posts: 60

Thank You
-Given: 27
-Receive: 23


« Reply #31 on: July 08, 2013, 05:51:20 05:51 »

I don't think the ADC can keep steady even adding capacitor. The may be noise within your power line which will cause voltage reference varying.

I would suggest reduce resolution on ADC scale to keep it steady. Hope below code help.

Code:
new_adc_data = read_adc(ADC_START_AND_READ);  // read ADC
new_adc_data /= 2;  // reduce resolution to 1024/2=512 scale
if((new_adc_data > adc_data + 1) || (new_adc_data + 1 < adc_data))  // further reduce resolution only when change over 2 level within 512 scale
  adc_data = new_adc_data;
Logged
Ichan
Hero Member
*****
Offline Offline

Posts: 833

Thank You
-Given: 312
-Receive: 392



WWW
« Reply #32 on: July 08, 2013, 11:11:50 11:11 »

Some had been mentioned above,

1. Make sure the supply and ref voltage is stable and clean
2. Add RC or LC filter at analog input
3. Use good quality pots
4. Pay attention on pcb layout
5. Filter out some unwanted data, let say take 10 adc reading, remove the highest and lowest value then average the rest 8 data.

The way you read the adc is a kind of "blocking code" - consider to use adc interrupt reading. Also if the adc_data is 16bit then it can be overflowed inside that 100 loops.

-ichan
« Last Edit: July 08, 2013, 11:19:09 11:19 by Ichan » Logged

There is Gray, not only Black or White.
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #33 on: July 09, 2013, 06:05:11 06:05 »

Finally, my dimmer is working great with a nice bargraph (dim level).  Grin
I used ADC denoising filter and adc fluctuation is gone.

Thanks a lot to all of you.

Code:
unsigned int16 adc_denoise(void) {  // read 16 - sort, keep middle 8 average 

 unsigned int8 i;  unsigned int16 accum=0; 
 unsigned int16 s, b[16]; int1 didswap=1;

   for ( i = 0 ; i < 16;  i++ ) {
           b[i]= read_adc(ADC_start_and_read);  // ADC set for 10 - 12 bits
           delay_us(8); 
     } //    end of for loop for multi sample
   while(didswap){               // bubble sort
     didswap=0;
     for (i=0; i<15; i++){      // i 0-15
      if(b[(i)]>b[(i+1)]){        // if low element greater than next  -do  swap
           s=b[i]; // hold upper
           b[i]=b[(1+i)];
           b[(1+i)]=s;
           didswap=1;
      } // ~if
     } // ~for
    } // ~while
   // now sort and keep middle 8 values
   for (i=4; i<12; i++){  accum +=b[i];  }
   return(accum>>3);
}
Logged
Pages: 1 [2]  All
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC