PDA

View Full Version : 16F877A won't keep relay on 100% of the time



coyotegd
- 6th September 2007, 18:48
I have a relay with 5V on one side of the relay's coil and the collector of a darlington transistor on the other side. I have a diode reverse-biased across the coil. I am using a 16F877A with PORTB as inputs (active low) with weak pull-ups enabled. On B0 I monitor whether a 12kHz square wave is present. The square wave is a good 5V-0V. If B0 has a 12kHz signal, I make A2 high, which is connected to the base of the darlington. This allows the relay's coil to find ground through the transistor and turn on.

However, although the relay turns on with the 12kHz signal present, every second for a split second the relay turns off and then back on and so on and so on. When a put a digital probe on A2 during this on-off cycle, the pin mimics the on-off cycle of the relay with a high-low cycle.

Is the problem with my code? If not, any suggestions?

MAIN:
COUNT PORTB.0, 1, Counter
IF (Counter >= 11) AND (Counter <=13) THEN
PORTA.2 = 1
ELSE
PORTA.2 = 0
GOTO MAIN
ENDIF
. . .

Rob
- 6th September 2007, 22:20
It sounds to me like the PIC is resetting but I could be wrong. Have you got a pull-up resistor on MCLR or disabled it in your code? Is the Watch Dog Timer set to ON?

I assume the 12Khz signal is from a very reliable source?

Please ignore me if I'm way off!

Cheers

Rob

Archangel
- 6th September 2007, 23:35
Hello Coyotegd,
just for hoots try it this way:


MAIN:
COUNT PORTB.0, 1, Counter
IF (Counter >= 11) AND (Counter <=13) THEN
GOSUB ON
ELSE
GOSUB OFF
GOTO MAIN
ENDIF

ON:
PORTA.2 = 1
RETURN

OFF:
PORTA.2 = 0
RETURN

END

coyotegd
- 7th September 2007, 00:55
I was thinking that I need to test the relay circuit isolated from the rest of the PCB, but I've done that before, it works. I know I should test every circuit when components change, but they are both 5V relays with the same current requirements for the coil to trip the relay. "Murphy's Law" gets me every time.

I'll try your ideas when I feel motivated about this again.

I have a 10k0 between 5V and MCLR. I am making a CNC Mill "Monitoring PCB" between Mach3, the software controller on a PC, and stepper-motor driver hardware, and I assume software. I've oscilloscope-tested the 12kHz signal, which according to Mach3 is suppose to be 12.5kHz, and it is a good 0V to 5V square wave. The PC DB25 signal is stepped up from 3V by a three-state octal bus transceiver.

Anyway, I'll let you know if your suggestions help.

coyotegd
- 7th September 2007, 01:04
I have this assembler code at the start of my program:

@ DEVICE HS_OSC, WDT_OFF, LVP_OFF, BOD_OFF, PWRT_ON, PROTECT_OFF

The "HS_OSC" is my change because I have a 20Mhz xtal, and yes, I have "OSC 20" in my "PIC Basic" code. The other line items are "Boiler Plate" I've found looking around the Forum. I'm quite certain the "WDT_OFF" turns the Timer off.

Rob
- 7th September 2007, 08:03
I have this assembler code at the start of my program:

@ DEVICE HS_OSC, WDT_OFF, LVP_OFF, BOD_OFF, PWRT_ON, PROTECT_OFF

I'm quite certain the "WDT_OFF" turns the Timer off.

Yeah that's right, it does turn the tmier off.



The "HS_OSC" is my change because I have a 20Mhz xtal, and yes, I have "OSC 20" in my "PIC Basic" code.

It still sounds to me like the PIC is resetting or some other code elsewhere in your program is causing the output to go low on the pin you are using. Just for arguments sake, create a new program with just this code and try it out.



The other line items are "Boiler Plate" I've found looking around the Forum.

I've never heard the term "boiler plate" before so I'm not quite sure what you mean?

Cheers

Rob

peterdeco1
- 7th September 2007, 11:30
Try removing the relay and use an LED with a resistor. If the LED works, your code is OK and the relay coil is the culprit. I've had interference problems with small vibrating motors located very close to the PIC.

Acetronics2
- 7th September 2007, 12:39
Hi, Coyote

1) Did you try to use HIGH Portx.y ...

I noticed many times it is much more reliable than Portx.y = 1 in disturbed circuits ...

2) @ 20 Mhz, you also could try PULSIN instead of count ( as it is a square wave )... nominal result will be 20 ... and there will be a little less "rollover" issues ...

3) The ideal way would be to use the "capture" feature of the CCP modules ... in a '877 there are two modules !! ...

Darrel's instant interrupts are ... the easy way ... to make that. And it takes much, much, much less CPU time ...

Alain

Rob
- 7th September 2007, 12:47
Hi, Coyote

1) Did you try to use HIGH Portx.y ...

I noticed many times it is much more reliable than Portx.y = 1 in disturbed circuits ...



That's interesting! I learn something new every day! Nice one!

Cheers

Rob

coyotegd
- 7th September 2007, 18:40
"Boiler Plate" is a term attorneys use when drafting wrtten legal documents. It's the language included based on prior experience with similar documents. Although the exact purpose would have to be researched, it's included based on long-standing practice. I read a thread and picked up this "assembler" based on what I read about it, and I include it in all my programs.

The follow code executing all by itself (that is, all other code except initialization, commented out) had the same result:

MAIN:
Count PORTB.0, 1, Counter
if (Counter >= 11) and (Counter <= 13) then
gosub TurnOn
else
gosub TurnOff
goto main
endif
'gosub CK_PORTB
'gosub CK_PORTE
goto main
end

'----------

TurnOn:
high PORTA.2
RETURN
TurnOff:
LOW PORTA.2
RETURN

The relay is operating properly. The output of the 877 and darlington was tested with a breadboard and LEDS. I suspect the problem did not show itself at the time because the LEDs were switching so fast I couldn't see the "off". The relay is extremely slow compared to an LED, so now the problem presents itself. The thing is, I'm certain I tested it with the relay too.

No vibrations occur on this PCB.

I am now researching the use of PULSIN and the "capture" feature of a CCP module with "Darrel's instant interrupts".

Archangel
- 7th September 2007, 19:12
Hi coyotegd,
by boilerplate I assume you refer to code that you reuse over and over like TRIS and Config fuse settings, that can be dicey in programming PICs as so many have their own quirks. You might think good thoughts about posting that boiler plate code so as we can smoke it over. You know, I think I would try your code on a port B pin, as Port A has lots of confusing analog stuff to contend with, the process of elimination.
JS

coyotegd
- 7th September 2007, 19:23
Here is the entire program I am working with just to get the relay to operate properly:

@ DEVICE HS_OSC, WDT_OFF, LVP_OFF, BOD_OFF, PWRT_ON, PROTECT_OFF

Define OSC 20

ADCON1 = 7 ' Digital I/O for Registers A & E
TRISA = 0 ' PORTA as outputs
PORTA = 0 ' PORTA pins low
TRISB = 255 ' PORTB as inputs from Mach3
PORTB = 255 ' PORTB pins high for active low
OPTION_REG.7 = 0 ' Enable PORTB pull-up resistors
TRISC = 0 ' PORTC as outputs
PORTC = 0 ' PORTC pins low for active high
TRISD = 0 ' PORTD as outputs
PORTD = 0 ' PORTD pins low for active high
TRISE = 7 ' PORTE as inputs from machine for x, y, z travel limits
PORTE = 7 ' PORTE pins high for active low

ChrgPmp var PORTB.0 ' Input for Mach3 charge pump
CntCP var byte ' Count check for 12kHz on PORTB.0
Estop var PORTA.0 ' Send Emergency stop to Mach3
LPTports var PORTA.1 ' Enable parallel ports
Aux var PORTA.2 ' Auxilary power
Coolant var PORTA.3 ' Coolant power
Spindle var PORTA.4 ' Spindle power
SpinDir var PORTA.5 ' Spindle direction
XLED VAR PORTD.0
YLED VAR PORTD.1
ZLED VAR PORTD.2
X var byte ' Counter for pin cycling

'----------

MAIN:
count chrgpmp, 1, cntcp ' Count freq. on B0, Mach3's 12kHz
if (cntcp >= 11) and (cntcp <= 13) then ' Freq. must be between 11 & 13kHz
lptports = 1
else
LPTports = 0
goto main
endif
'gosub CK_PORTB
'gosub CK_PORTE
goto main
end

mackrackit
- 7th September 2007, 20:11
Are you on the correct pin. At the beginning you said you were using PORTA.2.
Code shows PORTA.1?

What about CMCON = 7

coyotegd
- 7th September 2007, 20:56
You are right, but A2 is correct. When I first posted, I change my code for clarity. I probably should have used the exact same code all the way through. When I said A1 earlier, it should have been A2. Good find. Thanks for looking.

I think everyone should STOP TRYING TO FIGURE THIS OUT. I tested the programmed PIC with a breadboarded darlington and relay and it works like a champ. No split-second low on A2 approximately every second during a proper A2 high when B0 frequency is between 11 and 13kHz.

I must have a conflict in my power supply or other PIC peripheral connections. I'm sure I'll find the answer when I look very closely at my schematic.

Thanks everyone.

coyotegd
- 7th September 2007, 21:11
When I use a 12kHz TTL signal from my Function Generator, the relay works fine. However, when I use the 12kHz signal from Mach3, I get the spastic relay. I scoped the Mach3 signal after passing through the transceiver, it appeared to be a good 12kHz 5V to 0V signal.

I am going to run the Function Generator signal through the parallel port as if it's Mach3's, and thereby through the tri-state transceiver. I'm narrowing it down and will find it.

Thanks for letting me vent.

coyotegd
- 7th September 2007, 21:53
Function Generator 12.1kHz TTL 3V signal directly on B0 and the relay works great. Ditto when the Generator's signal is run through PC parallel port input and tri-state transceiver to boost to 5V square wave.

Mach3 PC software transmitting 3V TTL through parallel printer port. Signal placed directly on B0, spastic relay. Ditto when the signal is passed through the tri-state transceiver.

Both signals look exactly the same on an oscilloscope. Both signals find the same ground as the PIC, relay, transceiver, parrallel port and power supply.

I even took the signal directly from the parallel port attached to the PC in case the cable was defective.

Arghhhhh.....

BTW, I believe "CMCON = 7" would be a moot entry. "ADCON1 = 7" makes ports A and E digital I/O rather than analog.

mackrackit
- 7th September 2007, 22:39
BTW, I believe "CMCON = 7" would be a moot entry. "ADCON1 = 7" makes ports A and E digital I/O rather than analog.
You may want to read this. It explains ADCON and CMCON.
http://www.picbasic.co.uk/forum/showthread.php?t=561

coyotegd
- 7th September 2007, 23:41
I'll remember that and keep "CMCON = 7" with "ADCON1 = 7" when switching from analog to digital I/O. However, this did not solve my problem either.

I now know that it's the 12kHz from Mach3. Although I can't see it on the oscilloscope, the signal has a hiccup. I can hear it on my digital probe, and the probe's ever so slightly audible hiccup matches the relay's. Even the hi-low lights dim very slightly now and then.

So off to Mach3 support for information on how to obtain a clean 12kHz from their software.

As soon as their signal measured at 12 to 12.1kHz when they stated it would be 12.5kHz, I should have looked more closely at the signal.

coyotegd
- 8th September 2007, 00:54
With a terrible hiccup in the 12kHz signal, I have to test the the frequency with:

If (Counter > 1) then

So as long as the PIC counts anything over a 1kHz, the relay works properly. What a crappy 12kHz signal from Mach3. I hope this doesn't reflect the quality of their stepper motor control. I guess I'll find out.

Hopefully, they the explanation is that they had to compromise the 12kHz signal for better control over the stepper motor signals.

Rob
- 9th September 2007, 13:12
With a terrible hiccup in the 12kHz signal, I have to test the the frequency with:

If (Counter > 1) then

So as long as the PIC counts anything over a 1kHz, the relay works properly. What a crappy 12kHz signal from Mach3. I hope this doesn't reflect the quality of their stepper motor control. I guess I'll find out.

Hopefully, they the explanation is that they had to compromise the 12kHz signal for better control over the stepper motor signals.

I'm not familiar with the Mach3 product but it sounds like it needs to be corrected as it's not offering a correct output. If you need to use it you could always try this in your code:




working var byte
working = 2

MAIN:
count chrgpmp, 1, cntcp ' Count freq. on B0, Mach3's 12kHz
if (cntcp >= 11) and (cntcp <= 13) then ' Freq. must be between 11 & 13kHz
working = 2
else
if working > 0 then ' Stops working variable from rolling from 0 to 255!
working = working - 1
endif
endif
if working >0 then
lptports = 1
else
lptports = 0
endif

goto main



This will make a double check every time there is a 'hiccup' in the 12kHz signal. Of course if this doesn't correct it you could always increase the "working" variable where it is defined and also in the third line of the above code.

Hope this helps

Rob

BrianT
- 10th September 2007, 11:24
From the symptoms described, I would be looking (with a scope) at the power supply. If the 5V relay draws slightly more current than the power supply can sustain then I would expect BrownOut Resets some short time after the relay energises.

Just a thought.

Brian