View previous topic :: View next topic |
Author |
Message |
matthewmilford
Joined: 09 Feb 2021 Posts: 23
|
Interrupt Issue |
Posted: Wed Feb 24, 2021 1:28 pm |
|
|
Hello all. Hopefully someone has ran into this issue before. I am using a triac to switch AC from a pic 18f26k42. This is the simplest code version that I can come up with, however it seems to be skipping signals. I am feeding in a 60 hz square wave. It should be driving an output on every change (up or down) it isn't. What is puzzling me about this is that there seems to be no pattern as to how often the signal coming out of the pic occurs. When it occurs it is always in the correct place on the waveform and will light the bulb, however it is missing the vast majority of the signals. It seems to me that I maybe overflowing a buffer or possibly the pic is going to sleep? Any insight would be appreciated.
Mplab x v5.35
Code: |
#include <18f26k42.H>
#include <stdio.h>
#define triac_gate PIN_A1
#PIN_SELECT INT1=PIN_B0
#use delay(clock = 4MHz)
int ZC = 0;
//******************************************************************
#INT_EXT // external interrupt ISR
void EXT_ISR()
{
//clear_interrupts(INT_EXT);
ZC = 1;
}
//******************************************************************
void main()
{
//ext_int_edge(H_TO_L); //catch only high to low
output_low(triac_gate);
output_drive(triac_gate);
clear_interrupt(INT_EXT); // clear external interrupt flag bit
enable_interrupts(INT_EXT); // enable external interrupt
enable_interrupts(GLOBAL); // enable global interrupts
while(TRUE)
{
if(ZC == 1)
{
ZC = 0;
delay_ms(4);
output_high(triac_gate);
delay_us(5);
output_low(triac_gate);
}
}
}
|
Last edited by matthewmilford on Wed Feb 24, 2021 1:42 pm; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Wed Feb 24, 2021 1:40 pm |
|
|
Ok, what is the hardware that's between the AC signal and the PIC ?
If you're actually feed in AC, you WILL destroy the PIC, sooner or later.....
You NEED a proper 'zero cross detector' circuit... |
|
|
matthewmilford
Joined: 09 Feb 2021 Posts: 23
|
|
Posted: Wed Feb 24, 2021 1:45 pm |
|
|
There is an isolator between the ac and the pic. I am not feeding in ac direct, the square wave form is coming off a zero cross detector.
Also I used a scope and the pic is getting in a correct square wave on pin b0.
Just to clarify also.... I have tested the circuit... If I unplug the pic and short across my +5v to the signal line I get a steady full on which is what should be expected with an all on signal. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
matthewmilford
Joined: 09 Feb 2021 Posts: 23
|
|
Posted: Wed Feb 24, 2021 3:17 pm |
|
|
Okay, I will look into that and see if it will work for my application. |
|
|
matthewmilford
Joined: 09 Feb 2021 Posts: 23
|
Update |
Posted: Wed Feb 24, 2021 3:58 pm |
|
|
I have been looking into the ZCD module. I don't think it will work for my application. Primarily due to I do not want to tie my microchip and control circuitry to Ac mains. I am working with an optically isolated 0-5v dc square wave. Any thoughts as to why the original code only fires every 10th or so (inconsistent) cycles. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 24, 2021 5:23 pm |
|
|
You've selected INT1 as the interrupt for PIN_B0. Then you setup your
isr for INT_EXT. That's not correct. INT0 is the correct interrupt for
INT_EXT. Fix this line:
Quote: | #PIN_SELECT INT1=PIN_B0 |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Thu Feb 25, 2021 3:45 am |
|
|
This is one where it is easy to get confused. Unfortunately, CCS are still
sticking with the 'old' interrupt names (EXT, EXT1 & EXT2), rather than
the names now used in the data sheet for this chip (INT0 INT1 & INT2).
Makes this mistake very easy to make... |
|
|
matthewmilford
Joined: 09 Feb 2021 Posts: 23
|
Update 2 |
Posted: Thu Feb 25, 2021 10:15 am |
|
|
PCM I have corrected that issue. That still does not seem to solve the issue.
To clarify this is the new code with your correction applied.
Code: |
#include <18f26k42.H>
#include <stdio.h>
#define triac_gate PIN_B4
#PIN_SELECT INT0=PIN_B0
#use delay(clock = 4MHz)
int ZC = 0;
//******************************************************************
#INT_EXT // external interrupt ISR
void EXT_ISR()
{
//disable_interrupts(GLOBAL);
ZC = 1;
//clear_interrupt(INT_EXT);
//enable_interrupts(GLOBAL);
}
//******************************************************************
void main()
{
//ext_int_edge(H_TO_L); //catch only high to low
output_low(triac_gate);
output_drive(triac_gate);
clear_interrupt(INT_EXT); // clear external interrupt flag bit
enable_interrupts(INT_EXT); // enable external interrupt
enable_interrupts(GLOBAL); // enable global interrupts
while(TRUE)
{
if(ZC == 1)
{
ZC = 0;
delay_ms(4);
output_high(triac_gate);
delay_us(5);
output_low(triac_gate);
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 25, 2021 11:35 am |
|
|
I was able to make it work with my setup.
I used the Microchip small pin count board with a 16F690 to create a
60 Hz, 0 to 5v, squarewave signal. I jumpered ground, plus the 60
Hz signal over to the main board. Here is the 60Hz program:
Code: | #include <16F690.h>
#fuses INTRC_IO
#use delay(clock=8M)
//======================
void main(void)
{
while(TRUE)
{
output_toggle(PIN_C0);
delay_us(8333);
}
}
|
For the main board, I don't have your PIC, so I used an 18F46K22.
I then took your latest posted program and commented out two lines near
the top, as shown below. I don't need stdio.h (it clutters up the .LST file)
and 18F46K22 doesn't use #pin_select.
Anyway, it works. I sync'ed on the incoming 60 Hz signal on channel 1.
On channel 2, I can see thin positive pulse slivers occuring on the rising
edges of the ch. 1 signal. As far as I can tell, it's working just fine.
Code: |
#include <18F46K22.h>
//#include <stdio.h>
#define triac_gate PIN_B4
//#PIN_SELECT INT0=PIN_B0
#use delay(clock = 4MHz)
int ZC = 0;
//*********************************************************
#INT_EXT // external interrupt ISR
void EXT_ISR()
{
//disable_interrupts(GLOBAL);
ZC = 1;
//clear_interrupt(INT_EXT);
//enable_interrupts(GLOBAL);
}
//*********************************************************
void main()
{
//ext_int_edge(H_TO_L); //catch only high to low
output_low(triac_gate);
output_drive(triac_gate);
clear_interrupt(INT_EXT); // clear external interrupt flag bit
enable_interrupts(INT_EXT); // enable external interrupt
enable_interrupts(GLOBAL); // enable global interrupts
while(TRUE)
{
if(ZC == 1)
{
ZC = 0;
delay_ms(4);
output_high(triac_gate);
delay_us(5);
output_low(triac_gate);
}
}
}
|
|
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Thu Feb 25, 2021 12:09 pm |
|
|
Add a pin toggle before your while(TRUE) loop so you can check to see if the processor is resetting.
Maybe also do the test with the bulb disconnected to see if it is a noise reset.
Make sure you definitely have the WDT disabled so it does not reset the processor. |
|
|
|