PIC programming - Driving a dual coil relay using a latching switch as an input

Thread Starter

bluenote9

Joined Sep 9, 2020
2
Hello there!
First of all I want to state that I am an absolute beginner in programming.
I am quite experienced in electronics (audio mostly) though, but I never dipped my toes in programming since recently...

So, I am trying to implement a PIC microcontroller (PIC 16F676) in one of my designs. Its use will be to drive some relays by taking digital information by a few switches.
I have already programmed a working code with the XC8 compiler for a couple of non-latching relays that are in my design... But there is a dual coil latching relay also in the circuit, and here is the problem.

This latching relay must be controlled by a SPST ON-OFF switch (Latching... NOT momentary).
I have tried triggering a pulse out of the microcontroller when it reads high or low from the switch but with no good results.

My main problem (I think...) is that since I there is a latching switch, the pulse for the latching relay must be sent only when the PIC sees a change at its input pin... and do this just once, somehow... ( I mean not doing it repeatedly while it sees the desired input since there is a latching switch in the input). Of course since it is a dual coil relay there will be two outputs from the PIC to drive the two coils (with a 5V pulse using transistors)...

I am posting this because I honestly don't know where to start addressing my problem, so any help will be appreciated, even to give me a general approach I should be taking.

P.S. (I am not sure if this thread should be here or in the micro-controllers section forum... lets move it if it is more relevant there)
 

MaxHeadRoom

Joined Jul 18, 2013
21,426
On-edge interrupt, See App note AN566.
Also P22 of the pic manual
You may also need debounce detection on the input, either external discrete components or internally.
Max.
 
Last edited:

geekoftheweek

Joined Oct 6, 2013
528
What if you set up an interrupt on change for the desired pin for the switch. The first time the change is detected, make the appropriate change in your output and start a timer. Use the timer to keep the output on and to also ignore the extra interrupts from the switch contacts bouncing. Once the timer expires turn off your output and you'll be ready for the next change.
 

peterdeco

Joined Oct 8, 2019
222
This sounds like something we do at work. The code is in basic which is easy to translate to your source code. Hope it helps.
We'll use porta.0 as input and portb.0 as output. Porta.0 has a pull up with switch to negative ground.

x var bit 'create a bit variable
let x = porta.0 'x will be 0 or 1
pause 50 '50ms debounce
if porta.0 <> x then high portb.0 : pause 500 : low portb.0 'any change on the input not equal to x will cause portb.0 to go high for 1/2 second
 

Thread Starter

bluenote9

Joined Sep 9, 2020
2
Thanks everyone for your replies!

What if you set up an interrupt on change for the desired pin for the switch. The first time the change is detected, make the appropriate change in your output and start a timer. Use the timer to keep the output on and to also ignore the extra interrupts from the switch contacts bouncing. Once the timer expires turn off your output and you'll be ready for the next change.
I have already started reading about interrupt on change like Max also suggested and it seems that I am am on the right track for what I want to do... but I have a question:

the way I understand it so far is that the "interrupt on change" will help me to overcome the problem of using a latching switch as an input so the code will not run forever ... but... It is essential for my design that when the device loses power and comes back on, to take account the state of the switch, so it will trigger the correct coil (each of the two positions of the switch will have to trigger each of the two coils of the relay)... will this be possible with the "interrupt on change"?

I will read more about it of course and I am already thinking about possible changes in my design if it cannot work the way I need it...
 

peterdeco

Joined Oct 8, 2019
222
I do nothing with interrupts but the PIC's we use have eeprom. If the user of the device - or interruption of power occurs, we add read and write commands for eeprom. Such as:
let x = porta.0
write 0,x 'write value of x in eeprom location 0

upon power up the first line ahead of the others would be something like:
read 0,x 'read value and put back in variable x
 

MaxHeadRoom

Joined Jul 18, 2013
21,426
If you mean detect the switch at power up after a loss of power, of course you would not have an interrupt at that point, but the program will reset to the start, so during the pgm initiation section, do a read of the input and set or reset the output for the relay based on this input status..
From then on, the interrupt routine will take over,,
Something like @peterdeco meant.?
This as I understand your meaning.
Max.
 
Another possibility instead of the interrupt on change idea...

On startup setup a bit in memory to use to store the current switch state and set it opposite of the current state.
Setup a timer for say 200 milliseconds.
Every time the timer times out...
Turn off any outputs that were on from last time
Read the switch and compare with the stored state.
If the states are different store the new state and turn on the appropriate output
The next time the timer times out it will turn off the output

200 milliseconds isn't noticeable, it should take care of the switch bouncing, and unless I'm wrong it should be long enough for the relay to latch (I've never played with them yet).

Even better yet would be use something like 10 milliseconds and a couple bytes to act as counters. One to count the switch and one to count when to turn off the output. The switch one you could reset to 0 every time the switch states match, and count every time they are different. Once you count to 20 the switch has been in the same state for 200 milliseconds and it's time to change. The times aren't exact... you will have to experiment to find what works for you.

As you learn more programming you'll find different ways to go about pretty much everything. Some ways work better than others at times, and sometimes it just depends on how you feel at the moment. Good luck!
 

MaxHeadRoom

Joined Jul 18, 2013
21,426
I tend to use simple R/C de-bounce, often a pull up is required on an input so all that is needed to add is usually 1res + 1 cap.
Max.
 
Top