Noob needs some help please...


Closed Thread
Results 1 to 12 of 12
  1. #1
    Join Date
    May 2008
    Posts
    31

    Question Noob needs some help please...

    I have three page boundary warning, but I read in another post that PBP takes care of these. The main loop runs and check for button presses and counts up the lcd_info variable but it never branches (like it used to last week) to the LCD display routines. When I run it the LCD loops... "Main Loop" then "LCD Info" X up to 6 then repeats. Why isn't it branching to the LCD display section? What am I missing?
    This is my first project with PICs and PBP other than what I was doing earlier with a DS1821...
    I've loaded this into both a 16F886 and 887 and run it on both an EASYPIC3 dev board as well as a breadboard, and with battery and USB power. Results are the same with all configuration, so I'm pretty sure it's in the code somewhere. After two days of looking and commenting out bits of code here and there I don't know where else to look. I probably can't see what's right in front of me. Hope someone else can.

    Thanks

    Edit: Using melabs U2 Programmer to program the MCU; set MCU to 16F887 (or 886 as I switch back and fourth), Oscillator to XT, all other fuses to default.

    Code:
    ' PIC 16f886 (28 pin)                                                             
    
    ' Connections:
    '   -------------------- 
        ' LCD:
        '
        ' PORTB.2     ' LCD RS bit
        ' PORTB.3     ' LCD Enable Bit
        ' PORTB.4     ' LCD Data
        ' PORTB.5     ' LCD Data
        ' PORTB.6     ' LCD Data
        ' PORTB.7     ' LCD Data
        ' PORTC.1     ' LCD Backlight (20mA)
        ' PORTC.2     ' LCD Power Vdd +5V ~1.5mA
    '   ------------------------ 
    '   ' Buttons:
        ' PORTC.3       ' Enter / Confirm / Run Up / increase
        ' PORTC.4       ' Forward
        ' PORTC.5       ' Back
        ' PORTC.6       ' Down / decrease 
        ' PORTC.7       ' Up / increase
    '   ----------------------------
    '   ' Solar Charge Control:
        ' PORTC.0       ' To depletion mode MOSFET in series with Solar panel & Battery pack
    '   -----------------------------
    '   ' Solar Energy Detect:
        ' PORTA.2       ' ADC or Input to determine if Solar panel is producting power
    '   -----------------------------
    '   ' Battery Level:
        ' PORTA.3       ' ADC Monitor battery level (state of charge / Charging)
    '   ---------------------------
    '   ' Oscillator:
        ' PORTA.6       ' 4 MHZ Xtal  
        ' PORTA.7       ' 4 MHZ Xtal
    ' -----------------------------------
    '   ' Temperature Sensor
        ' PORTA.5       ' DS1821 Digital temperature sensor
    '   --------------------------------
    '
    '   EEPROM Locations
    '       0 = Alarm temperature set (trip) point
    '       1 = Battery level for compare to current batt level to determine charging or not
    '       2 = Daily High temperature
    '       3 = Daily Low temperature 
    '
    '
    '
    ' CONSTANTS
    sol_con     con     500     ' Set point where Solar array has enough sun to set flag "sun_up"
    '
    ' Define LCD pins
    DEFINE LCD_DREG     PORTB  ' Sets LCD Data Port to Port-B instead of default Port A
    DEFINE LCD_DBIT     4      ' Sets for use of PortB bits 4 thru 7 for the data
    DEFINE LCD_RSREG    PORTB  ' Sets RS (Register Select) to Port B instead of default PortA.4
    DEFINE LCD_RSBIT    2      ' Sets RS (Register Select) to bit 2 of port B (PORTB.2)
    '                          ' Enable stays at the default PORTB.3
    ' Define oscillator
    '
    define OSC 4               ' Define Oscillator as 4 MHZ
    '
    ' Define Variables
    '        
    btn_up      var     PORTC.7     ' Momentary SPST push buttons for setting system options
    btn_dwn     var     PORTC.6     ' Momentary SPST push buttons for setting system options
    btn_back    var     PORTC.5     ' Momentary SPST push buttons for setting system options
    btn_nxt     var     PORTC.4     ' Momentary SPST push buttons for setting system options
    btn_entr    var     PORTC.3     ' Momentary SPST push buttons for setting system options
    '
    sun_lvl     var     word        ' Holds solar energy level info from ADC 2
    sun_up      var     bit         ' Storage for sun is shining flag
    sun_toggle  var     bit         ' Toggle bit used for resetting daily Hi and Lo Temperatures
    toggle_drag var     bit         ' Qualifier bit to drag toggle bit low with sun_up going low
    batt_lvl    var     word        ' Holds battery level info from ADC 3
    batt_mem    var     byte        ' Battery level written to memory after subtracting ~450 (indicates 0-100%)
    batt_comp   var     bit         ' Storage for flag when batt_lvl compared to batt_mem
    charge      var     bit         ' Storage for battery charging or discharging flag for LCD
    chg_y_n     var     byte        ' Holds charactor for LCD to display "Y" if charging "N" if not
    solar_fet   var     PORTC.0     ' Solar array control ON / OFF (Depletion mode MOSFET)
    
    '
    lcd_lite    var     PORTC.1     ' LCD Backlight ON / OFF (~20 mA)
    lcd_pwr     var     PORTC.2     ' LCD power down ON / OFF
    '
    tx_pwr      var     PORTA.0     ' Transmitter board power (5V into 3V reg.)
    tx_alrm     var     PORTA.1     ' Transmitter - send alarm for low temperature condition
    tx_tst      var     PORTA.4     ' Transmit / receive loop test
    tx_confm    var     PORTB.0     ' Confirmation from receiver that transmitted data was received
    tx_g_ng     var     bit         ' Storage for transmit/receive go, no-go flag from tx_confm cycle
    '
    lcd_info    var     byte        ' Index for which LCD Info to display on line two, 1-4...
    '                               '   ...1=batt_lvl, 2=batt_chrg, 3=tx_g_ng, 4=alrm_set
    m           var     byte        ' Storage for mainloop counter
    b           var     byte        ' Storage for button set loop counter
    counter1    var     byte        ' Storage for longer period counter 1
    counter2    var     byte        ' Storage for longer period counter 2
    '
    ' DS1821 digital temperature sensor
    command     var     byte            ' Storage for command
    i           var     byte            ' Storage for loop counter
    temp        var     BYTE            ' Storage for temperature 
    DQ          var     PORTA.5         ' Alias DS1821 data pin
    DQ_DIR      var     TRISA.5         ' Alias DS1821 data direction pin
    '
    alrm_set    var     byte            ' Store set point for alarm to trip at
    day_hi      var     byte            ' Storage for Daily High temperature EEPROM loc. 2
    day_lo      var     byte            ' Storage for Daily Low temperature  EEPROM loc. 3
    
    
    ' Define ACD settings
    DEFINE ADC_BITS 10       ' 10 bit A/D Conversion
    DEFINE ADC_CLOCK 3       ' Set clock source (rc = 3)
    
    ANSELH = 0              ' Set AN8 thru AN13 Off
    ANSEL  = %00001100      ' Set pins A.2 & A.3 (AN2, AN3) to analog input, the rest to digital
    'ADCON0
    ADCON1 = %10000000      ' Set up A/D converter - Right Just., VDD REF. 
    '
    ' Set Ports input/output
    TRISA = %11101100       ' Set port A I/O
    TRISB = %00000001       ' Set port B I/O
    TRISC = %11111000       ' Set port C I/O
    
    'SSPCON = 0              ' turn off serial comm
    
    'Define ADC_SAMPLEUS 50 ' Set sampling time in uS (For different chip not needed)
    'CM1CON0 = 0 ' Comparators off (Set to zero by default, not needed)
    'CM2CON0 = 0 ' Comparators off (Set to zero by default, not needed)
    '
    '
    '
    ' ALL Settings done by me TO HERE 04/02/2013
    
    ' Test parameters. These will be replaced by actual inputs..............
    input PORTB.1
    tx_g_ng = PORTB.1
    lcd_info = 0
    ' End Test Parameters
    
    ' START-UP
            high lcd_pwr        ' Turn on the LCD display
            pause 2000          ' Wait 1 sec for LCD to start up
            low tx_pwr          ' Turn off the transmitter. A loop will turn it on when needed
            low tx_alrm         ' Turn off alarm to ensure no accidental activation
            low tx_tst          ' Turn off Transmitter test pin, loop activates it when needed
            write 1, 0          ' Put a zero in EEPROM location 1, clear Battery level in memory (batt_mem)
            batt_mem = 0        ' Clear batt_mem - Set to 0
            batt_comp = 0       ' Set battery compare flag to 0
            read 0, alrm_set    ' Get the alarm set temperature from memory
            gosub get_temp      ' Get current temperature
            high solar_fet      ' Turn on solar array to charge batteries
            sun_lvl = 0         ' Set sun level reading to 0 to prevent false indication of charging
            b = 0
    ' End Start-up
            
    
    ' Mainloop
    mainloop:
     Lcdout $fe, 1, "   Main Loop"       'Display sign-on message
     pause 1000
            'm = 0
            For m = 1 to 250        ' For Next loop generates X second delay while checking buttons
            gosub check_button      ' Check to see if a button has been pressed          
            pause 10                ' pause 10 milliseconds
            next m                  ' Repeat loop 250 times
    '        
        lcd_info = lcd_info + 1     ' Increment LCD info VAR, lcd_info count determines what info is displayed on the LCD
     Lcdout $fe, 1, "LCD Info ", dec (lcd_info)  
     pause 1000
    '        if lcd_info = 3 then goto alarm_ck  ' Check for am Alarm condition (temperature below the set point)
            If lcd_info >= 6 then               ' Reset LCD info VAR to 0 when count reaches 6
            lcd_info = 0                        ' Reset LCD info VAR to 0 when count reaches 6
            counter1 = counter1 + 1             ' Longer period counter, used for longer delays in program (Hi Lo temp reset, Sleep?)
                   ' if counter1 >= 5 then       ' X cycles throught 250 counter above... 
               ' gosub tx_test                   ' 
                counter1 = 0                    ' Reset counter 1 after GOSUB 
                'counter2 = 0                    ' reset counter 2
           ' endif    
            gosub get_temp                      ' Get curent temperature
           endif
    '
    ' Go and display LCD infor based on lcd_info count
    branchl lcd_info,[lcd_batt,lcd_chrg,lcd_tx,lcd_alrm_set,lcd_day_hi,lcd_day_lo] 
    '
    get_temp:
            Gosub init1821          ' Init the DS1821   
    
            command = $EE           ' Start temperature conversion. Changed from 44h to EEh for DS1821
            Gosub write1821               
    
            Pause 1000              ' Wait 1 second for conversion to complete
    
            Gosub init1821          ' Do another init
    
            command = $AA           ' Read the temperature.
            Gosub write1821
            Gosub read1821
    
           ' Display the decimal temperature
           ' Lcdout $fe, 1, dec (temp >> 1),".",dec(temp.0 * 5)," degrees C"  ' This line was the original code, replacement right below
            
           ' Convert to Degrees Fahrenheit
            temp = temp * 9/5 + 32      ' Degree C to Degrees F ONLY work for positive Degrees C temps (32 F and above).
    
            return          
    
    
    ' Initialize DS1821 and check for presence
    init1821:
            Low DQ                  ' Set the data pin low to init
            Pauseus 500             ' Wait > 480us
            DQ_DIR = 1       ' Release data pin (set to input for high)
    
            Pauseus 100             ' Wait > 60us
            If DQ = 1 Then
                    Lcdout $fe, 1, "DS1821 not Found"
                    Pause 500
                    Goto mainloop   ' Try again
            Endif
            Pauseus 400             ' Wait for end of presence pulse
            Return
    
    
    ' Write "command" byte to the DS1821
    write1821:
            For i = 1 to 8          ' 8 bits to a byte
                    If command.0 = 0 Then
                            Gosub write0    ' Write a 0 bit
                    Else
                            Gosub write1    ' Write a 1 bit
                    Endif
                    command = command >> 1  ' Shift to next bit
            Next i
            Return
    
    ' Write a 0 bit to the DS1821
    write0:
            Low DQ
            Pauseus 60              ' Low for > 60us for 0
            DQ_DIR = 1         ' Release data pin (set to input for high)
            Return
    
    ' Write a 1 bit to the DS1821
    write1:
            Low DQ                  ' Low for < 15us for 1
    @       nop                     ' Delay 1us at 4MHz
            DQ_DIR = 1        ' Release data pin (set to input for high)
            Pauseus 60             ' Use up rest of time slot
            Return
    
    
    ' Read temperature from the DS1821
    read1821:
            For i = 1 to 8         ' 16 bits to a word. * Changed to 8 for DS1821 Byte
                    temp = temp >> 1        ' Shift down bits
                    Gosub readbit   ' Get the bit to the top of temp
            Next i
            Return
    
    ' Read a bit from the DS1821
    readbit:
            temp.7 = 1             ' Preset read bit to 1. Was temp.15 chgd to .7
            Low DQ                  ' Start the time slot
    @       nop                     ' Delay 1us at 4MHz
            DQ_DIR = 1        ' Release data pin (set to input for high)
            If DQ = 0 Then
                    temp.7 = 0     ' Set bit to 0.  Was temp.15 chgd to .7
            Endif
            Pauseus 60              ' Wait out rest of time slot
            Return
    '
    '
    check_button:
    
            if btn_up = 0 OR btn_dwn = 0 OR btn_back = 0 _  ' If any button is pressed 
                OR btn_nxt = 0 OR btn_entr = 0 then         ' Go to button loop
    
                High lcd_lite                               ' Turn on the LCD Backlight
                goto button_loop
            endif
            return
    
    
    ' ADC
    adc_loop:               ' Get readings form the Analog to digital converters
    '
    ADCIN 2, sun_lvl      ' Get ADC value from ADC 2, the solar array 
        if sun_lvl > sol_con then   ' If the ADC reading is high enough... 
        sun_up = 1                  '   ... consider the sun to be up (day time).
        else
        sun_up = 0                  ' If ADC reading not high enough, the sun is considered down (night)
        endif
    
    ADCIN 3, batt_lvl                       ' Get ADC value from ADC channel 3
        batt_lvl = (batt_lvl - 450)         ' Remove bottom 4.4 volts or so from battery reading
        if batt_lvl > 575 then batt_lvl = 0 ' Limit high battery level reading, too high = 0 (error)  
    return
    
    ' Battery - compare ADC volts to volts in EEPROM (memory) location 1
    batt_mem_comp:
    read 1, batt_mem
    if batt_lvl >= batt_mem and _                   ' If battery level is increasing or staying the...
     batt_comp = 0 then batt_comp = 1               '   ...same set batt_comp 1 to indicate charging
    if batt_lvl > batt_mem then write 1, batt_lvl   ' As battery is charging write the new higher voltage to memory
    if batt_lvl < (batt_mem - 15) then batt_comp = 0 ' If battery voltage falls (by about 0.2), Battery not charging... 
                                                     '  ... this gives a buffer for passing clouds etc.
    ' Check if battery charging (increasing or steady volts)
    charge_ck_loop:
    '
    if sun_up = 1 and batt_comp = 1 then charge = 1     ' If sun is up and batt volts increasing then charging
    if sun_up = 0 and batt_comp = 1 then charge = 0     ' If sun is not up, no charging
    if sun_up = 1 and batt_comp = 0 then charge = 0     ' If battery volts aren't going up, no charging
    if sun_up = 0 and batt_comp = 0 then charge = 0     ' No sun, no volts, No charge.
    
    ' Daily reset of batt_mem
    
    reset_batt_mem:
    '
    if sun_up = 0 and batt_comp = 0 then write 1, 0  ' Write a 0 to EEPROM loc. 1 when 
                                                     '  sun goes down and batt discharging
    return                                                 
    
    'Compare, set, reset, & read from EEPROM daily Hi & Lo temperatures
    '
    compare_hi_lo:
        
        if sun_up = 1 then toggle_drag = 1      ' When the sun comes up set toggle drag to 1
        if sun_up = 0 and toggle_drag = 1 then sun_toggle = 0   ' If the sun is down set toggle drag to 0
        if sun_toggle = 0 then                  ' If sun toggle is a 0 then reset daily hi & lo temperatures by...
            write 2, temp                       ' Write the current temperature to EEPROM locatio 2 (Hi temp)
            write 3, temp                       ' Write the current temperature to EEPROM locatio 3 (Lo temp)
            sun_toggle = 1                      ' Set suntoggle bit to 1
            toggle_drag = 0                     ' Set toggle drag to 0
        endif    
        
        if temp > day_hi THEN write 2, temp     ' If current temperature is greater than hi temp in...
                                                ' ...memory then write the new higher temperature
        if temp < day_lo THEN write 3, temp     ' If current temperature is less than lo temp in...
                                                ' ...memory then write the new lower temperature
        read 2, day_hi                          ' Read the hi temperature into the variable day_hi
        read 3, day_lo                          ' Read the lo temperature into the variable day_lo
        
    Return
    
    
    
    ' LCD Display Information cycle                                                    
    
    lcd_batt:                                               '$DF hex for degree symbol
    gosub adc_loop                                          ' Get battery and Solar levels
        Lcdout $fe, 1, "  Temp is ", dec (temp), $DF, "F"   ' Display current temperature
        Lcdout $fe, $C0, "Battery At ", DEC (batt_lvl), "%" ' Display battery fullness %age
    goto mainloop                                           
    
    lcd_chrg:
    gosub batt_mem_comp         ' Run battery voltage comparison loop if voltage...
                                '   ... is increasing charge = 1
        if charge = 1 then 
            chg_y_n = $59       ' 59 is Hex for "Y" if charging ($ indicates Hex)
        Else
            chg_y_n = $4E       ' 4E is Hex for "N" if not charging
        endif    
            Lcdout $fe, 1, "  Temp is ", dec (temp), $DF, "F"   ' Display current temperature
            Lcdout $fe, $C0, "Charging?(Y/N) ", (chg_y_n)       ' Display "Y" if charging & "N" if not
    
            
    goto mainloop
    
    lcd_tx:
    
        if tx_g_ng = 1 then                                     ' Check to see if the Tx/RX test passed
            Lcdout $fe, 1, "  Temp is ", dec (temp), $DF, "F"   ' Display current temperature
            Lcdout $fe, $C0, "Tx/Rx Test: PASS"                 ' Display that test passed
        else    
            Lcdout $fe, 1, "  Temp is ", dec (temp), $DF, "F"   ' Display current temperature
            Lcdout $fe, $C0, "Tx/Rx Test FAIL!"                 ' Display that test failed
            PAUSE 1000                                          ' ... and pause for 5 sec to bring attention
        endif
    goto mainloop
    
    lcd_alrm_set:
        Lcdout $FE, 1, "  Temp is ", dec (temp), $DF, "F"       ' Display current temperature
        Lcdout $FE, $C0, "Alrm Tmp Set ", DEC (alrm_set),$DF    ' Display what the alarm is set...
    goto mainloop                                               '   ...to go off at
    
    lcd_day_hi:
    gosub compare_hi_lo
        Lcdout $FE, 1, "  Temp is ", dec (temp), $DF, "F"       ' Display current temperature
        Lcdout $FE, $C0, "Daily Hi ", DEC (day_hi), $DF, "F"    ' Display the daily hi temperature
    goto mainloop
    
    lcd_day_lo:
        Lcdout $FE, 1, "  Temp is ", dec (temp), $DF, "F"       ' Display current temperature
        Lcdout $FE, $C0, "Daily Lo ", DEC (day_lo), $DF, "F"    ' Display the daily lo temperature                                       
    goto mainloop    
    '
    ' What gets done when a button is pressed...
    button_loop:
    
    if btn_up = 1 and btn_dwn = 1 and btn_back = 1 _  ' If no buttons are pressed go to mainloop...
        and btn_nxt = 1 and btn_entr = 1 then  
        goto mainloop                                
        endif
    
    button_set_loop:
    if btn_up = 0 then up                   ' If the up button is pressed go to the Up loop
    if btn_dwn = 0 then down                ' If the down button is pressed go to the Down loop
    if btn_back = 0 then back               ' If the back button is pressed go to the Back loop
    if btn_nxt = 0 then forward             ' If the next button is pressed go to the Next loop
    if btn_entr = 0 then                    ' If the enter button is pressed go to the Enter loop
            goto enter
        else
            goto button_loop                ' If no buttons are pressed run the button loop again...
    endif                                   '   ... which takes you to the main loop.
    
    up:
    while btn_up = 0                ' While the Up button is pressed do this loop...                    
    pause 33                        ' pause 33 milliseconds to debounce switch
    alrm_set = alrm_set + 1         ' increase alarm set point by one degree F
    pause 300                       ' pause for 300 milliseconds
    lcdout $FE, 1, dec (alrm_set)   ' Display the alarm set point as it's changed
    wend                            ' Repeat, increasing it 1 degree F every ~1/3...
                                    '   ... second until the switch is released
    
    goto button_loop
    
    down:
    while btn_dwn = 0
    pause 50
    alrm_set = alrm_set - 1 
    pause 300
    lcdout $FE, 1, dec (alrm_set)
    wend
    
    goto button_loop
    
    back:
    while btn_back = 0
    pause 50
    alrm_set = alrm_set - 1 
    pause 300
    lcdout $FE, 1, dec (alrm_set)
    wend
    
    goto button_loop
    
    forward:
    while btn_nxt = 0
    pause 50
    alrm_set = alrm_set + 1 
    pause 300
    lcdout $FE, 1, dec (alrm_set)
    wend
    
    goto button_loop
    
    enter:                                  ' Enter button loop
    while btn_entr = 0                      ' While the button is pressed...
    pause 50                                ' pause 0.05 seconds
    wend                                    ' Do this loop until button is released
    write 0, alrm_set                       ' Write the new setting to memory location zero 
    lcdout $FE, 1, dec (alrm_set), " Has Been Set" ' Disp[lay what has been set
    pause 3000                              ' Leave that displayed for 3 seconds
    
    goto mainloop                           ' go back to normal operation (main loop)
    
    tx_test:
        lcdout $FE, 1, "  Transmit Test"    ' Display that a tx test is being performed
        LCDOUT $FE, $C0, "   In Progress"
            high tx_pwr                     ' Turn on the transmitter
            pause 1000                      ' Wait 1 seconds for the transmitter to stabilize
            high tx_tst                     ' Output a high to the chosen data pin for the test
            pause 1500                      ' wait 1.5 sec for the signal to tbe received and confirmation sent back
        if tx_confm = 1 then                ' Check for confirmation from the receiver
            tx_g_ng = 1                     ' Set the Tx go/no go bit to 1 if confirmation was received...
            else
            tx_g_ng = 0                     ' ...Otherwise set it to 0
        endif
            low tx_pwr                      ' Turn off the tranxmitter
            low tx_tst                      ' set the transmit test pin back to low
        IF tx_g_ng = 1 Then                 ' Display the result of the test...
            lcdout $FE, 1, "  Transmit Test"
            LCDOUT $FE, $C0, "      PASS"
            pause 1500
        Else
            lcdout $FE, 1, "  Transmit Test"
            LCDOUT $FE, $C0, "      FAIL"
            pause 3000
        endif
        
    return    
    
    ' Check for alarm condition (Low Temperature) and activate alarm as required
    '
    alarm_ck:
    if temp <= alrm_set then            ' Compare current temp to set temp, run loop if alarm 
            high tx_pwr                 ' Turn on transmitter
            high lcd_pwr                ' Turn on LCD
            pause 2000                  ' Wait for LCD to initialize
            for i = 1 to 10             ' Run loop 10 times
            high tx_alrm                ' Alarm pin on Txmitter high
            low lcd_lite                ' turn off LCD backlight
            LCDOUT $FE, 1, "**** ALARM! ****"    ' Display alarm message
            LCDOUT $FE, $C0, "TEMPERATURE LOW!"  ' Display alarm message
            gosub check_button          ' Check for button press
            pause 1500                  ' Pause for 1.5 sec
            low tx_alrm                 ' Turn off alarm pin o Txmitter
            high lcd_lite               ' Turn on LCD backlight
            LCDOUT $FE, 1, "TEMPERATURE LOW!"     ' Display alarm message
            LCDOUT $FE, $C0, "**** ALARM! ****"   ' Display alarm message
            gosub check_button          ' Check for button press
            pause 1500                  ' Pause for 1.5 sec
            next i                      ' Repete loop 
            'gosub compare_hi_lo         ' Reset 
            gosub get_temp              ' Get gurrent temperature
    endif 
    
        if temp > alrm_set then         ' If current temp is back above set temp...
            low tx_alrm                 ' Turn off the Alarm pin on Txmitter
            low tx_pwr                  ' Turn off Txmitter power
            low lcd_lite                ' Turn off LCD Backlight after alarm or shortly after a button press 
            goto mainloop               ' Go back to normal operation (main loop)
            else
            goto alarm_ck               ' If temp is low go to alarm loop again.
        endif             
     
    end
    
    ''''''  CODE Size Check  """""""""""""""""
           
    
          
    
    
    ' SOLAR cut-off   ' Mind where this is put (after the math on batt_lvl for display)
    
    if batt_lvl >= 110 then   ' If battery level 110% or more turn off solar array
        Low solar_fet              ' Puts ground (0 volts) on MOSFET gate  
        else 
        high solar_fet        ' Puts +5 volts on MOSFET gate
    endif    
    
    
    ' SOLAR Powered cycle  'Goes in main loop
    
    if sun_lvl >= 200 then
        gosub run_day
        else
        gosub run_nite
    endif    
    
    
    run_day:
    ' constant runnng loop with LCD display, backlite w/ good battery, tx tests
    return
    
    if batt_lvl >= 100 then
         high lcd_lite 
         'Run loop
    endif
         
    
    run_nite:
    ' sleep cycle loop implemented, low power mode
    return
    
    
    
    ' NIGHT Sleep mode
    
    low lcd_pwr
    low lcd_lite
    
    'TRISA = %11101100       ' Set port A I/O  Ok, No change
    TRISB = %11111111       ' Set port B I/O  was %00000001 for LCD out & tx_confm in
    TRISC = %11111010       ' Set port C I/O  was %11111000 buttons, 
    '                       ' C.2 LCD pwr, C.1 LCD Lite, C.0 sol-FET
    ANSEL  = 0              ' Turn off ADCs
    '
    FLAGS = 0               ' So LCD will reinitalize on wake-up
    Sleep 60
    
    ANSEL  = %00001100      ' Reset(AN2, AN3) on
    TRISB = %00000001       ' Set port B I/O
    TRISC = %11111000       ' Set port C I/O
    
    
    
    
    
    
    end
    Last edited by Neosec; - 12th April 2013 at 18:38.

  2. #2
    Join Date
    May 2008
    Posts
    31


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    Some one shoot me! I figured it out 10 minutes after posting. It is branching... I was relying on the loop for the delay for the LCD to display the info. once I put in the "Main Loop" and "LCD Info" bit for debugging they would immediately overwrite the LCD info from the branch, and I would not see it of course.
    For some reason posting a question here causes me to find the answer almost immediately afterwards. Thanks for the "Magic" this site casts on me.

  3. #3
    Join Date
    Apr 2012
    Location
    Ptolemaida
    Posts
    50


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    Same happens with me !! Try to make some flowchart on paper with a pencil or on any programm it helps to think and see clear ur code. Also try some beer or a coffe for a change :P xaxaxa

    Regards Kostas.

  4. #4
    Join Date
    May 2008
    Posts
    31


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    Thanks for the tips!! I'll give the flow chart a try. I don't drink coffee and it's a little too early for beer

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    This looks like trouble in your code. You gosub to "check_button:" and then goto "button_loop:" if a button is pressed. This creates a case where the gosub never returns, which can cause problems. Beer may help.

    Code:
    check_button:
    
            if btn_up = 0 OR btn_dwn = 0 OR btn_back = 0 _  ' If any button is pressed 
                OR btn_nxt = 0 OR btn_entr = 0 then         ' Go to button loop
    
                High lcd_lite                               ' Turn on the LCD Backlight
                goto button_loop
            endif
            return

  6. #6
    Join Date
    May 2008
    Posts
    31


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    That bit has been reworked as follows...

    Code:
    check_button:
            if btn_up = 0 OR btn_dwn = 0 OR btn_back = 0 _  ' If any button is pressed... 
                OR btn_nxt = 0 OR btn_entr = 0 _            ' and the LCD Backlight is on...
                and lcd_lite = 1 then                       ' Then Go to button loop
                goto button_loop
            endif
            if btn_up = 0 OR btn_dwn = 0 OR btn_back = 0 _  ' If any button is pressed...
                OR btn_nxt = 0 OR btn_entr = 0 _            ' and the LCD backlight is not on...
                and lcd_lite = 0 then                       ' Then turn on the backlight...
                high lcd_lite                               ' ...and pause 2 seconds
                pause 2000               ' Holding the button longer than 2 sec. gets you to...
            endif                        ' the button loop VIA the mainloop & check_button and...
            return                       ' IF statement above.
    But the GOTO / GOSUB seems ok... At least is seems to be working.

    Code:
    button_loop:
    '
    if btn_up = 1 and btn_dwn = 1 and btn_back = 1 _  ' If no buttons are pressed go to mainloop...
        and btn_nxt = 1 and btn_entr = 1 then 
     goto mainloop                                 
        endif                                         ' Otherwise continue...
    
    button_set_loop:
    if btn_up = 0 then up                   ' If the up button is pressed go to the Up loop
    if btn_dwn = 0 then down                ' If the down button is pressed go to the Down loop
    if btn_back = 0 then back               ' If the back button is pressed go to the Back loop
    if btn_nxt = 0 then forward             ' If the next button is pressed go to the Next loop
    if btn_entr = 0 then                    ' If the enter button is pressed go to the Enter loop
            goto enter
        else
            goto button_loop                ' If no buttons are pressed run the button loop again...
    endif                                   '   ... which takes you to the main loop.
    
    up:
    while btn_up = 0                ' While the Up button is pressed do this loop...                    
    pause 30                        ' pause for 30 milliseconds
    alrm_set = alrm_set + 1         ' increase alarm set point by one degree F
    lcdout $FE, 1, "Alarm Set ", _  ' Display the alarm set point as it's changed
    dec (alrm_set),$DF, "F"
    pause 300
    wend                            ' Repeat, increasing it 1 degree F every ~1/3...
    lite_timer = 0                     '   ... second until the switch is released
    goto button_loop
    
    down:
    while btn_dwn = 0
    pau... (and it continues)
    The check_button loop returns to the main loop, the button_loop series all end with a GOTO mainloop so it finds its way back. In the code above what I wanted to accomplish was that any button press would turn on the LCD backlight but not increment the variable in button_loop in doing so. The above code work pretty well though I may back off the 2 second pause.
    I'm aware that there is much room for improvement in both the code and the hardware... I'm learning as I go. I'm working with a deadline of April 17th so I don't have the time to pretty it up. The hardware is functional with some software work-arounds... Rev B will be awesome!
    The IF statement about all the buttons being "1" (not pressed) is likely not necessary since it was a button press that got me there in the first place. Cleaning up that stuff will come later, right now it doesn't break anything and I'm not tight on space yet.

    Thanks for looking it over I'm grateful for any tips.

    PS I know... interrupts and timers... in Rev B
    Last edited by Neosec; - 15th April 2013 at 02:20. Reason: typo

  7. #7
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,154


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    GOTO out of a subroutine is never a good idea.

    Set a flag before GOSUB, change the flag within the subroutine, then check the flag once you've returned and GOTO at that point.

    Robert

    Edit: it may work this time, but it's a habit you don't want to get into.

  8. #8
    Join Date
    May 2008
    Posts
    31


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    I don't follow... can you give a quick example?

  9. #9
    Join Date
    Dec 2010
    Posts
    409


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    In most programming languages, when you GOSUB, a number of registers get stored in memory to free them up for use by the subroutine. When you RETURN, those values are put back so the program can continue where it left off. When you GOTO out of a subroutine, the registers are not restored. If you did this when writing a program in a Windows or Linux environment, where the values are store in program RAM, the memory is not released when you GOTO out of the subroutine. This is called a memory leak in your program. Do this often enough, and all the RAM is used and not released until a reboot. It's a good habit to always return from a GOSUB with a RETURN to prevent this.

  10. #10
    Join Date
    Apr 2007
    Location
    Pennsylvania, USA
    Posts
    158


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    I had a similar routine once and it worked fine, until the 23rd time pressing the button it would cause the pic to reset. As Demon said, just have the button set a bit to 1 then return. Immediately after the gosub check if the bit is a 1 and if it is then goto wherever you want.
    Shawn

  11. #11
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,154


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    Quote Originally Posted by Neosec View Post
    I don't follow... can you give a quick example?
    Flag=0
    Gosub routine
    If flag = 1 then goto somewhere
    .
    .
    Routine:
    Bla bla bla
    If something then flag = 1
    Return

    Robert

  12. #12
    Join Date
    May 2008
    Posts
    31


    Did you find this post helpful? Yes | No

    Default Re: Noob needs some help please...

    OK, got it. Thanks to everyone for the input.

Similar Threads

  1. PICKit2 vs. JDM (Noob question)
    By loamobn in forum General
    Replies: 4
    Last Post: - 19th September 2010, 18:19
  2. NOOB in need of help
    By studysession in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 26th January 2009, 23:01
  3. Help a noob out?
    By yasiryassin in forum mel PIC BASIC
    Replies: 2
    Last Post: - 15th January 2008, 06:37
  4. (noob)hello world?
    By m4gill4 in forum mel PIC BASIC
    Replies: 2
    Last Post: - 30th November 2007, 00:23
  5. Uber noob needs clarity!
    By bill12780 in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 23rd July 2007, 21:40

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