Referral to ULPWU/PLVD code per AN879??


Closed Thread
Results 1 to 14 of 14
  1. #1
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378

    Angry Referral to ULPWU/PLVD code per AN879??

    Am programming a 16F690 chip using PicBasic Pro. My application is battery powered (3 ea NiMH AA batteries) and I am using a Low Drop Out regulator with very low quiescent power to provide Vdd = 3.3 vdc to the MCU and peripherals. I want to monitor the battery voltage with PICBasic code whenever the chip is not in SLEEP mode and then flash a red LED if the battery voltage has dropped to 3.5 volts. The 16F690 doesn't have a PLVD module. Therefore, I have been studying the Microchip AN879 application note on how to use the ULPWU module of the 16F690 as a Programmable Low-voltage Detect circuit. However, I am struggling trying to figure out how to convert the algorithm described in AN879 to PicBasic.

    Do any of you have or can you point me to any PICBasic coding examples to do this or another way to do the battery monitor/low voltage detect function I need in the 16F690??

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    The 16F690 has an internal 0.6V reference that can be turned ON/OFF from the VRCON register.

    With VREF+ set to VDD, you can use the 0.6V reference to measure the PIC's VDD voltage. Which goes something like this ...
    Code:
    VDD   VAR WORD
    
    VRCON.4 = 1        ; Turn 0.6V reference ON
    PAUSEUS 100        ; Allow VP6 to settle
    ADCIN 15, VDD      ; get VP6 analog reading (10-bit)
    VRCON.4 = 0        ; Turn 0.6V reference OFF
    VDD = 6138 / VDD   ; convert to voltage
    The variable VDD now holds the VDD voltage *10 (3.3V = 33).
    The formula is the same for any VDD voltage.

    Then ...
    Code:
    IF VDD < 32 THEN GOSUB LowVoltage   ; if less than 3.2V
    This then tells you when the battery voltage has gone below the LDO's "Drop-Out".
    Or you can set it to any other voltage (lower than normal VDD) as required.

    hth,
    DT

  3. #3
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Question 6138/VDD?? Testing not showing correct measurement

    Darrell, first of all thanks so much for your input. I really like your algorithm much better than the Microchip AN869 approach to a PLVD because it is simpler and also doesn't require an additional Resistor and Capictor.
    I have implemented your algorithm into the code attached below and tried to test it using the 16F690 in a PICKIT2 LPDV board. It compiles and programs the board/16F690 with no problem, but the testing shows there must be a problem in the code, which I will explain.
    To ensure accurate testing I calibrated my PICKIT2 per their instructions with a voltmeter and made sure it puts out exactly 4.8 volts to the target ch when 4.8 volts is selected in the PICKIT2 Voltage selector. I have attached a picture of the PICKIT2 screen during the test for reference.
    Notice that I have inserted some WRITE statements in the code to enable me to READ the different variables at certain points in the code execution.
    These read values are shown in HEX in the EEPROM memory locations at the bottom of the PICKIT2 screen:
    Address 11 is ADINPUT = hex A0 = decimal 160
    Address 13/14 is VDD = hex 0027 = decimal 38; which is equivalent to the code calculation 6138/ADINPUT = 6138/160 = 38.36 => 3.84 volts.
    Address 17 is Vthr = hex 2F = decimal 47; which is as it should be based on the constant value being set as 47 in the variable declarations.

    However, this testing shows the calculated VDD to be 3.84 volts when the voltmeter on the calibrated PICKIT2 input to the VDD on the chip is showing exactly 4.80 volts. This then causes the IF-THEN statement to incorrectly trigger the Low Voltage warning subroutine that blinks the LED. I have double checked my code and can't find why the A/D is measuring the wrong value. In fact, to equal the calibrated 4.8 volt input the ADINPUT reading by the A/D would have to be decimal 127 instead of the measured 160. Can you see any mistakes in my code that would cause this measurement error? If you have a PICKIT2 with the LPDV board you should be able to use this code to replicate my testing.

    One thing in your algorithm I didn't quite understand was where the value 6138 comes from in the calculation 6138/ADINPUT that converts the A/D measurement to voltage. Can you please explain?

    Code:
    '****************************************************************
    '*  Name    : DT_VoltageMonitor.BAS                             *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2009                                *
    '*          : All Rights Reserved LodeStar Assoc. Inc.          *
    '*  Date    : 7/21/2009                                         *
    '*  Version : 1.0                                               *
    '*  Size    : 226 words                                         *
    '*  Notes   : Adapted from Darrell Taylor's code in order to      *
    '*          : monitor a battery pack input from 4ea NiMH AA     *
    '*          : batteries that is normall fully charged at 4.8vdc.*
    '****************************************************************
    
    ' ---------[ Device Declaration & CONFIG settings]-----------------------------
    ASM  ; 16F690
      ifdef PM_USED                  ; For PM assembler
        device  INTRC_OSC_NOCLKOUT   ;   Oscillator Selection
        device  FCMEN_OFF            ;   Fail-Safe Clock Monitor
        device  IESO_OFF             ;   Internal External Switchover
        device  BOD_OFF              ;   Brown-out Detect
        device  CPD_OFF              ;   Data Code Protection
        device  PROTECT_OFF          ;   Code Protection
        device  MCLR_OFF             ;   Master Clear Reset
        device  PWRT_ON              ;   Power-up Timer
        device  WDT_OFF              ;   Watchdog Timer
    
      else                            ; For MPASM assembler
    cfg=      _INTRC_OSC_NOCLKOUT     ;   Oscillator Selection
    cfg=cfg&  _FCMEN_OFF              ;   Fail-Safe Clock Monitor
    cfg=cfg&  _IESO_OFF               ;   Internal External Switchover
    cfg=cfg&  _BOR_OFF                ;   Brown-out Reset
    cfg=cfg&  _CPD_OFF                ;   Data Code Protection
    cfg=cfg&  _CP_OFF                 ;   Code Protection
    cfg=cfg&  _MCLRE_OFF              ;   Master Clear Reset
    cfg=cfg&  _PWRTE_ON               ;   Power-up Timer
    cfg=cfg&  _WDT_OFF                ;   Watchdog Timer
      __CONFIG  cfg
                                
      endif
    ENDASM
    ' The above config  is inteded to set CONFIG = %0000000000000000 for hex 00C4 or
    ' FCMEN off(0), IESO off(0), BOR off(00), CPD off(1), CP off(1), /MCLR is  
    ' digital input(0), /PWRTE on(0), WDTE off(0), FOSC<2:0> (100). 
    
    ' -----------------------[ Set Registers & Ports ]-----------------------------
      ' Set ADCON registers for A/D converter
            ADCON0 = %10110101  
                ' ADCON0.7 = ADFM = 1          ' 10-bit result is right justified
                ' ADCON0.6 = VCFG = 0          ' Set VREF+ to VDD 
                ' CHS<3:0> = 1101              ' Select 0.6V Ref channel                                                    
            ADCON1 = %00110000    ' Select FRC as A/D conversion clock source
      ' Set FOSC=1MHz to stay inside recommended TAD range when not in SLEEP mode
            OSCCON = %01000001
    
      ' Set ANSEL register to make RA1 analog input
        ANSEL= %11110011   ' Set PortA to Analog I/O to save power during Sleep but
                           ' leave Bits 2 & 3 as digital for RA2 and RA3 interrupts
        ANSELH= %11111111  ' Analog module enabled to save power during Sleep
        DEFine ADC_BITS 10
    
    ' -----------------[ Declare Variables & Aliases ]-----------------------------  
    led2    VAR PORTC.1     ' Set RC1 as LED indicator of low battery condition
    ADINPUT VAR WORD        ' Stores VP6 value as sampled by ADC
    VDD     VAR WORD        ' Stores VDD value as converted from ADINPUT
    Vthr    CON 47         ' Set threshold (4.7v) to trigger low voltage warning
    b0      VAr vdd.byte1   ' LSB of VDD when right justified
    b1      var VDD.Byte0   ' MSB of VDD when right justified
    
    Main:
        VRCON.4 = 1        ' Turn 0.6V reference ON
        PAUSEUS 100        ' Allow VP6 to settle
        ADCIN 15,ADINPUT   ' Get VP6 analog reading (10-bit)
        VRCON.4 = 0        ' Turn 0.6V reference OFF
        WRITE 11,ADINPUT
        VDD = 6138/ADINPUT ' convert input reading to VDD voltage
        ' VDD now holds the measured VDD voltage * 10 (i.e., 3.4V = 34)
        '    The formula is the same for any VDD voltage.
        ' Assume normal VDD = +4.8vdc direct from fully charged battery pack input
        WRITE 13,b0        ' Remove comments on Write statements for test only
        WRITE 14,b1
        Write 17,Vthr      
        IF VDD < Vthr THEN 
            GOSUB LowVoltage   ' if VDD less than 4.7v
        EndIF
    GOTO Main
    '------------------------------Subroutines-------------------------------------
    LowVoltage:
    ' If Battery is low..flash low battery monitor light
        HIGH led2
        PAUSE 125        
        Low led2
        Pause 500                                                         
      RETURN
    END
    Attached Images Attached Images  
    Last edited by jellis00; - 22nd July 2009 at 21:34. Reason: Add picture

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    OOPS, my bad!

    The VP6 channel is 13, not 15.
    So use this instead ...
    Code:
    ADCIN 13,ADINPUT
    It's channel 15 on a 16F887, so I got confused.
    <br>
    DT

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Oh I forgot to answer the 6138 question.

    6138 comes from 0.6 * 1023 = 613.8
    In order to get 1 decimal of precision, multiply * 10 for 6138.
    <br>
    DT

  6. #6
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Talking Changing channel to 13 fixed it!

    Thanks Darrell. I should have caught that channel number myself. I was able to test this thoroughly by incrementally changing the Vthr constant in the code and correspondingly incrementing the target voltage in the PICKIT2. It now works like a charm.

    Thanks also for answering my question about the 6138/VDD calculation. I now understand the algorithm completely.

    Let me say how much I appreciate your frequent and outstanding support to the forum. I use it extensively and really do appreciate it.

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    SWEET!

    I expect to receive 1% of the value of that resistor and capacitor you saved.
    <br>
    DT

  8. #8
    Join Date
    Jan 2007
    Posts
    39


    Did you find this post helpful? Yes | No

    Default Re: Referral to ULPWU/PLVD code per AN879??

    Hello, I have found this post, because I want to do the same. I have 16F690 battery powered system and I want to detect low battery caase. I have Implemented the code like described here, but it somehow doesn't work:

    'read baterry
    VRCON.4 = 1 ; Turn 0.6V reference ON
    PAUSEUS 200 ; Allow VP6 to settle
    ADCIN 13, temp_word ; get VP6 analog reading (10-bit)
    VRCON.4 = 0 ; Turn 0.6V reference OFF
    VDD = 6138 / temp_word ; convert to voltage ve vdd je 25 = 2,5 V
    temp_data[9] = (VDD DIG 1) + $30
    temp_data[10] = "."
    temp_data[11] = (VDD DIG 0) + $30
    temp_data[12] = 13
    temp_data[13] = 10

    But it somehow doesn't work. If powerred with 3.3 V I have in VDD 42, if powerred from exhausted bateries with total voltage 2.4 V I have there 4 and if powered from new bateries with 3.1 V I have there 4. Do you have any idea, why it is doesn't work?
    Bob

  9. #9
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Referral to ULPWU/PLVD code per AN879??

    I imagine that you are only seeing 2 digits of a much larger number that was calculated wrong because either the A/D wasn't set up right or a variable size is wrong.
    Make sure you have these in your program.
    Code:
    temp_word VAR WORD
    VDD       VAR WORD
    
    DEFINE ADC_BITS 10
    ADCON0.7 = 1
    DT

  10. #10
    Join Date
    Jan 2007
    Posts
    39


    Did you find this post helpful? Yes | No

    Default Re: Referral to ULPWU/PLVD code per AN879??

    Wow, super, it's working now. I didn't specified the

    DEFINE ADC_BITS 10
    ADCON0.7 = 1

    Thanks a lot, I really apreciated you quick answer and help!!!

    bob

  11. #11
    Join Date
    Dec 2013
    Posts
    2


    Did you find this post helpful? Yes | No

    Default Re: Referral to ULPWU/PLVD code per AN879??

    Hello I've just recently joined and found this post after a lot of research because I am wanting to do the same. I am using the chip 16F690 and I want to detect low battery also. I would be using 5volts to power on the chip and would want to detect 3.7volts or any voltage as long as its lower than 5volts when the voltage has dropped and the led would be used as the output to indicate this or a multimeter showing the voltage if possible. I have Implemented the code that has been provided by 'jelliss00' in the MPLAB software to build but the program but isn't working. If any of you can give guidance to me on developing the program I would really appreciate.

  12. #12
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,599


    Did you find this post helpful? Yes | No

    Default Re: Referral to ULPWU/PLVD code per AN879??

    It would help if you posted your entire code, which PBP version and assembler. A schematic of your circuit is always a good idea.

    Robert

  13. #13
    Join Date
    Dec 2013
    Posts
    2


    Did you find this post helpful? Yes | No

    Default Re: Referral to ULPWU/PLVD code per AN879??

    Name:  schematic of voltage.jpg
Views: 863
Size:  23.3 KB

    Hi sorry about the late reply I have added the schematic and included the programming below. The Led would turn on when the potentiometer has been adjusted and the voltage comes to 2.5volts as I would be using comparator to detect voltage. The software I am using is MPLAB IDE version 8.92. The program doesn't seem to work I would appreciate your help on this.

    list p=16F690
    include "p16F690.inc"
    radix dec

    ;***** CONFIGURATION
    ; ext reset, no code protect, no watchdog, 4 MHz int clock
    __CONFIG _MCLRE_ON & _CP_OFF & _WDT_OFF & _IOSCFS_OFF & _IntRC_OSC_RB4EN
    ; pin assignments
    #define LED PORTC,3 ; indicator LED on RC3
    constant nLED=3 ; (port bit 3)

    ;***** RC CALIBRATION
    RCCAL CODE 0x3FF ; processor reset vector
    res 1 ; holds internal RC cal value, as a movlw k
    ;***** RESET VECTOR ************************************************** ***
    RESET CODE 0x000 ; effective reset vector
    movwf OSCCAL ; apply internal RC factory calibration

    ;***** MAIN PROGRAM ************************************************** ***
    ;***** Initialisation
    start
    ; configure ports
    movlw ~(1<<nLED) ; configure LED pin (only) as an output
    tris PORTC

    ; configure comparator 1
    movlw 1<<C1PREF|1<<C1NREF|1<<C1POL|1<<C1ON
    ; +ref is C1IN+ (C1PREF = 1)
    ; -ref is C1IN- (C1NREF = 1)
    ; normal polarity (C1POL = 1)
    ; comparator on (C1ON = 1)
    movwf CM1CON0 ; -> C1OUT = 1 if C1IN+ > C1IN-

    ;***** Main loop
    main_loop
    ; display comparator output
    btfsc CM1CON0,C1OUT ; if comparator output high
    bsf LED ; turn on LED
    btfss CM1CON0,C1OUT ; if comparator output low
    bcf LED ; turn off LED
    ; repeat forever
    goto main_loop

    END

  14. #14
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,599


    Did you find this post helpful? Yes | No

    Default Re: Referral to ULPWU/PLVD code per AN879??

    To start:

    Labels end with colons.

    Assembler must be delimitted with ASM.

    Is this really PIC BASIC?

    Robert

    Edit: PORTC.3 <--- period, not comma
    Last edited by Demon; - 22nd December 2013 at 17:50.

Similar Threads

  1. Reading in Manchester code
    By brid0030 in forum Code Examples
    Replies: 0
    Last Post: - 10th March 2009, 21:55
  2. How much code space do PBP statements use.
    By Darrel Taylor in forum Code Examples
    Replies: 5
    Last Post: - 13th February 2009, 21:31
  3. Loop with two motor and 2 sensors
    By MrRoboto in forum mel PIC BASIC
    Replies: 4
    Last Post: - 8th December 2008, 23:40
  4. Making Program Code Space your playground...
    By Melanie in forum Code Examples
    Replies: 15
    Last Post: - 19th July 2008, 08:26
  5. Re-Writing IF-THEN-AND-ENDIF code?
    By jessey in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 18th August 2006, 17:23

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts