+ Post New Thread
Results 1 to 19 of 19
  1. #1
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    PIC12F683 pin high problem

    Dear All,

    I'm once again turning to you with one issue that I'm not able to solve by my self. I'm using PIC12F683 which reads through ADC voltage and blinks led in various frequencies. That part works like it should in the code. Then there is a part which should control relay NC contacts (through transistor, RelayOutput at GP1_bit) when input GP3 is high. Program should turn GP1 high when short is sensed and retry 6 times turning GP1 low in 10 seconds intervals. 6th time it will exit the loop and switch GP1 permanently on.

    This is is sort of working. But GP3 when turned on inside the loop is switched on and off by 29khz frequency. See below screenshot.
    Click image for larger version. 

Name:	actual_program.png 
Views:	7 
Size:	33.4 KB 
ID:	150646

    I've tried numerous things and then tested to comment the if shorted -clause and tested inside the loop by RelayOutput = ~RelayOutput; to see what would the frequency then be and it was arund twice faster.
    Click image for larger version. 

Name:	Testing_output.png 
Views:	3 
Size:	34.4 KB 
ID:	150647

    I really don't get it why is that GP3 behaving like this. Please help.

    Here's the complete mikroC code:

    Code:
     bit Timer, PermanentShort;
     char RetryTimerCounter=0, RetryCounter = 0, PreviousRetryCounter = 0;
     double PressureReading = 0.0;
     sbit LEDOutput at GP2_bit;
     sbit RelayOutput at GP1_bit;
     sbit Shorted at GP3_bit;
    
    
    // Initializing registers
    void InitMain(void) {
         ANSEL = 0b00010001;         // Set input to digital
         TRISIO = 0b00111001;      // input Pin 7 ADC, 4 Short circuit ind. Output Pin 5 LED, 6 Relay
         OPTION_REG = 0b10000000; // GPPU disabled
         INTCON = 0b11000000;        // GIE and PEIE enabled
         PIE1 = 0b00000001;      // Enable Timer1 interrupt
         T1CON = 0b00111101;  //Timer1 Registers Prescaler= 8 - TMR1 Preset = 0 - Freq = 1.91 Hz - Period = 0.524288 seconds
         TMR1H = 0;             // preset for timer1 MSB register
         TMR1L = 0;             // preset for timer1 LSB register
         ADCON0 = 0b10000001;
    }
    // Interrupt handling
    void interrupt(void)
    {
        if (TMR1IF_bit) // If timer1 is interrupting
        {
          Timer = 1;
          TMR1IF_bit = 0; // Reset timer1 Interrupt
          if ((RetryTimerCounter > 20) && Shorted ) // ~10 seconds and short is present
          {
             RetryTimerCounter = 0;
             Retrycounter++;
          } else if (Shorted) //
            {
             PreviousRetryCounter =  Retrycounter;
             RetryTimerCounter++;
            }
        }
    }
    // Read the pressure
    double ReadPressure (void) {
          double analogvalue = 0.0;
          ADCON0.f1 = 1;                              // Enable conversion
          while (ADCON0.f1);                          // Wait for conversion to end
          analogvalue = (ADRESH << 8 ) + ADRESL;      // Store results
          analogvalue = (analogvalue/1024.00)*5.0; //calculate actual voltage across the sensor
          return analogvalue;
    }
    
    void HandleShort(void) {
        RelayOutput = 1;
        if (RetryCounter > 5)
        {
           RetryCounter = 0;
           PermanentShort = 1;
           LEDOutput = 1;
        } else if (PreviousRetryCounter != Retrycounter) RelayOutput = 0;
    }
    
    unsigned int HandleLedBlinking(double BlinkCase) {
       unsigned int BlinkInterval1;
       
       if (BlinkCase > 1.8) Blinkinterval1 = 3740;    // 5 hz
       else if (BlinkCase > 0.89) Blinkinterval1 = 6233;  // 3 hz
       else if (BlinkCase > 0.544) Blinkinterval1 = 9350; // 2 hz
       else if (BlinkCase > 0.2) Blinkinterval1 = 18700;  // 1 hz
       else if (BlinkCase < 0.2) BlinkInterval1 = 0;     // Led off
    
       return BlinkInterval1;
    }
    
    
    void main() {
         unsigned int BlinkInterval = 0, i = 0;
         InitMain();
         Timer = 0;
         PermanentShort = 0;
         LEDOutput = 0;
         RelayOutput = 0;
    
         while(1)
         {
          if (Timer)
          {
           Timer = 0;
           PressureReading = ReadPressure();
           BlinkInterval = HandleLedBlinking(PressureReading);
          }
          // Check whether there is short circuit
          if (Shorted)
          {
             HandleShort();
          } else RelayOutput = 0;
    
      //    RelayOutput = ~RelayOutput; // Testing the frequency
      
          // Short circuit is persistent. Exit loop.
          if (PermanentShort) break;
          
          if (BlinkInterval) {     // Blink led through various frequency
             if (i > BlinkInterval) {
                LEDOutput = ~LEDOutput;
                i = 0;
             }
             i++;
          } else LEDOutput = 0;
          
         }
       RelayOutput = 1; // Turn relay on as there is permanent short
    }
    Last edited by Veketti; 7th January 2019 at 21:06.

  2. #2
    Super Moderator
    Points: 77,386, Level: 67
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    12,667
    Helped
    4224 / 4224
    Points
    77,386
    Level
    67

    Re: PIC12F683 pin high problem

    I'm finding that hard to follow, can you show a flow chart please. Also, why do you convert the ADC reading to a voltage then compare it to a series of fraction values instead of using the ADC readings directly? It seems to complicate the code and make it bigger and less accurate for no reason. What happens if the voltage returned is 0.2V?

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.


    1 members found this post helpful.

  3. #3
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    You're correct, no need to convert the ADC reading to voltages, I could use as well the ADC readout directly. It just made it easier for me to undestand the voltage directly instead.. That part actually is working ok.

    This works so that Timer1 will interrupt every 0.5 seconds. Inside timer there is counters for led blink intervals, GP1 on every 10 seconds, GP1 on tries counter and flag for timer interrupt for taking ADC readout. In main there is if which checks the timer flag and if set it will take the ADC readout in volts and blink interval for corresponding voltages. Voltage below 0.2 led (GP2) is off. Next if check whether GP3 is high or low. If high it will turn relay output on (GP1). Also in that procedure (HandleShort) it tries every 10 seconds to turn off GP1 until 6 times tried and still GP3 high it will turn the led on and set flag for permanent off.

    Next in main it will exit the loop if GP3 has been high for ~60 seconds. Next if clause in main will blink the led in every 3740 to 18700 rounds depending the ADC readout.

    I'd see that the issue is within these as these are the only ones which handle the RelayOutput (GP1).
    Code:
    void interrupt(void)
    {
        if (TMR1IF_bit) // If timer1 is interrupting
        {
          Timer = 1;
          TMR1IF_bit = 0; // Reset timer1 Interrupt
          if ((RetryTimerCounter > 20) && Shorted ) // ~10 seconds and short is present
          {
             RetryTimerCounter = 0;
             Retrycounter++;
          } else if (Shorted) //
            {
             PreviousRetryCounter =  Retrycounter;
             RetryTimerCounter++;
            }
        }
    }
    ......
    void HandleShort(void) {
        RelayOutput = 1;
        if (RetryCounter > 5)
        {
           RetryCounter = 0;
           PermanentShort = 1;
           LEDOutput = 1;
        } else if (PreviousRetryCounter != Retrycounter) RelayOutput = 0;
    }
    ......
    if (Shorted)
          {
             HandleShort();
          } else RelayOutput = 0;
    I did this relay control first and then the led control. I'm pretty certain that it worked before... But how could that led control part mess it up.. Now that I was writing this I was doubting this:
    Code:
    else if (PreviousRetryCounter != Retrycounter) RelayOutput = 0;
    in the code. But I've tried that commented and still same output from GP1. Also after 6 retries it will break from the loop, turn led on and GP1 on. When it's outside of the loop GP1 stays on without any frequency.



  4. #4
    Advanced Member level 4
    Points: 7,260, Level: 20

    Join Date
    Jan 2015
    Posts
    1,015
    Helped
    321 / 321
    Points
    7,260
    Level
    20

    Re: PIC12F683 pin high problem

    According to the data sheet, GP3 is a input only pin. (You must realise this as you only ever try to read it in your code.)
    However I'm not sure if I understand you correctly about what is happening to it: are the images you have shown the GP3 signal? If so then whatever is driving it will be in your external circuit and not (necessarily - see below) your code. If those images are not GP3 then what are they?
    (There is a slight possibility you are being bitten by the RMW situation that can occur which these devices. I don't have the time to try to understand all of the ways the global variables interact but the GP3 pin is read every time though the main loop and 'HandleShort' will always start by writing a '1' to the GP1 bit - this may be triggering the RMW situaiton on GP3.)
    By the way, there is a logical problem with your code. If 'PermanentShort' is ever set, it wil cause a 'break' from the main loop. I'm not sure what mikroC does when the main loop exits but exiting the main loop is something that an embedded program should never do. The mikroC runtime code *may* just sit in a tight loop when the main funcito exits but, as some other compiler runtime codes does, it *may* cause a reset which will start you program running again (i.e. reinitialise everything and again call the 'main' function). Either way, this shoudl never happen.
    Susan


    1 members found this post helpful.

    •   AltAdvertisment

        
       

  5. #5
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    Thank you both for your input so far. Sorry in my first post I wrongly wrote GP3 on those oscilloscope texts. It should have been GP1.
    So GP1 is only output and that is doing that (can I call that Oscillate?). GP3 is just digital input sensing high/low.

    I wasn't aware of the RMW thing. I'll try that later on eg. delay after turning GP1 on. I'm starting to believe that this is not code issue rather than something like that. Eg. if I let the GP3 float it will make GP1 oscillate. Sure floating is not ideal situation but I noticed that on breadboard...



  6. #6
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    Added 10us delay after every output state change and all I could find is that the positive and negative width is now 10us longer. So I guess it's not RMW then...
    Also removed the break and changed it to if clause in main loop. Now if permanentShort is set it will just do nothing in main loop, except of course turn on the relay.

    Any other ideas what could cause this oscillation?



  7. #7
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    This is getting more confusing. ADC input pin GP0 is messing up things. If I plug that GP0 to VDD, GP1 is not oscillating anymore. If plugged to GND it does oscillate (or some other low voltage in between). How come? They're two different functions in code.

    Also just noticed that compiler is telling "Variable 'analogvalue' has been eliminated by optimizer". But that variable is used.. Something strange is happening.



  8. #8
    Super Moderator
    Points: 77,386, Level: 67
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    12,667
    Helped
    4224 / 4224
    Points
    77,386
    Level
    67

    Re: PIC12F683 pin high problem

    Sure floating is not ideal situation but I noticed that on breadboard...
    No pins should float EVER!
    I can't see where anything can cause oscillation at 29KHz, especially as a square wave. The only square wave possible at that rate is from the PWM output but that is on GP2 not GP1. I know this is frustrating but it would help us if you could show a flow diagram of what you want to happen and also show us a schematic so we can look for potential problems.

    The only software issue I can see is in relation to post #1, you break out of the while(1) loop and execute "RelayOutput = 1;" but where does it go from there?
    Aligning the braces and indenting the routines would make it much easier to read.

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.



    •   AltAdvertisment

        
       

  9. #9
    Advanced Member level 1
    Points: 2,290, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    444
    Helped
    43 / 43
    Points
    2,290
    Level
    11

    Re: PIC12F683 pin high problem

    Try this configuration.

    Code:
    CMCON = 0x07;
    Comparator if enabled affects GP0, GP1 and GP2 pins.


    1 members found this post helpful.

    •   AltAdvertisment

        
       

  10. #10
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    Quote Originally Posted by baileychic View Post
    Try this configuration.

    Code:
    CMCON = 0x07;
    Comparator if enabled affects GP0, GP1 and GP2 pins.
    That's it! You're my hero. Thank you! Wohoo, now it's working.

    That leads me to one more guestion. Since day one I started with these PIC microcontrollers it has always been bit soft to me that what registers need to be declared. There are zillion registers and every pic is different so how do you know? Of course those which you need to enable you know, but else.. Like this one. Is there any quide or quick reference for every type that you need to declare at least these registers? Or you just need to read the whole datasheet from end to end every time? Also is there any sequency what you need to use to declare these? Like for example you always need to declare INCON before PIE etc?



  11. #11
    Advanced Member level 4
    Points: 7,260, Level: 20

    Join Date
    Jan 2015
    Posts
    1,015
    Helped
    321 / 321
    Points
    7,260
    Level
    20

    Re: PIC12F683 pin high problem

    In each data sheet there is a section for each register that contains a diagram/table for the register. At the top of the table is a code for each bit that tells you if it readable and/or writable and, importantly for your question, what the 'Power On Reset' (POR) setting is.
    In many data sheets there is a table that lists all of the registers, the page the are described in full on (i.e. the table mentioned above) and also the default POR settings.
    After that, it is often down to experience in that there are several things that always need to be set: the CONFIG settings (sometimes called fuses), the oscillator, and if the MCU has any analog functionality, then the default for the related pins will be 'analog' mode (*) so setting the analog/digital mode is essential.
    (*) - there is a 'trick' that can get new players when debugging. The debug kernel that gets loaded makes all analog capable pins 'digital' at the start. Therefore if you don't set the 'ANSELx' (or whatever the name is for your MCU) register, your app can work beautifully while debugging but fail with a 'release' build. Therefore my suggestion is to ALWAYS set the analog/digital mode of all pins you use to the way you want them.
    As for other things, then my general rule is always set up before you enable - that would include setting up the interrupts the way you want them before you enable any. With some peripherals (UARTs are an example) you have to follow the sequence in the data sheet but there are peripherals in some families of devices where setting the 'enable' bit can lock in the configuration of that peripheral (although most do allow on-the-fly reconfiguration).
    Of course, the above is generic advice and any particular MCU might (and probably will) have its own set of quirks.
    Susan


    1 members found this post helpful.

  12. #12
    Super Moderator
    Points: 70,834, Level: 64
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    14,486
    Helped
    3296 / 3296
    Points
    70,834
    Level
    64

    Re: PIC12F683 pin high problem

    Hi,

    There are zillion registers and every pic is different so how do you know?
    It's less than a zillion, that's the good news.
    The bad news is, that you should read the whole datasheet thoroughly..maybe 300 pages, maybe more.
    You don't need to store every single word in your mind, but you should have a detailed overview about all the functions to easily find the place in the datasheet.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  13. #13
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    May I borrow bit this same thread even though this is bit unrelated. Do you need pull down resistor for NPN transistor base when controlling it through PIC output? I'm pretty certain that the pic has strong enough pull that it is not needed but it wouldn't be first time I'm wrong.



  14. #14
    Super Moderator
    Points: 70,834, Level: 64
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    14,486
    Helped
    3296 / 3296
    Points
    70,834
    Level
    64

    Re: PIC12F683 pin high problem

    Hi,

    To be true, I don't know the answer.

    If I want to find the answer I need the circuit and the voltages and currents.
    And I need to read the datasheets.

    The same can you do. At least you could try it and ask someone to verify your thoughts.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



    •   AltAdvertisment

        
       

  15. #15
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    Ok, that's no brainer. PIC datasheet says sink current is as well 25mA as source current so that's plenty for most transistor base currents..



  16. #16
    Super Moderator
    Points: 77,386, Level: 67
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    12,667
    Helped
    4224 / 4224
    Points
    77,386
    Level
    67

    Re: PIC12F683 pin high problem

    ... but beware that if you tri-state the pin (TRISx register) it is disconnected from the driver circuit inside the PIC so it will no longer pull the base to ground. If you use that method, you should add a resistor to prevent the base floating.

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.


    1 members found this post helpful.

  17. #17
    Super Moderator
    Points: 70,834, Level: 64
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    14,486
    Helped
    3296 / 3296
    Points
    70,834
    Level
    64

    Re: PIC12F683 pin high problem

    Hi,

    Ok, that's no brainer. PIC datasheet says sink current is as well 25mA as source current so that's plenty for most transistor base currents..
    Out of curiosity I had a look into the datasheet.
    25mA is not an "operational" current. It is the absolute maximum, the edge to get killed.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.


    1 members found this post helpful.

  18. #18
    Full Member level 2
    Points: 1,394, Level: 8

    Join Date
    Sep 2014
    Posts
    135
    Helped
    0 / 0
    Points
    1,394
    Level
    8

    Re: PIC12F683 pin high problem

    Quote Originally Posted by betwixt View Post
    ... but beware that if you tri-state the pin (TRISx register) it is disconnected from the driver circuit inside the PIC so it will no longer pull the base to ground. If you use that method, you should add a resistor to prevent the base floating.

    Brian.
    Sorry, got bit confused. You mean maybe in some other case eg. PIC16F1847 which has TRISA and TRISB and if those are set "1 = PORTA pin configured as an input (tri-stated)" it needs resistor? In this particular topics case I do declare initially ANSEL digital and TRISIO output and don't touch these after that, so they are either pulled high or down. Correct?



    Quote Originally Posted by KlausST View Post
    Hi,


    Out of curiosity I had a look into the datasheet.
    25mA is not an "operational" current. It is the absolute maximum, the edge to get killed.

    Klaus
    Yes, that was it. 20mA is the operating current.



  19. #19
    Super Moderator
    Points: 77,386, Level: 67
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    12,667
    Helped
    4224 / 4224
    Points
    77,386
    Level
    67

    Re: PIC12F683 pin high problem

    Sorry, got bit confused. You mean maybe in some other case eg. PIC16F1847 which has TRISA and TRISB and if those are set "1 = PORTA pin configured as an input (tri-stated)" it needs resistor? In this particular topics case I do declare initially ANSEL digital and TRISIO output and don't touch these after that, so they are either pulled high or down. Correct?
    The same applies to all PICs, the pins can be inputs, outputs or tri-stated. If you are using any as an output and drive it high or low, it will have the ability to source or sink current so driving a transistor through a suitable current limiting resistor is fine. However, if you use the TRIS register to tri-state a pin, it effectively becomes disconnected from the output driver circuit so in that scenario, if driving a transistor it leaves the base disconnected and floating. So if you use TRIS to control a pin, it may be wise to add a resistor to ground anyway.

    Using TRIS is actually quite a clever way to control a pin, it allows open-drain parallel connections with other devices in a bus configuration and it allows for logic level translation to any voltage lower than VDD. For example, you can run the PIC from 5V but produce a 3.3V level at the output pin. Makes it easy to mix logic families that need different signal levels.

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.



--[[ ]]--