1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

HT12D and HT12E encoder/decoder issues

Discussion in 'Electronic Projects Design/Ideas/Reviews' started by MrDEB, Dec 4, 2012.

  1. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,792
    Likes:
    134
    Location:
    morristown,tn
    This
    Code (text):
     
     
     While true
         portb.0 = 1
          Delayms(50)
         Portb.0 = 0
          delayms(50)
     Wend
    used the same as this
    Code (text):
    While true
          DelayMS(50)
         toggle(portb.0)
          DelayMS(50)
     Wend
     
    Now that was done with the full ver's of Swordfish Basic the free is not as good toggle uses more with it.
     
  2. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    True Burt. But MrDEB isn't using TOGGLE in a loop...he's using it ONE TIME to turn on an LED. This is a big waste of resources.
     
  3. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    The INTERRUPT on portB was an example that Graham used. It seems to do what it is supposed to do seeing how I need to wake up each time a tilt switch is closed.
    Working on a different issue. Wondering if I really need the weak pullups on portB but it works BUT on portB.6 I show 1.46v while portB.4&5 show 3.75. (I have 10k pullups soldered in the circuit.)
    Another issue I need to look at is Grahams code used switches on PortC to interrupt on PortB but this shouldn't make to much difference?
    In the mean time having fits with the tilt switches. The damped ones work well, One works really well while the other one is really slow. Experimenting with the dampened and undampened switches. Shaking and pounding on the bench etc. Seem pretty resilient to shaking etc but ?
    As far as TOGGLE, only using for testing (indication) not going in the final code but yes I wondered about too much in the INTERRUPT?
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22

    Going to attempt to get the interrupt with less code within.
     
  6. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Whether or not it's going in the final code is no reason NOT to understand how it should be used and why it's undesirable to use it when not needed.

    If you're asking if you need weak pullups enabled and you have 10K pullup resistors installed, the answer is no. If you are wondering if you need pullups at all, further discussion is not worthwhile.

    A command or two is reasonable. More may lead to problems and unreliable operations. The usual approach is set a flag and get out.

    The code in the interrupt routine might be:

    ButtonPressed = True

    Elsewhere in the code....like the first thing in the program loop...is a routine to read which button is pressed and take appropriate action.
     
  7. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,792
    Likes:
    134
    Location:
    morristown,tn
    This is grams code for interrupt's on portb I don't think yours look any thing like this
    Code (text):
    Interrupt PORTB_Change()
     Save(0) // Save the system variables
     If RBIF = 1 Then // Check if the interrupt was a PORTB change
     RBIF = 0
     WREG = PORTB // Be sure to read the contents of PORTB to
     // clear the mismatch
     
     // PORTB 7:4 has changed, do what you want here...
     PORTC = PORTB // In this case, I am making PORTC = PORTB
     EndIf
     Restore // Restore the system variables
    End Interrupt
     
  8. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,792
    Likes:
    134
    Location:
    morristown,tn
    See this part you would change to do what needs done
    Code (text):
     // PORTB 7:4 has changed, do what you want here...
     PORTC = PORTB
     EndIf
     Restore // Restore the system variables
    End Interrupt
    First off you should of tried this code as is and looked how it worked.

    Then you could of wrote some thing like this
    Code (text):

    Dim SavePort as byte
     // PORTB 7:4 has changed, do what you want here...
     SavePort = PORTB  // In this case, I am saving to a variable to test in main
    // so the chip can keep doing something useful and not a have a melt down becuse I got lost in
    // a long interupt hander becuse you don't no that your code jumps to the wrong place.  
     EndIf
     Restore // Restore the system variables
    End Interrupt

    main:
     If saveport = XX then // I had a button press
      // do this
      High(portc.0)
    else
     Low(portc.0)
    endif

     
     
    Last edited: Jan 16, 2013
  9. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I realize I need the port pins pulled high, I was worried WHY the portb.6 was lower than the rest of the port pins.
    Going to rewrite my code tomorrow and my code has all the elements that Graham has in his code except portC = portB. This is where I think I made my big mistake.
    Going to bed an mull over the issues. Tomorrow is a new day so I will start fresh.
    YES I should have tried out Grahams code but read through it and get the drift of what and why except the PORTC = PORTB.
    I like what Burt posted for code suggestion. Will give it a whirll in the morning
    Nite All
     
  10. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Please READ Graham's code. Here it is again.

    Code (text):



    Interrupt PORTB_Change()
     Save(0) // Save the system variables
     If RBIF = 1 Then // Check if the interrupt was a PORTB change
     RBIF = 0
     WREG = PORTB // Be sure to read the contents of PORTB to
     // clear the mismatch
     
     // PORTB 7:4 has changed, do what you want here...
     PORTC = PORTB // In this case, I am making PORTC = PORTB
     EndIf
     Restore // Restore the system variables
    End Interrupt
     
    Ok. Count.

    Step 1: Save(0)

    Step 2: If RBIF = 1 Then
    RBIF = 0
    WREG = PORTB

    PORTC = PORTB
    EndIf

    Step 3: Restore

    End Interrupt


    Let's set. Save the context. One command. One IF/THEN statement. Two commands. Restore the context. Three commands. SHORT. FEW COMMANDS. The absolute minimum possible.

    PORTC = PORTB has absolutely NOTHING to do with what you are trying to do - it's only there as an EXAMPLE. DO NOT PUT THIS IN YOUR CODE.

    Now, guess what? Leave out PORTC = PORTB. Instead, put in WhatTheHellButtonWasPressed = PORTB. Then test WhatTheHellButtonWasPressed in the main program loop to determine which button caused the interrupt.

    Code (text):


    If WhatTheHellButtonWasPressed.bits(4) = 1 then
          'the button connected to RB4 was pressed
    End if

    If WhatTheHellButtonWasPressed.bits(5) = 1 then
          'the button connected to RB5 was pressed
    End if

    If WhatTheHellButtonWasPressed.bits(6) = 1 then
          'the button connected to RB6 was pressed
    End if

    If WhatTheHellButtonWasPressed.bits(47) = 1 then
          'the button connected to RB7 was pressed
    End if

     
     
  11. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,792
    Likes:
    134
    Location:
    morristown,tn
    Jon read the code I posted its saving the portb
    To a variable that you then test and reset in main it don't
    Get better then that
     
  12. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Burt, just trying to make things clear for MrDEB. Sometimes he has trouble seeing the difference between what an example says and what he's doing.
     
  13. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    Thank you guys, Now it is more clear what I am trying to do.
    Burts code saves the button press variable then uses it in the main code body while Jons it appears to do basically the same thing?
    Didn't occur to me to use button.bits(x)=1
    Sounds easy enough. Will try both codes out but Jons looks easier to implement with a good explaniation of what is taking place.
     
  14. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    Well now it won't get out

    I changed as per suggestions but now it gets stuck. The LEDs stay on but appearently its not going into the approit routine. The greel led stays on.
    Kept getting conpile errors so I moved the sub portb interrupts.
    will investigsate futher but this is my progress = not much
    Code (text):
    'xxxxxxxxxxxxxxxxxxxx
    'interrupt
    'xxxxxxxxxxxxxxxxxxxxx
    Interrupt PORTB_Change()
     Save(0) // Save the system variables
     If RBIF = 1 Then // Check if the interrupt was a PORTB change
     RBIF = 0
     WREG = PORTB // Be sure to read the contents of PORTB to
     // clear the mismatch
          if portb.bits(6)=0 then led1 = 1
     endif
          if portb.bits(5)=0 then led2 = 1
     endif
          if portb.bits(4)=0 then led0 = 1
     endif
     // PORTB 7:4 has changed, do what you want here...
     EndIf
     Restore // Restore the system variables
    End Interrupt


    Sub PORTB_Interrupts(Control As Boolean) // Small routine to enable/disable PORTB Interrupts.
     If Control = True Then
     RBIE = 1 //  interrupt enable bit
     Enable(PORTB_Change)
     
     Else
     
     RBIE = 0 //  port change interrupt enable bit
     Disable(PORTB_Change) //
     EndIf //
    End Sub
     
    Inline Sub Sleep()
     Asm
        Sleep
     End Asm
    End Sub


    'xxxxxxxxxxxxxxxxxxxxxxxxxxx
    //                          TURN DETECTION
    'xxxxxxxxxxxxxxxxxxxxxxxxxx
    '   LEFT
    '--------------------
     If led1 = 1  Then
        RBIF = 1
       // LED1 = 1  // GREEN       // NOTE I need to make ports LOW for transmission, HIGH for testing
        led2 = 0
        led0 = 0
        TX_pwr = 1               // turn on transmitter
        TX_Enable = 0            // enable encoder
             DelayMS(500)
        Toggle (LED1)
             DelayMS(500)
        LED1 = 0      // make sure its off
        TX_pwr = 0
        TX_Enable =1           // LOW for transmit        
        rbie = 0  
           
     End If
         
     '-------------------------    
     
  15. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I THINK I solved issue

    It seems to work except the low battery test. Needs work.
    Put the turn detections into subs. hopefully this is correct?
    Code (text):
    {
    *****************************************************************************
    *  Name    : UNTITLED.BAS                                                   *
    *  Author  : [select VIEW...EDITOR OPTIONS]                                 *
    *  Notice  : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS]              *
    *          : All Rights Reserved                                            *
    *  Date    : 1/2/2013                                                       *
    *  Version : 1.0                                                            *
    *  Notes   :  this one works 1/10/2013                                                              *
    *          :                                                                *
    *****************************************************************************
    }



    Device = 18F2420
    Clock = 8
    Config   LVP = OFF, mclre = off
    Include "InternalOscillator.bas"
    Include "utils.bas"
    Dim RBIF As INTCON.0  //port change interupt flag
    Dim RBIE As INTCON.3 //port change interupt enable
    Dim x As Byte
    Dim TX_Enable As PORTC.0
    Dim TX_pwr As PORTC.1
    Dim GD_bat As PORTC.2
    Dim led0 As PORTC.3 // blue
    Dim LED1 As PORTC.4  //green
    Dim led2 As PORTC.5  //red
    Dim s1 As PORTB.6
    Dim s2 As PORTB.5
    Dim s3 As PORTB.4
    Dim saveport As Byte
    'xxxxxxxxxxxxxxxxxxxxxxxxxxx
    //  TURN DETECTION SUB ROUTINES
    'xxxxxxxxxxxxxxxxxxxxxxxxxx

     '-------------------------    
    sub   RIGHT ()
    '--------------------------
        led2 = 1
        RBIF = 1
        led0 = 0
        LED1 = 0
       // led2 = 1    // RED
        TX_pwr = 1               // turn on transmitter
        TX_Enable = 0            // enable encoder
               DelayMS(500)      // just enough to see for testing
        Toggle (led2)
               DelayMS(500)
        led2 = 0     // make sure its off
        TX_pwr = 0
        TX_Enable =1           // LOW for transmit        

    end sub    
    '-----------------------
    Sub  LEFT()
    '--------------------
        LED1 = 1  
        RBIF = 1
       // LED1 = 1  // GREEN       // NOTE I need to make ports LOW for transmission, HIGH for testing
        led2 = 0
        led0 = 0
        TX_pwr = 1               // turn on transmitter
        TX_Enable = 0            // enable encoder
             DelayMS(500)
        Toggle (LED1)
             DelayMS(500)
        LED1 = 0      // make sure its off
        TX_pwr = 0
        TX_Enable =1           // LOW for transmit        
        RBIE = 0               // reset enable bit

     End Sub
    ' xxxxxxxxxxxxxxxxxxxxxxxxxx
    sub  BATTERY_TEST()
    'xxxxxxxxxxxxxxxxxxxxxxxxxxx
    ' BAD BATTERY
     If led0 = 1 And  PIR2.bits(2)=1 Then         // check hlvd flag
        TX_pwr = 1    //turn on transmitter
        led0 = 1     //blue led next to green BI color in final plan
             DelayMS(1000)
        Toggle(led0)
     End If
        PIR2.bits(2)=0
         
     ' GOOD BATTERY
     If led0 = 0 And PIR2.bits(2)=0 Then
           GD_bat = 1       // green led next to blue GD_bat = good battery
           DelayMS(1000)
           Toggle( GD_bat)
           DelayMS(1000)
           TX_pwr = 0                       //turn off transmitter
        EndIf  
       // PIR2.bits(2)=0    // reset interrupt flag  DO I REALLY NEED TO RESET?
       // RBIF = 0      // Port change interrupt flag bit
    end sub

     
         
    'xxxxxxxxxxxxxxxxxxxx
    'interrupt
    'xxxxxxxxxxxxxxxxxxxxx
    Interrupt PORTB_Change()
     Save(0) // Save the system variables
     If RBIF = 1 Then // Check if the interrupt was a PORTB change
     RBIF = 0
     WREG = PORTB // Be sure to read the contents of PORTB to
     // clear the mismatch
          If PORTB.bits(6)=0 Then LEFT()
     EndIf
          If PORTB.bits(5)=0 Then RIGHT()
     EndIf
          If PORTB.bits(4)=0 Then BATTERY_TEST()
     EndIf
     // PORTB 7:4 has changed, do what you want here...
     EndIf
     Restore // Restore the system variables
    End Interrupt


    Sub PORTB_Interrupts(Control As Boolean) // Small routine to enable/disable PORTB Interrupts.
     If Control = True Then
     RBIE = 1 //  interrupt enable bit
     Enable(PORTB_Change)
     
     Else
     
     RBIE = 0 //  port change interrupt enable bit
     Disable(PORTB_Change) //
     EndIf //
    End Sub
     
    Inline Sub Sleep()
     Asm
        Sleep
     End Asm
    End Sub



    '

     

    //sssssssssssssssssssssssssssssssssssssssssss


     


    SetAllDigital
    Input(s1)
    Input(s2)
    Input(s3)
    Output(led0)
    Output(LED1)
    Output(led2)
    Output(TX_Enable)
    Output(TX_pwr)
    Output(GD_bat)
    HLVDCON = %00010111  // 3.12 volts
    PIR2.bits(2)=0       // clear HLVD flag
    PIE2.bits(2) = 1      //enable HLVD interrupt



    // Start Of Program...
    TRISB = %11110000 // Make PORTB7:4 all inputs
    TRISC = %00000000 // Make PORTC all outputs
    led0 = 0          // turn off all leds
    LED1 = 0
    led2 = 0
    TX_Enable = 1
    TX_pwr = 0
    GD_bat=0
    While True // Infinite loop
           
    PORTB_Interrupts(True) // Enable PORTB interrupts
        Sleep // Put the PIC to sleep and wait for a change
     // on PORTB 7:4
    Wend


     
     
  16. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Sigh.

    1. Toggle to turn on an LED one time is STUPID as we have discussed.

    2. Exactly ONE command in the interrupt subroutine: WhatTheHellButtonWasPressed = PORTB. Parse it out in the main program loop.

    3. The HLVD routine is just hosed up. Read my code again and don't get creative.

    4. You ARE NOT using interrupts for the HLVD test...a button press activates the routine, so again, it should look just like what I posted....including setting and clearing register bits.
     
  17. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    Not using interrups for the HLVD?
    pressing the s3 button make a change on portb so is it not using the interrupt to WAKE?
    I will check if the pic is in SLEEP before pressing the s3. It appears to work? but maybe not??
    Will try and make some changes so only one command for the interrupt exit.
     
  18. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    This dosen't seem right?
    Code (text):
    nterrupt PORTB_Change()
    Save(0) // Save the system variables
    If RBIF = 1 Then // Check if the interrupt was a PORTB change
    RBIF = 0
    WREG = PORTB // Be sure to read the contents of PORTB to
    // clear the mismatch

    If s1=0 Then

    //LEFT()
    EndIf
    Unless all it is doing is reading the PortB contents?
    I see where I had the sub routes it has a possibility of getting lost.
     
  19. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    It appears the INTERRUPT is being used

    for all three button presses unless I am missing something?
    As for the HLVD it appears to work.
    I set the voltage in MPLAB higher than the trip point and the GREEN LED comes on(GD_bat) but if I lower the voltage below the trip point the blue led comes on (led0)
    I inserted LED routines within the interrupt and all the LEDs come on at appropriate times but it goes no further(runs the associated sub routine). I now know that that section of code is executing within the interrupt but want to figure out why it goes no further as it should. If I take out the LED routines all is well.
    Code (text):
    Interrupt PORTB_Change()
     Save(0) // Save the system variables
     If RBIF = 1 Then // Check if the interrupt was a PORTB change
     RBIF = 0
     WREG = PORTB // Be sure to read the contents of PORTB to
     // clear the mismatch
     
            If s1=0 Then
            led0 = 1       // TEST IF WORKING
      delayms(500)
            led0 = 0
          //LEFT()
     EndIf
     
          If s2=0 Then
           led0 = 1       // TEST IF WORKING
      delayms(500)
      toggle(led0)
          //RIGHT()
     EndIf

          If s3=0 Then
          led1=1           // TEST IF WORKING
          delayms(500)
          led1 = 0
         // BATTERY_TEST()
       
     EndIf
     // PORTB 7:4 has changed, do what you want here...
     EndIf
     Restore // Restore the system variables
    End Interrupt
     
  20. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    It's really spelled out in message #129.

    Before I contact my attorney to file a lawsuit against you for the blunt trauma to my head I have incurred because of you, let me try one last time.

    In the first block of code in message #129, replace

    PORTC = PORTB with

    WhatTheHellButtonWasPressed = PORTB

    Do NOT add anything else to the subroutine. NOTHING no matter how much you want to.

    The second block of code goes in the main program loop. Put the various actions in the appropriate places in the IF/THEN statements.


    You are not using HLVD to generate an interrupt. Use the code I originally posted to poll the HLVD register to determine status when the button is pressed which is what you claimed to want.
     
  21. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    Will try your suggestions
    Confussed about the HLVD as it seems to work but will review and make suggested changes.
     

Share This Page