Code Problems with 16F684


Closed Thread
Results 1 to 6 of 6
  1. #1
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72

    Unhappy Code Problems with 16F684

    Hello and thanks for any and all help or comments,

    I'm having issues with the attached code. Its for a circuit that replaces an Escort Radar Detector "Smart Cord". The original just didn't have enough features for me, so I built my own and tossed in a PIC to add a few more features.

    The PIC for the most part adds a "flip-flop" type on-off function by inputing the state of a tact-button and toggling a relay and green power LED on or off when pressed between 100 mS and 1 S ( anti "accidental bump" protection).

    When a radar alert is detected on another pin, the PIC flashes red and blue LEDs in an alternating fashion for a visual alert (very small and NOT visible outside of my car).

    Another feature uses an ADC input to measure the voltage output by the cars dashboard light dimmer circuit to dim the LEDs in relation with the dashboard lights. Also, when the car detects that it is daylight out, it automaticaly turns the dashlights off and takes the dimmer voltage to ground which makes my radar detector cord LEDs go to full brightness so they can be seen in daylight. (Thanks HUGE to Darrel Taylor and his HPWM10 routine!)

    The above all works fine, and is great. However, When I try to detect the length of the power button press to see if it is held down for more than ~ 3 seconds and toggle a bit which is suppsed to suppress the LEDs (turn them off, but leave the radar detector on), It doesn't work. As in it won't turn off the LEDs, But everything else still works.

    I use a while/wend on the tact-button input pin to increment the variable "onOffBtntst" while the button is pressed. If it is pressed for 100 mS to 1 S then it toggles the power on and off like above. If it is held for more than 3 seconds it should set the varible "suprsLEDs" to 1 which in turn should keep the LEDs off. It doesn't seem to want to suppress the LEDs. The power on-off part works as expected, and if you hold the button for more than 1 S it doesn't toggle the relay, which it shouldn't. Maddning!

    I then added a serial debug output to PORTC.4 to try to see what "onOffBtntst" is doing, and then what "suprsLEDs" is doing and that won't work either! It just spits gibberish into hyperterm (spades) and another program "realterm" (random giberrish), and I've tried every
    mode PIC side and port setting on the PC side I can think of (Both program and hardware device settings. other serial devices work fine)

    I think I must be setting up a port or module wrong or have a logic error that I just can't see. I've stepped away and came back over the past two weeks and still can't nail it down, Please
    help!

    Code:
    @ DEVICE pic16F684,INTRC_OSC_NOCLKOUT,  WDT_OFF,  PWRT_OFF,  MCLR_OFF, BOD_OFF, IESO_OFF, FCMEN_OFF
    
    include "HPWM10.pbp" 
    
    DEFINE OSC 8            ' Define 8 MHz oscillator 
    
    DEFINE ADC_BITS 10      ' 10 bit A/D Conversion
    DEFINE ADC_SAMPLEUS 50  ' 50 uS A/D sample time
    
    CMCON0 = %00000111      ' Disable Comparator
    VRCON = %00000000       ' Disable Comparator Voltage Reference
    
    ANSEL = %01000000       ' Set pin 8 (AN6) to analog input, the rest to digital
    ADCON0 = %10011001      ' Set up A/D converter - Right Just., VDD REF., CH 6, ON
    ADCON1 = %00110000      ' Set up A/D Converter clock source to internal RC
    
    TRISC.2 = 1             ' Set Pin 8 to input for A/D Converter input
    TRISC.5 = 0             ' Set Pin 5 to output for PWM generator
    TRISA.5 = 1             ' Set Pin 2 to input for Power ON/OFF Button
    TRISC.3 = 0             ' Set Pin 7 to output for Power ON/OFF Relay
    TRISA.4 = 1             ' Set Pin 3 to input for Power LED sense input
    TRISA.3 = 1             ' Set Pin 4 to input for Alert LED sense input
    TRISC.1 = 0             ' Set Pin 9 to output for LED3 - Blue Alert LED Cathode
    TRISA.2 = 0             ' Set Pin 11 to output for LED2 - Red Alert LED Cathode
    TRISA.0 = 0             ' Set Pin 13 to output for LED1 - Green Power on LED Cathode
    
    ' definitions
    
    onOffBtn var PORTA.5    ' Power ON/OFF Button               - Pin 2
    onOffRly var PORTC.3    ' Power ON/OFF Relay                - Pin 7
    brghtns var PORTC.2     ' LED Brightness A/D input.         - Pin 8
    pwrOn var PORTA.4       ' Power LED sense input             - Pin 3
    alrt VAR PORTA.3        ' Alert LED sense input             - Pin 4
    LED1 var PORTA.0        ' LED1 - Green Power on LED Cathode - Pin 13
    LED2 var PORTA.2        ' LED2 - Red Alert LED Cathode      - Pin 11
    LED3 var PORTC.1        ' LED3 - Blue Alert LED Cathode     - Pin 9
    beepSup Var PORTA.1     ' Beep Suppress                     - Pin 12
    beep var PORTC.0        ' Beep on power cut                 - Pin 10
    serial var PORTC.4      ' Serial out for debugging          - Pin 6
    
    btnVar var byte         ' Holding variable for Power Button
    aTOd var word           ' Holding variable for A/D converter
    Frequency var word      ' Holding variable Frequency for PWM
    DutyCycle1 Var Word     ' Holding variable Duty Cycle For PWM
    beepLoop var byte       ' Loop Variable for beep
    beepKill var bit       ' Kill variable for beep loop
    onOffBtnTst var word    ' Test variable for on/off button
    suprsLEDs var bit      ' Variable to suppress LEDs
    
    frequency = 1000        ' Set PWM frequency to 1000 Hz
    LOW LED1               ' Set Green Power on LED  to off at start-up
    LOW LED2               ' Set Red Alert LED to off at start-up
    LOW LED3               ' Set Blue Alert LED to off at start-up
    low onOffRly            ' Set On/Off relay to off at start-up
    btnVar = 0              ' Clear On/Off Button Variable
    aTOd = 0                ' Clear A/D converter Variable
    DutyCycle1 = 0          ' Clear PWM Duty Cycle Variable
    beepLoop = 0
    beepKill = 0
    onOffBtnTst = 0
    suprsLEDs = 0 
    high beepsup 
    
    '-------------------------------------------------------------------------------
    MainLoop:
    
    button onoffbtn, 0, 255, 0,btnvar, 1, pwrOnOff:
    
    PowerCheck_Alert:
    IF pwron = 0 then 
        gosub pulseWidthModulator:
        if suprsLEDs = 0 then
        HIGH led1
        else
        LOW led1
        endif
        high beepsup
        HIGH Beep
        beepkill = 0
    else 
            LOW led1
             if onOffRly = 0 then    
                if beepkill = 0 then 
                    for beeploop = 1 to 6
                    low beepSup
                    LOW beep 
                    Pause 50
                    High beep
                    Pause 100
                    next beepLoop
                    beepkill = 1
                endif
            endif            
    endif
    
    
    IF alrt = 0 then 
    if suprsLEDs = 0 then
        LOW led1
        HIGH led2
        pause 70
        LOW led2
        HIGH led3
        pause 70
        LOW led3
     else
     LOW led2
     LOW led3
     endif
        else 
        LOW led2
        LOW led3
    endif
    
    goto mainloop:
    
    '-------------------------------------------------------------------------------
    pulseWidthModulator:
    
    ADCIN 6, atod 
    
    
    IF aTOd	>	93	AND	aTOd	<=	186	THEN		
    								DutyCycle1 = 	10
    ENDIF									
    IF aTOd	>	186	AND	aTOd	<=	279	THEN		
    								DutyCycle1 = 	30
    ENDIF									
    IF aTOd	>	279	AND	aTOd	<=	372	THEN		
    								DutyCycle1 = 	50
    ENDIF									
    IF aTOd	>	372	AND	aTOd	<=	465	THEN		
    								DutyCycle1 = 	70
    ENDIF									
    IF aTOd	>	465	AND	aTOd	<=	558	THEN		
    								DutyCycle1 = 	90
    ENDIF									
    IF aTOd	>	558	AND	aTOd	<=	651	THEN		
    								DutyCycle1 = 	110
    ENDIF									
    IF aTOd	>	651	AND	aTOd	<=	744	THEN		
    								DutyCycle1 = 	130
    ENDIF									
    IF aTOd	>	744	AND	aTOd	<=	837	THEN		
    								DutyCycle1 = 	150
    ENDIF									
    IF aTOd	>	837	AND	aTOd	<=	930	THEN		
    								DutyCycle1 = 	170
    ENDIF									
    IF aTOd	>	930	AND	aTOd	<=	1023 THEN		
    								DutyCycle1 = 	200
    ENDIF									
    
    IF aTOd	<	45	AND	aTOd		     THEN		
    								DutyCycle1 = 	1023
    ENDIF
    								
    @ HPWM10 1,_DutyCycle1, _Frequency
    
    return
    '-------------------------------------------------------------------------------
    pwrOnOff:
    
    WHILE onoffbtn = 0
    pause 1
    onOffBtntst = onOffBtntst + 1
    wend
    pause 10
    serout2 serial,16780,[DEC onOffBtntst, 10] 
    if onOffBtntst >= 3000  and onOffBtntst <= 65535 then
        if suprsLEDs = 0 then
        suprsLEDs = 1
        else
        suprsLEDs = 0
        endif
    endif
    
    if onOffBtntst >= 100 and onOffBtntst <= 1000  then
    toggle onOffRly 
        if onOffRly = 0 then
        suprsLEDs = 0
        endif
    endif
    onOffBtntst = 0
    serout2 serial,16780,[DEC suprsLEDs, 10] 
    goto PowerCheck_Alert:
    
    
    end

  2. #2
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Figured out part of it.

    I guess I was thinking that 1000 mS was equal to 1 second and 3000 mS was equal to 3 seconds in PIC time. turns out I was wrong, tweaked my pauses a little and got it to work right.
    However, still having serial issues, unimportant now, But I suspect if I were using a better OSC it would clear up. I have a cap across the rails right at the pic but I may tack on a smaller one right across the power pins to see if that helps.

    While I'm using up a post I might as well ask another question. I getting ready to do something with serial again, and I want to use a "two's complement addition" error checking routine and I'm a bit afraid of the math involved. I guess an example of some code could help, or if someone could explain how to add three bytes with no carries or how to discard the overflow bits? To explain it in terms of (A+B+C) ? discard some things = 0 using actual PBP operators would be the most helpful. Or if someone has a ready to use routine? or is there something easier?


    Thanks as always ahead of time.

  3. #3
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    I don't know about your current question, but I think I can shead some light on you solution. You have OSC = 8 for an 8meg clock, but the pic you are using defaults to 4 meg. To use 8 you need to set up OSCCON reg for 8 meg clock. The DEFINE OSC just tells PBP how fast you INTEND to run, so it is able to calculate the delays for your pause. I am guessing your pauses were taking twice as long? so 1000 = 2 sec and 3000 = 6 sec?

    This will also affect your serial issues
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  4. #4
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    Ryan7777, I can't help but notice that you are missing a compare value in the last statement:
    IF aTOd < 45 AND aTOd ??????? THEN DutyCycle1 = 1023
    ENDIF

    I think I would write this routine it as follows to save you some cycles:

    SELECT CASE aTOd
    CASE < 94
    DutyCycle1 = 10
    CASE < 187
    DutyCycle1 = 10
    CASE < 280
    DutyCycle1 = 30
    CASE < 373
    DutyCycle1 = 50
    CASE < 466
    DutyCycle1 = 70
    CASE < 559
    DutyCycle1 = 90
    CASE < 652
    DutyCycle1 = 110
    CASE < 745
    DutyCycle1 = 130
    CASE < 838
    DutyCycle1 = 150
    CASE < 931
    DutyCycle1 = 170
    CASE <= 1023
    DutyCycle1 = 200
    END SELECT

    That should save you some cpu cycles...

    Dave Purola,
    N8NTA

  5. #5
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Awesome!

    Thanks for your replies. I had always assumed that the 16F68Xs just defaulted to 8 instead of 4 Mhz. I'll OSCTUNE it to 8, as you said, it seems like everything is timing out to be twice as long. That explains a lot, Thanks! And yeah, I'll re-write it for select case for the end version, I was still hashing it out and ended up with rough code trying to figure out the timing issue. Now that I have that figured out, and If i can use serout to debug my dimming feature, I can tighten it all up.

    Thanks again to the both of you, You guys are awesome.

    Ryan

  6. #6
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    i'll osctune it to 8
    nope!!!
    Code:
    DEFINE OSC 8              
    OSCCON = %01110000
    Dave
    Always wear safety glasses while programming.

Members who have read this thread : 0

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