PIC12F675 INTERRUPT WITH COMPARATOR OUTPUT CHANGING doesn't work

61 views
Skip to first unread message

Michel MORICE

unread,
Jul 27, 2020, 10:00:14 AM7/27/20
to jallib
Hi
On a PIC12F675 I use A0 and A1 as analogic input to control the light of the day to open/close a door 
A2 as logic output with a led to control the right operating.
An interrupt on A2 changing should start the process but that doesn't work.
Hereafter a little program to try the function.
Thanks for helping me.

--************************************************************************
--****** Programme POULE2  -Ouverture crépusculaire du poulailler ********
--***************************************Michel MORICE 16 juillet 2020****
include 12f675
pragma target clock 4_000_000
pragma target OSC INTOSC_NOCLKOUT  -- horloge interne à 4 MHz
pragma target MCLR internal        -- make MCLR pin A3 available as I/O
pragma target WDT disabled
--conditionnement du PIC
ANSEL  = 0b_0000_0011  --ports 0 et 1 en analogique, entrées du comparateur
TRISIO = 0b_0000_1011  --ports 0, 1, 3 en input, 2, 4 et 5 en output
CMCON  = 0b_0000_0001  --comparateur + en 0, - en 1, sortie en 2
PIE1   = 0b_0000_1000  --comparateur enable bit
INTCON = 0b_1100_0000  --global interrupt et peripheral interrupt
--paramétrage des portes
alias COMPS is pin_A2   --sortie du comparateur
alias ILS is pin_A3     --ILS contrôlant la fermeture de porte
alias OUVRE is pin_A4   --commande l'ouverture
alias FERME is pin_A5   --commande la fermeture
--paramétrage général
--ON OFF TRUE FALSE définis par include 12f675 et constants_jallib
const dword seconde = 1_000_000
const bit OUVERTE = ON
const bit FERMEE  = OFF
var bit changeLum = FALSE
--***************************************************************
--****************************************************************
procedure changeLuminosite() is pragma INTERRUPT
  if PIR1_CMIF then     --changement de luminosité détecté
    changeLum = TRUE
  end if
end procedure
--****************************************************************
--programme principal
forever loop
  if changeLum then
    PIR1_CMIF = OFF
    INTCON_GIE = OFF
    OUVRE = ON
    _usec_delay(seconde * 3)
    OUVRE = OFF
  end if
  INTCON_GIE = ON
  changeLum = FALSE
end loop



Rob CJ

unread,
Jul 27, 2020, 3:38:09 PM7/27/20
to jal...@googlegroups.com
Hello Michel,

If you want to use the external interrupt you have to enable it by: INTCON_INTE = TRUE      

Initially it is disabled by default.

Kind regard,

Rob


Van: jal...@googlegroups.com <jal...@googlegroups.com> namens Michel MORICE <morm...@gmail.com>
Verzonden: maandag 27 juli 2020 12:06
Aan: jallib <jal...@googlegroups.com>
Onderwerp: [jallib] PIC12F675 INTERRUPT WITH COMPARATOR OUTPUT CHANGING doesn't work
 
--
You received this message because you are subscribed to the Google Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jallib+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jallib/cdf66d12-1e34-4563-9d26-345617726af0o%40googlegroups.com.

Rob CJ

unread,
Jul 27, 2020, 3:42:44 PM7/27/20
to jal...@googlegroups.com
Hi Michel,

Maybe I was too quick. You mentioned that you have connected something to A2 so I assume you use the external interrupt.

Next to that you are using a comparator which is a peripheral device.

This means that you also have to enable interrupts from peripheral devices by enabling those interrupts with: INTCON_PEIE = TRUE 

Kind regards,

Rob


Van: Rob CJ <rob...@hotmail.com>
Verzonden: maandag 27 juli 2020 21:38
Aan: jal...@googlegroups.com <jal...@googlegroups.com>
Onderwerp: Re: [jallib] PIC12F675 INTERRUPT WITH COMPARATOR OUTPUT CHANGING doesn't work
 

Michel MORICE

unread,
Jul 28, 2020, 1:06:38 PM7/28/20
to jal...@googlegroups.com
Hi Rob,
Thank you for trying to help me.
Yes it's necessary to enabling INTCON_PEIE. It is what I did with INTCON = 0b_1100_0000.
The mystery is elsewhere

Garanti sans virus. www.avast.com


Garanti sans virus. www.avast.com

Rob CJ

unread,
Jul 28, 2020, 1:10:44 PM7/28/20
to jal...@googlegroups.com
Hi Michel,

Sorry missed that one. Then your problem may be the following.

I do not see that you service the external interrupt. This will result in the PIC being continuous in the interrupt routine since the INTF flag remains set.

It then appears as if the PIC hangs (believe me I have also run into this issue).

So you have to least service the external interrupt otherwise it will not work.

Kind regards,

Rob


Verzonden: dinsdag 28 juli 2020 17:57

Rob CJ

unread,
Jul 28, 2020, 1:51:59 PM7/28/20
to jal...@googlegroups.com
Hi Michel,

Sorry for the spam but I saw that you did not enable the external interrupt in INTCON0. I was confused because you mentioned "An interrupt on A2 changing should start the process but that doesn't work."

But the statement about hanging in the interrupt routine still stands.

You have to change the code in your interrupt routine into the following:

procedure changeLuminosite() is pragma INTERRUPT
  if PIR1_CMIF then     --changement de luminosité détecté
     PIR1_CMIF = FALSE
    changeLum = TRUE
  end if
end procedure

Otherwise the PIC will re-enter the interrupt routine as soon as it has left it.

Kind regards,

Rob




Van: jal...@googlegroups.com <jal...@googlegroups.com> namens Rob CJ <rob...@hotmail.com>
Verzonden: dinsdag 28 juli 2020 19:10

Michel MORICE

unread,
Aug 1, 2020, 8:08:17 AM8/1/20
to jal...@googlegroups.com
Hi Rob,

Sorry for not answering sooner, I was enjoying the sun for a few days. 

Thank you for this solution, it's perfect. The problem was actually there and is fixed now.
I'ill finally be able to continue my project.

Best regards

Michel

Garanti sans virus. www.avast.com

Michel MORICE

unread,
Aug 2, 2020, 1:27:39 PM8/2/20
to jal...@googlegroups.com
Hi Rob,

As I continued my project, I discovered a new problem for me.
Here after the initial draft:
--************************************************************************
--****** Programme POULE3  -Ouverture crépusculaire du poulailler ********

--***************************************Michel MORICE 16 juillet 2020****
include 12f675
pragma target clock 4_000_000
pragma target OSC INTOSC_NOCLKOUT  -- horloge interne à 4 MHz
pragma target MCLR internal        -- make MCLR pin available I/O

--conditionnement du PIC
ANSEL = 0b_0000_0011   --ports 0 et 1 en analogique, entrées du comparateur
TRISIO = 0b_0000_1011  --ports 0, 1, 3 en input, 2, 4 et 5 en output
CMCON = 0b_0000_0001   --comparateur + en 0, - en 1, sortie en 2
PIE1_CMIE = ON         --Comparator changing Interrupt ON
INTCON_PEIE = ON       --Peripheral Interrupt On
INTCON_GIE = ON        --Global Interrupt On

--paramétrage des portes
alias COMPS is pin_A2   --sortie du comparateur
alias ILS is pin_A3     --ILS contrôlant la fermeture de porte
alias OUVRE is pin_A4   --commande l'ouverture
alias FERME is pin_A5   --commande la fermeture
--paramétrage général
--ON OFF TRUE FALSE définis par include 12f675 et constants_jallib
const dword seconde = 1_000_000
const bit OUVERTE = ON
const bit FERMEE = OFF
var bit changeLum = FALSE
OUVRE = OFF
FERME = OFF

--****************************************************************
procedure changeLuminosite() is  pragma INTERRUPT
  if PIR1_CMIF == ON then     --changement de luminosité détecté
    PIR1_CMIF = OFF              --reset du flag de détection
    INTCON_GIE = OFF           --Stop global interrupt
    changeLum = TRUE           --flag de détection de changement activé
  end if
end procedure
--***************************************************************
procedure ouverturePorte() is
    OUVRE = ON               --on ouvre la porte - moteur ON+
    _usec_delay(seconde * 3) --pendant 3 secondes
    OUVRE = OFF              --arrêt du moteur
end procedure
--***************************************************************
procedure fermeturePorte() is
  FERME = ON                 --on ferme la porte - moteur ON-
  while ILS == OUVERTE loop  --tant que la porte n'est pas fermée
  end loop
  FERME = OFF                --arrêt moteur
end procedure
--****************************************************************
--***********programme principal******************************
forever loop
  while !changeLum loop
  end loop
  if COMPS == ON  then     --passe au jour
    ouverturePorte()
  else                                   --passe à la nuit
    fermeturePorte()
  end if
  changeLum = FALSE
  INTCON_GIE = ON
end loop
--*********************************************************************

That doesn'nt work and I found this solution (in blue):

--************************************************************************
--****** Programme POULE5  -Ouverture crépusculaire du poulailler ********
--***************************************Michel MORICE 2 août 2020****

include 12f675
pragma target clock 4_000_000
pragma target OSC INTOSC_NOCLKOUT  -- horloge interne à 4 MHz
pragma target MCLR internal        -- make MCLR pin A3 available as I/O
pragma target WDT disabled
--conditionnement du PIC
ANSEL  = 0b_0000_0011  --ports 0 et 1 en analogique, entrées du comparateur
TRISIO = 0b_0000_1011  --ports 0, 1, 3 en input, 2, 4 et 5 en output
CMCON  = 0b_0000_0001  --comparateur + en 0, - en 1, sortie en 2
PIE1   = 0b_0000_1000  --comparateur enable bit
INTCON = 0b_1100_0000  --global interrupt et peripheral interrupt
--paramétrage des portes
alias ILS is pin_A3     --ILS contrôlant la fermeture de porte
alias OUVRE is pin_A4   --commande l'ouverture
alias FERME is pin_A5   --commande la fermeture
--paramétrage général
--ON OFF TRUE FALSE définis par include 12f675 et constants_jallib
const dword seconde = 1_000_000
const bit OUVERTE = TRUE
const bit FERMEE  = FALSE
var bit lumChange = FALSE --flag de changement de luminosité
var bit etatCout           --etat de la sortie du comparateur
OUVRE = OFF
FERME = OFF

--****************************************************************
procedure changeLuminosite() is pragma INTERRUPT
  if PIR1_CMIF then     --changement de luminosité détecté
    PIR1_CMIF = OFF        --reset du flag détecté
    INTCON_GIE = OFF       --stop interrupts
    etatCout = CMCON_COUT  --mise en mémoire de la sortie
    lumChange = TRUE       --flag de changement de luminosité
  end if
end procedure

--***************************************************************
procedure ouverturePorte() is
  OUVRE = ON              --on ouvre la porte - moteur ON+
  _usec_delay(seconde * 3) --pendant 3 secondes
  OUVRE = OFF             --arrêt du moteur
end procedure
--***************************************************************
procedure fermeturePorte() is
  FERME = ON                   --on ferme la porte - moteur ON-
  while ILS == OUVERTE loop    --tant que la porte n'est pas fermée
  end loop
  FERME = OFF                --arrêt moteur
end procedure
--********************************************************************
--*************programme principal********************************
forever loop
  while !lumChange loop  --tant qu'il n'y a pas de changement
  end loop                       --on boucle
  _usec_delay(seconde)
  if etatCout == HIGH  then      --si c'est de nuit à jour
    ouverturePorte()
  else                           --si c'est de jour à nuit
    fermeturePorte()
  end if
  lumChange = FALSE              --reset du flag de changement
  INTCON_GIE = ON                --remise en attente des interrupts
  asm sleep                               --mise en sommeil
end loop
--*************************************************************************

I don't no exactly the reason, perhaps a timing problem again.
Now  tutto va bene , grazie mille
Thank you again. Merci beaucoup

Michel

Garanti sans virus. www.avast.com

Rob CJ

unread,
Aug 2, 2020, 2:13:06 PM8/2/20
to jal...@googlegroups.com
Hi Michel,

Your solution is correct. You have to read the value of the comparator as soon you get an interrupt so you capture the value in the interrupt routine itself. In your second program you could remove the _usec_delay in the forever loop since it will only delay the opening or closing (unless you want that of course).

Note that your input signal on the comparator must have a minimal length as for the PIC to be able to read the correct level. If for example the pulse would be very short, you could get the interrupt but the signal could already be changed before you read the pin. Of course I am talking here about a signal in the microsecond range. Since in your first program you missed this signal, I suspect it to be short. 

Kind regards,

Rob


Verzonden: zondag 2 augustus 2020 19:20

Michel MORICE

unread,
Sep 2, 2020, 5:45:15 AM9/2/20
to jal...@googlegroups.com
Hi Rob,
I come back to you because I have always some problems with my project.
Let me remind you this project:
a LDR controls the light of the day. As soon as the level is under a threshold, a motor closes a door up to an ILS is detected.
When level goes beyond this threshold, the motor opens the door until an other ILS is detected.
I use a PIC12F675 to control the system.
The system, sometimes, doesn't run correctly: stops before the ILS, starts and goes back, or other quirks.
Can you have a look to my program if you find a mistake.
I also send you the circuit scheme.

Kind regards
Michel

Garanti sans virus. www.avast.com

Poule5.jal
Poule.pdf

Oliver Seitz

unread,
Sep 2, 2020, 7:10:36 AM9/2/20
to jal...@googlegroups.com
Salut Michel,

I have not read every line of your program, but it seems like you don't have any hysteresis. Slowly changing values on a comparator without hysteresis *will* lead to erratic behaviour while the voltage is near the threshold. 

This is not easy to handle, especially if you're tying an interrupt to the comparator output.

I would do it differently. I'd use the ADC, saying it is "light" when the reading is above 60%, and "dark" when the reading is below 40% or so. If the reading is between the numbers, I wouldn't do anything.

Then I would only really start anything if the reading stays on "light" or "dark" for more than a minute or two, so that not every cloud would start the motor.

Bonne chance!

Kiste

Am Mittwoch, 2. September 2020, 11:45:15 MESZ hat Michel MORICE <morm...@gmail.com> Folgendes geschrieben:


Rob CJ

unread,
Sep 2, 2020, 12:39:25 PM9/2/20
to jal...@googlegroups.com
Hi Michel,

Kiste is right and the solution provided with the ADC would also be my suggestion. It wil even safe you some components since you do no longer need R4 and R5.

Kind regards,

Rob


Van: 'Oliver Seitz' via jallib <jal...@googlegroups.com>
Verzonden: woensdag 2 september 2020 13:07

Michel MORICE

unread,
Sep 3, 2020, 3:14:43 AM9/3/20
to jal...@googlegroups.com
Hi Kiste and Rob
Thanks you for your answers.
As I stopped the interrupts at the first detection, I believed I could do quietly the job after. I half understand this problem of hysteresis but your solution is certainly better.
I'm gonna adopt this way; it's a pity because i liked the principle of interrupts.

Kind regards
Michel

Garanti sans virus. www.avast.com

Rob CJ

unread,
Sep 3, 2020, 3:25:41 AM9/3/20
to jal...@googlegroups.com
Hi Michel,

You can still use the ADC interrupt in your new version 😊.

Met vriendelijke groet,
Rob Jansen

From: jal...@googlegroups.com <jal...@googlegroups.com> on behalf of Michel MORICE <morm...@gmail.com>
Sent: Thursday, September 3, 2020 9:06:52 AM
To: jal...@googlegroups.com <jal...@googlegroups.com>
Subject: Re: [jallib] PIC12F675 INTERRUPT WITH COMPARATOR OUTPUT CHANGING doesn't work
 
Reply all
Reply to author
Forward
0 new messages