0
\$\begingroup\$

I'm having a problem with this circuit, it's my first time using the A/D converter.

The circuit turns on a relay when the battery connected to the A/D input reaches a voltage. The supply for this circuit is 220 VAC, then a 10 V transformer, rectified and filtered, and then a 7805.

If I plug the 220 V connector in first, it functions perfectly, it does everything. The problem is when I connect the battery first, because this is like feeding my circuit, and the PIC turns on. I measured the VCC and GND pin from the PIC and it has the same voltage as the voltage divider coming from the battery.

So my problem is that I can't plug in the battery first (the battery voltage goes through a voltage divider, so the maximum and minimum voltage of the battery is from 1 to 5 V).

Another thing, if anyone has an idea: if I connect a larger voltage battery, the input of the PIC probably burns, so, what circuit for a voltage "cropper" can I use?

The clamp circuit:

enter image description here

enter image description here

enter image description here

Here's the code, but I don't think that it has anything to do with my problem.

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)

#define _XTAL_FREQ 4000000
#define standby 1
#define detectar 2
#define carga 3
#define cargatemporizada 4
#define ecualizacion 5
#define fincarga 6
#define stop 7

/* Para realizar conversion:
 *      ADCON0bits.GO_DONE=1; ARRANCA CONVERSION
 *      while (ADCON0bits.GO_DONE == 1 ) {} ESPERA A QUE SE REALICE LA CONVERSION
 *      int bits_low= ADRESL; se guardan los resultados
 *      int bits_high= ADRESH;  se guardan los resultados
 *      int res=(ADRESH<<8)+ADRESL;
 */

/*  tiempo de clock: 0,065025
        1 Segundo=15 ciclos de clock
        30 segundos=461 ciclos de clock
        1 minuto = 900 ciclos de clock
        1 hora = 54000 ciclos de clock
        3 horas = 162000 ciclos de clock
        200 segundos= 3075 ciclos de clock
        200 segundos= 3075 ciclos de clock
 */

//SALIDAS
#define RELE RC5
#define ledlin RC4
#define ledbat RC3
#define ledcar RC2
#define ledfin RC1
#define ledecu RC0
//SALIDAS

//ENTRADAS
#define STOP RA5 
#define ECUA RA4
#define DATOS RA2 
//ENTRADAS

#include <xc.h>

void main(void) 
{
    OPTION_REG=0b10000111;    
    INTCON=0b00000000;  
    //OSCCON=NOUSE IRCF2 IRCF1 IRCF0 OSTS(1) HTS LTS SCS; para modificar CLOCK, POR DEFECTO=4MHZ
    TRISA=0b00110100;
    TRISC=0b00000000;
    CMCON0 = 7;
    PCON=0b00000000;
    WPUA=0b00000000;
    ANSEL=0b00000100;
    ADCON0=0b10001000;
    ADCON1=0b01110000;
    ADCON0bits.ADON=1;
    ledlin=0;
    ledbat=0;
    ledcar=0;
    ledfin=0;
    ledecu=0;
    RELE=0;
    int res=0, temporizador=0, tempmaximo=0, temporizadorb=0, bateriamin=561, bateriamax=940, bateriamed=836, bits_low=0, bits_high=0;
    unsigned char estado=1, estado_anterior=0, estadocambio=0, a=0,b=0, c=0;
    while (1)
    {
        if (T0IF == 1)
        {
            T0IF = 0;
            TMR0 = 0;
            if (temporizador > 0)
            {
                temporizador--;
            }
            if (tempmaximo > 0)
            {
                tempmaximo--;
            }  
            if (temporizadorb > 0)
            {
                temporizadorb--;
            }  
        }
        
        if (estado != estado_anterior)
        {
            estado_anterior = estado;
            estadocambio = 1;
        }
        else if (estado == estado_anterior) estadocambio = 0;
 
        if (estado == standby)
        {
            if (estadocambio == 1)
            {
                __delay_ms(1500);
                ledlin = 1;
                __delay_ms(500);
                ledlin = 0;
                ledbat = 1;
                __delay_ms(500);
                ledbat = 0;
                ledcar = 1;
                __delay_ms(500);
                ledcar = 0;
                ledfin = 1;
                __delay_ms(500);
                ledfin = 0;
                ledecu = 1;
                __delay_ms(500);
                ledecu = 0;
                ledfin = 1;
                __delay_ms(500);
                ledfin = 0;
                ledcar = 1;
                __delay_ms(500);
                ledcar = 0;
                ledbat = 1;
                __delay_ms(500);
                ledbat = 0;
                ledlin = 1;
                __delay_ms(500);
                ledlin = 0;
                __delay_ms(1500);
                ledlin = 1;
                ledbat = 1;
                ledcar = 1;
                ledfin = 1;
                ledecu = 1;
                __delay_ms(1000);
                ledlin = 0;
                ledbat = 0;
                ledcar = 0;
                ledfin = 0;
                ledecu = 0;
                __delay_ms(1000);
                ledlin = 1;
                ledbat = 1;
                ledcar = 1;
                ledfin = 1;
                ledecu = 1; 
                __delay_ms(1000);
                ledbat = 0;
                ledcar = 0;
                ledfin = 0;
                ledecu = 0;
                temporizador = 60;
            }
            if (temporizador == 0)
            {
                ADCON0bits.GO_DONEb = 1;
                while (ADCON0bits.GO_DONE == 1) {} 
                int bits_low = ADRESL; 
                int bits_high = ADRESH;
                int res = (ADRESH<<8) + ADRESL;
                if ((res > bateriamin) && (res < bateriamax) && (a == 0))
                {
                    ledbat = 1;
                    temporizadorb = 60;
                    a = 1;
                }
                if ((temporizadorb == 0) && (a == 1))
                {
                    estado = carga;
                    a = 0;
                }
            }   
        }
        else if (estado == carga)
        {
            if (estadocambio == 1)
            {
                ledcar = 1;
                RELE = 1;
                tempmaximo = 540000;
            }
            
            ADCON0bits.GO_DONE = 1;
            while (ADCON0bits.GO_DONE == 1) {} 
            int bits_low = ADRESL; 
            int bits_high = ADRESH;
            int res=(ADRESH<<8) + ADRESL;
            
            if ((STOP == 1) || (tempmaximo == 0) || (res > bateriamax))
            {
                estado = stop;
            }
            if ((res > bateriamed) && (res < bateriamax))
            {
                estado = cargatemporizada;
            }
            if (ECUA == 1)
            {
                ledecu = 1;
                a = 1;
            }
        }
        
        else if (estado == cargatemporizada)
        {
            if (estadocambio == 1)
            {
                temporizador = 16200;
            }
            if ((temporizadorb == 0) && (ledcar == 1))
            {
                ledcar = 0;
                temporizadorb = 15;
            }
            if ((temporizadorb == 0) && (ledcar == 0))
            {
                ledcar = 1;
                temporizadorb = 15;
            }
            
            ADCON0bits.GO_DONE = 1;
            while (ADCON0bits.GO_DONE == 1) {} 
            int bits_low = ADRESL; 
            int bits_high = ADRESH;
            int res=(ADRESH<<8) + ADRESL;
            
            if ((STOP == 1) || (tempmaximo == 0) || (res > bateriamax))
            {
                estado = stop;
            }
            
            if (temporizador == 0)
            {
                estado = fincarga;
            }
            
            if (((ECUA == 1) || (a == 1)) && (b == 0))
            {
                b = 1;
                ledecu = 1; 
                temporizador = temporizador + 162000; // 3 horas mas
            }
        }
        else if (estado == fincarga)
        {
            if (estadocambio == 1)
            {
                ledfin = 1;
                ledbat =0;
                ledcar= 0;
                ledecu = 0; 
                RELE = 0;                
            }
        }
        else if (estado == stop)
        {
            if (estadocambio == 1)
            {
                ledfin = 1;
                ledbat = 0;
                ledcar = 0;
                ledecu = 0; 
                RELE = 0;
            }
            if ((temporizadorb == 0) && (ledlin == 1))
            {
                ledlin = 0;
                temporizadorb = 15;
            }
            if ((temporizadorb == 0) && (ledlin == 0))
            {
                ledlin = 1;
                temporizadorb = 15;
            }
        }
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ The resistor values are missing. Please add them. \$\endgroup\$
    – Justme
    Commented Nov 20, 2022 at 9:01

1 Answer 1

2
\$\begingroup\$

Your circuit is likely latching up because the battery tries to power-up the processor via RA2/AN2 input.
Since the battery is a very slowly-varying DC voltage, try adding a 10k resistor in series. AN2 input resistance is quite high, so the DC voltage drop across this external resistor should be insignificant.
For further protection a clamp diode or zener diode might be added to, to prevent over-voltage on that input pin, but the 10k resistor alone may be sufficient to stop latch-up.


edit
Connecting the battery before connecting Vdd voltage from 7805 will try to power-up the 16F684 via RA2/AN2. Some precaution should be taken to prevent start-up with too-low Vdd. The 16F684 includes brown-out-reset hardware to ensure clean power-up. Take advantage of this feature.

schematic

simulate this circuit – Schematic created using CircuitLab

\$\endgroup\$
2
  • \$\begingroup\$ I mean, you give me the solution for every problem that i had! Really thank you for your time, its means a lot for me!!! i added a circuit in the post, can you tell me if you think its okay? i saw it in the datasheet of the pic. It doesnt says about what diode to use, you recommend me to use bat54 both? Thank you! \$\endgroup\$ Commented Nov 20, 2022 at 4:52
  • \$\begingroup\$ Samuel, the datasheet ADC circuit you refer to resides inside the 16F684 in an attempt to prevent latch-up that you're likely experiencing. This internal circuitry should only be expected to clamp very short-term weak transients. Edits have been added to this answer (please re-read). The externally-added BAT54 should conduct before the internal clamp diode since its forward voltage is lower than 0.6V. \$\endgroup\$
    – glen_geek
    Commented Nov 20, 2022 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.