Continue to Site

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.

  • 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.

HT12D and HT12E encoder/decoder issues

Status
Not open for further replies.
This
Code:
 While true
     portb.0 = 1
      Delayms(50)
     Portb.0 = 0
      delayms(50)
 Wend
used the same as this
Code:
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.
 
This
Code:
 While true
     portb.0 = 1
      Delayms(50)
     Portb.0 = 0
      delayms(50)
 Wend
used the same as this
Code:
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.

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.
 
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?
 
...As far as TOGGLE, only using for testing (indication) not going in the final code...

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.

...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.)...

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.

... but yes I wondered about too much in the INTERRUPT?...

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.
 
This is grams code for interrupt's on portb I don't think yours look any thing like this
Code:
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
 
See this part you would change to do what needs done
Code:
 // 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:
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:
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
 
Please READ Graham's code. Here it is again.

Code:
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:
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
 
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
 
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.
 
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.
 
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:
'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
      
 '-------------------------
 
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:
{
*****************************************************************************
*  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
 
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.
 
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.
 
This dosen't seem right?
Code:
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.
 
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:
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
 
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.
 
Will try your suggestions
Confussed about the HLVD as it seems to work but will review and make suggested changes.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top