interrupt handling faster than if's?


Closed Thread
Results 1 to 14 of 14
  1. #1
    Join Date
    Jul 2006
    Posts
    76

    Default interrupt handling faster than if's?

    I am using two 16F628A's and trying to get them to communicate serially that have ports turn on when a button is pressed. My code is listed below, but when I run the program it responds VERY SLOWLY. I am wondering if there is a way to make it respond faster by using interrupts, or some other way. Thank you for your time and patience...

    PS: the pauses below the hserout commands are to prevent buffer overflow problems (thanks mister_e)

    -Mike

    Transmitter Code:
    -----------------

    define HSER_TXSTA 20h
    define HSER_BAUD 2400

    cmcon = 7

    sone var byte
    sone = 0
    stwo var byte
    stwo = 0
    sthree var byte
    sthree = 0
    sfour var byte
    sfour = 0
    Synch var byte
    Synch = "~"
    Pre var byte
    Pre = $A5

    Main:

    if (PORTA.0 = 0) AND (sone = 0) then
    hserout [Pre,Synch,"1"]
    sone = 1
    pause 200
    endif
    if (PORTA.0 = 1) AND (sone = 1) then
    hserout [Pre,Synch,"2"]
    sone = 0
    pause 200
    endif


    if (PORTA.1 = 0) AND (stwo = 0) then
    hserout [Pre,Synch,"3"]
    stwo = 1
    pause 200
    endif
    if (PORTA.1 = 1) AND (stwo = 1) then
    hserout [Pre,Synch,"4"]
    stwo = 0
    pause 200
    endif


    if (PORTA.2 = 0) AND (sthree = 0) then
    hserout [Pre,Synch,"5"]
    sthree = 1
    pause 200
    endif
    if (PORTA.2 = 1) AND (sthree = 1) then
    hserout [Pre,Synch,"6"]
    sthree = 0
    pause 200
    endif


    if (PORTA.3 = 0) AND (sfour = 0) then
    hserout [Pre,Synch,"7"]
    sfour = 1
    pause 200
    endif
    if (PORTA.3 = 1) AND (sfour = 1) then
    hserout [Pre,Synch,"8"]
    sfour = 0
    pause 200
    endif

    goto Main

    Receiver code
    -------------
    define HSER_CLROERR 1
    define HSER_RCSTA 90h
    define HSER_BAUD 2400

    Msg Var BYte
    cmcon = 7

    Main:
    hserin [WAIT("~"),Msg]


    if (Msg = "1") then
    high PORTA.0
    goto main
    endif
    if (Msg = "2") then
    low PORTA.0
    goto main
    endif

    if (Msg = "3") then
    high PORTA.1
    goto main
    endif
    if (Msg = "4") then
    low PORTA.1
    goto main
    endif

    if (Msg = "5") Then
    high PORTA.2
    goto main
    endif
    if (Msg = "6") then
    low PORTA.2
    goto main
    endif

    if (Msg = "7") Then
    high PORTA.3
    goto main
    endif
    if (Msg = "8") then
    low PORTA.3
    endif
    goto main

  2. #2
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    Hi mbw123,

    Providing a timeout to "HSerin" would be one way.

    Also, why don't you send Decimal digits? Take a look at DEC modifier.

    Lastly, in receiver code, "Select Case" could be handy.


    --------------------------------
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  3. #3
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    How are the PICs connected together ? by a wire or by radio/IR link

    Do you really need the PRE and SYNCH values to be sent ?

    If there is only ever going to be the actual values sent between the PICs then just send the actual values and constantly loop the receiver program like this

    Code:
    Main:
    hserin 20,Main [Msg]
    
    Select Case Msg
       Case "1"
              high PORTA.0
       Case "2"
              low PORTA.0
       Case "3"
              high PORTA.1
       Case "4"
              low PORTA.1
       Case "5"
              high PORTA.2
       Case "6"
              low PORTA.2
       Case "7"
              high PORTA.3
       Case "8"
              low PORTA.3
    end select
    goto main
    When no data is being received your program will sit at the Hserin command and return to Main every 20mS if nothing is recevied. Because you are constantly waiting for the Msg the reponse will be instant and because you are only sending one character there should be no possibility of overflow unless three messages are sent in very quick succession but even then it should process them fast enough.

    You can then reduce the pause in your transmit program to get a very fast response. Currently you have 200*8 mS of pause in the transmit program so it will take a minimum of 1.6 seconds to complete one loop.

    You could also speed up the send program by changing

    Code:
    if (PORTA.0 = 0) AND (sone = 0) then
        hserout [Pre,Synch,"1"]
        sone = 1
        pause 200
    endif
    if (PORTA.0 = 1) AND (sone = 1) then
        hserout [Pre,Synch,"2"] 
        sone = 0
        pause 200
    endif
    to
    Code:
    if (PORTA.0 = sone) then           '  input state has changed
      if  PORTA.0 = 0 then               '  port has gone low
            hserout ["1"]                    '  send the command
            sone = 1                         ' record the state
      else
            hserout ["2"]                    ' port has gone high so send the command
            sone = 0                         ' record the state
      end if
      pause 10                     ' may not even need a pause
    endif
    That way with no switches being changed you only perform 4 tests each program loop and if a switch has changed you perform an additional test. Can probably be optimised further but brain is not fully functional yet... need more coffee

    Out of curiosity, why are you storing values opposite to the current state of the pin ?

    Personally I would store the current value and detect when it was different. eg

    Code:
    if (PORTA.0<>sone) then      ' state has changed
           sone = PORTA.0           ' store new state
           { do all the other stuff }
    endif
    Last edited by keithdoxey; - 21st October 2006 at 11:12.
    Keith

    www.diyha.co.uk
    www.kat5.tv

  4. #4
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    Thinking about this further, and assuming you are only using the pin values to send to the other end then

    TRANSMITTER

    Code:
    PORTSTATE var Byte
    LASTSTATE var Byte
    
    
    Main:
         PORTSTATE= PORTA & $0F ' mask Port A to retrieve lower 4 pins
         If PORTSTATE <> LASTSTATE then     ' something has changed
                LASTSTATE = PORTSTATE
                Hserout [PORTSTATE]
         Endif
         Pause 10
         Goto Main
    RECEIVER
    Code:
    Main:
          Hserin 20,Main, [PortState]
          PortState = PortState ^ $0F  ' EOR to invert pin states (omit this line if you want normal state)
          PORTA = Portstate   ' Set the pins
          Goto Main
    That would save loads of program space provided you did not need individual pin states for any other purpose.

    Dont forget the set the TRISA registers to configure pins as Inputs and outputs.

    NB: There might be slight errors above as I rarely get it right first time!!!!
    Keith

    www.diyha.co.uk
    www.kat5.tv

  5. #5
    Join Date
    Jul 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    Thanks for the many responses. I am going to eventually hook it up to a radio link so I will probably need the Pre and Synch values. Using your code previously posted, I should be able to just add those variables in, right? Thanks again (I will test the code right now)...

    -Mike

  6. #6
    Join Date
    Jul 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    One last thing. Will the code (your most recent post before this one) work when two or more buttons are pressed at the same time? Thank you for the help.

    -Mike

  7. #7
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mbw123
    One last thing. Will the code (your most recent post before this one) work when two or more buttons are pressed at the same time? Thank you for the help.

    -Mike
    Hi Mike, multiple keypresses shouldnt be a problem as it takes the value of all switches as a 4 bit binary value eg 0110 and sends that to the distant end where you write 1001 (or 0110 if you dont invert) to the output port.

    LASTPORT gets set as 0110 ( or 6 if you prefer) and the next time it looks at the port if the value is any different the new value will be sent and stored.

    It doesnt matter whether it has changed to 0100, 0111, 1010 etc because all of them are different to 0110 and the entire port value will be replicated at the distand end with just a single command string.
    Keith

    www.diyha.co.uk
    www.kat5.tv

  8. #8
    Join Date
    Jul 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    Hmmmm....the code isn't working. Maybe I am missing something out of the code. Could you post both of the entire programs to make sure I wrote them correctly? Thank you.

    -Mike

  9. #9
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    I dont have the programs, I just wrote that as a reply.
    I did say there might be a mistake in there.

    Have you set the TRISA register for inputs on the tranmitter PIC and outputs on the receiver PIC.

    Have you disabled the comparators on both PICs
    Keith

    www.diyha.co.uk
    www.kat5.tv

  10. #10
    Join Date
    Jul 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    I'll check that today. Again, thanks for the responses!

    -Mike

  11. #11
    Join Date
    Jul 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    Would this work as the full code (forgive my ignorannce: I'm a newbie)?

    Transmitter:
    ------------

    define HSER_TXSTA 20h
    define HSER_BAUD 2400

    cmcon = 7

    PORTSTATE var Byte
    LASTSTATE var Byte
    input PORTA.0
    input PORTA.1
    INput PORTA.2
    input PORTA.3

    Main:
    PORTSTATE = PORTA & $0F
    If (PORTSTATE <> LASTSTATE) then
    LASTSTATE = PORTSTATE
    Hserout [PORTSTATE]
    Endif
    Pause 10
    Goto Main


    Receiver
    --------

    define HSER_CLROERR 1
    define HSER_RCSTA 90h
    define HSER_BAUD 2400

    cmcon = 7
    PortState VAR byte
    output PORTA.0
    output PORTA.1
    output PORTA.2
    output PORTA.3
    low PORTA.0
    low PORTA.1
    low PORTA.2
    low PORTA.3

    Main:
    Hserin 20,Main, [PortState]
    PortState = PortState ^ $0F
    PORTA = Portstate
    Goto Main

  12. #12
    Join Date
    Jul 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    keithdoxey,

    what if I wanted to change

    "hserout [PORTSTATE]"

    to

    "hserout [WAIT("~"),PORTSTATE)"

    Would that work with the same code?

    Thank you.

    -Mike

  13. #13
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mbw123
    keithdoxey,

    what if I wanted to change

    "hserout [PORTSTATE]"

    to

    "hserout [WAIT("~"),PORTSTATE)"

    Would that work with the same code?

    Thank you.

    -Mike
    Hi Mike, sorry for the delay replying, been on holiday for a few days

    The above should be "Hserout["~",PORTSTATE]

    Wait is only applicable for Hserin.

    In your previous post, instead of all the input and output commands just use the following

    Transmitter

    TRISA = %11111111 ' all pins as inputs

    Receiver

    TRISA = %11110000 ' A3-A0 as outputs
    PORTA = 0 ' turn off all ports

    HTH

    Keith
    Keith

    www.diyha.co.uk
    www.kat5.tv

  14. #14
    Join Date
    Jul 2006
    Posts
    76


    Did you find this post helpful? Yes | No

    Default

    Thank you very much for the reply.

    "Wait is only applicable for Hserin."

    Sorry. Stupid mistake by me. I meant

    HSERIN [WAIT("~"),PORTSTATE]

    Also would that slow down the code a lot?

    Thanks.

    -Mike

Similar Threads

  1. Won't go back to SLEEP after 1st Interrupt
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 29th June 2009, 09:00
  2. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  3. Help with Analog Interrupt
    By brid0030 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 13th February 2008, 18:14
  4. NEWBIE: Some basic questions using interrupts
    By JackPollack in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 8th March 2006, 02:59
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

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