|
|
View previous topic :: View next topic |
Author |
Message |
leaveme
Joined: 24 Nov 2010 Posts: 19
|
New PIC user: Need help for AC dimmer |
Posted: Fri Nov 26, 2010 10:16 am |
|
|
I have a sound knowledge in electronics but this is first time I'm trying to build something in PIC mictrocontroller.
The project is actually an AC Dimmer project based on phase control method. I used PIC16F84A with an ADC (TLC548) for my project but it doesn't work as expected. I read many forums/posts and modified the coding, still no improvement at all.
Any help will guide me for learning and be greatly appreciated.
Code: |
//#include <16F88.h>
#include <16F84A.h>
#FUSES NOWDT,HS,NOPUT,NOPROTECT
#use delay(clock=20000000)
#use fast_io(A)
#use fast_io(B)
#byte OPTIONREG = 0b01001000
//#byte OPTIONREG = 0x81
#byte PORTA = 0x05
#byte PORTB = 0x08
#byte ANSEL = 0x9B
#define ZERO_IN PIN_B0 /* Zero Cross Detection PIN*/
#define TRIAC PIN_A0 /* Phase Ctrl Output PIN /TRIAC trigger*/
#define DOut PIN_A1 // Data out for ADC TLC549
#define CS PIN_A2 // Chip select for ADC TLC549
#define CLK PIN_A3 // I/O Clock for ADC TLC549
#define ON output_high /* To set Output to ON state */
#define OFF output_low /* To set Output to OFF state */
/** Mains Frequency **/
//#define HZ60 /* For 60Hz Mains system */
#define HZ50 /* For 50Hz Mains system */
#ifdef HZ50
#define TIMER_RELOAD 163
#endif
#ifdef HZ60
#define TIMER_RELOAD 181
#endif
#define TR_DELAY delay_ms(10) /* To set Trigger interupt */
//#define TR_DELAY delay_us(20) /* To set Trigger interupt */
unsigned char voltage = 0; // set and clear voltage variable
unsigned char bitcount = 0; // set and clear bitcount variable
unsigned char readadc(void); // declare readadc function
int TRIGGER;
int INTENSITY;
//zero crossing detector
/***********************************************************************/
#INT_EXT
void ext_isr()
{
TRIGGER=0;
if (input(ZERO_IN))
ext_int_edge(H_TO_L);
else
ext_int_edge(L_TO_H);
}
//Triac firing Interupt Timer
/***********************************************************************/
#INT_TIMER0
void tmr0_isr(){
// TIMER_RELOAD==326;
set_timer0(TIMER_RELOAD);
TRIGGER++;
if (TRIGGER==INTENSITY){
ON(TRIAC);
TR_DELAY;
OFF(TRIAC);
}
}
//Main function
/***********************************************************************/
void main(void)
{
// set_tris_a(0x0e); //set port directions 0=out, 1=in
// set_tris_b(0x01);
set_tris_A(0b00010);
set_tris_B(0b00000001);
PORTA = 0x00; // clear portA
PORTB = 0x00; // clear portB
// Disable & clear all interupts
disable_interrupts(INT_TIMER0);
disable_interrupts(INT_EXT);
disable_interrupts(GLOBAL);
// if (!INPUT(ZERO_IN)) OUTPUT_LOW(TRIAC); //Zero detection at START
// ANSEL=0;
// OPTIONREG=OPTIONREG & 0x7F;
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_EXT);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
set_timer0(TIMER_RELOAD);
// ON(CS); // set CS for ADC high
while(1) { // loop for ever
voltage = 0; // clear voltage
readadc(); // read A-D convertor
INTENSITY = voltage; // Set ADC result in intensity
}
}
/****************** END OF main *******************/
/* Read ADC TLC548 */
unsigned char readadc(void)
{
#asm
bcf PORTA,2; // take CS low
nop;
nop; // delay for 2uS
movlw 0x08;
movwf bitcount; // move 8 to bitcount
loop:
bsf PORTA,3; // take clk high
rlf voltage,f; // rotate voltage
btfsc PORTA,1 // check if data = 1
bsf voltage,0 // if 1 set bit 0 to 1 else leave at zero
bcf PORTA,3; // take clk low
decfsz bitcount; // decrement bitcount
goto loop; // loop if count not zero
bsf PORTA,2; // take CS high
movlw 0x05; // delay for minimum 17uS
movwf bitcount; // use count variable for delay
loop2:
decfsz bitcount; // loop till bitcount = 0
goto loop2;
#endasm
return(voltage); // return value to main
}
/************** END OF READADC *******************/
|
AC Dimmer Schematic |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Fri Nov 26, 2010 11:55 am |
|
|
Could you be a bit more specific about the failure?
Have you tried a simpler version of your program to exercise the interfaces? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Fri Nov 26, 2010 12:14 pm |
|
|
some ideas...
You might want to get rid of the external ADC and use a newer PIC with builtin ADC and serial port.
This would eliminate some potential problems(board layout, software,etc).
Be very,VERY careful with that circuit. the MAINS voltage can easily kill you, or at least ruin your day if the board shorts and blows up the chips.
I'd add 8 LEDs and 330rs to one port and veryify the pot-ADC hardware and software are working correctly.Simply cut code to read pot and display the result on the LEDs, should go from 00-ffx, LEDS will lightup in binary.
If you goto a newer PIC, you could send the ADC result to a PC to display..
Add a small cap to the trimpot to filter out noise.
Add small caps as bypass on each power pin
Add an LED in series with the diode of the MOC3021.This will glow dim-full on in sync with the trimpot setting.
If you have an oscilloscope look at the sync( zero cross) input and the PIC output to the MOC3021. Do this with MAINS OFF, it's safer that way !
If you put an LED in series between the R2(330r) and the MOC3021 pin 6, you'll have a handy free load indicating SSR. LED glows when lamp should be on.Helps verify burned out lamps,mains wiring off,etc.
hth
jay |
|
|
leaveme
Joined: 24 Nov 2010 Posts: 19
|
|
Posted: Fri Nov 26, 2010 12:24 pm |
|
|
Well, I simulated it in Proteus and there are two problems:
1. The output is flickering. Most likely problem is in timer interrupt routine.
2. Data read from adc.
I can provide the Proteus file if you need that.
Thanks for your help. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Fri Nov 26, 2010 1:24 pm |
|
|
Sorry but I NEVER trust simulators. They are NOT the real World. Been doing this gig since early 70s and have yet to run one that actually performed properly.
Hardware is the only real testbed to use.
Unless you can setup Proteus to 'simulate' the EM I get from the myriad of devices near my bench (smart meter, Weller soldering station, smart furnace stat, clothes washer, laser printer, t10 fl lamps, etc.)
Been burned couple of times with 'simulators', don't trust them, lost over $100,000 due to a 'glitch' in the simulator .....so chips and copper is the only things I trust !
Cheers
Now as to...
problem #1. Flickering. Could be a timing issue within Proteus not being able to update properly parameters correctly.
#2. Data read from ADC. Again, maybe a Proteus timing issue. Not generating clock signals correctly, edges not synced, race conditions.
If #2 is not running right, it will of course alter #1...so I'd test the ADC section first (using simple hardware). Once it is bulletproof carry on to #1.
And of course there's the whole gambit of what PC you're using (memory, speed, video, version of Windows, updates, # of programs open/running, etc.) Something as simple as a 'hidden' task, wanting Internet access to do an automatic update can be serious !
Remember this is not hard silicon but 'soft', subject to someone's idea of what the chip 'should' be doing. Even Microchip has errata that MUST be read and figured out if they pertain to your version of the PIC. |
|
|
leaveme
Joined: 24 Nov 2010 Posts: 19
|
|
Posted: Fri Nov 26, 2010 3:50 pm |
|
|
Thanx guy's.
Actually I was looking for...if someone take a look on my coding. I'll be really glad. |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Fri Nov 26, 2010 3:58 pm |
|
|
One thing I don't see described here is how good your zero-crossing detection is working. If that is not correct, you will have all sorts of strange things going on - if you are detecting noise instead of an actual zero crossing, your phase control will wander all over the place (been there, done that ).
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
leaveme
Joined: 24 Nov 2010 Posts: 19
|
|
Posted: Fri Nov 26, 2010 11:49 pm |
|
|
A...h...no one wants to help me...
I actually need your opinion/suggestion wheather my coding is right since I never used PIC/CCS before. |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Sat Nov 27, 2010 12:43 am |
|
|
I don't know about the others, but I don't do much in PIC assembler (my favorite assembler is 8080/Z80 -- in octal !! ). I didn't see anything obvious, but my question still stands about the zero crossing - if that is not correct, all bets are off.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 27, 2010 2:17 pm |
|
|
Quote: | //#include <16F88.h>
#include <16F84A.h>
#FUSES NOWDT,HS,NOPUT,NOPROTECT
#use delay(clock=20000000)
unsigned char readadc(void)
{
#asm
bcf PORTA,2; // take CS low
nop;
nop; // delay for 2uS
movlw 0x08;
movwf bitcount; // move 8 to bitcount
|
Your ASM code was designed (and presumably tested) for 4 MHz operation
only. This is shown by the two nops being commented as a 2 us delay.
The TLC548 data sheet says you need a minimum delay of 1.4 us after
\CS goes low. You have increased the PIC clock speed to 20 MHz. The
delay of those two nops is now only 400 ns. Therefore, you are violating
the TLC548 data sheet, and you will likely get flakey results from the A/D.
If you had written your TLC548 driver in CCS C, and used CCS functions
such as delay_us(2), then you would have a 2 us delay at both 4 MHz and
20 MHz operation, because the compiler would automatically make it so.
It's best to re-write your ASM code in C. |
|
|
|
|
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
|