Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Best practice - waiting for an interrupt - do nothing loop?

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
TSEYFARTH

Bascom Member



Joined: 01 Jul 2006
Posts: 1054

usa.gif
PostPosted: Sat Nov 22, 2014 12:16 am    Post subject: Best practice - waiting for an interrupt - do nothing loop? Reply with quote

Hello all,

I need to wait for an interrupt to occur. What is the best way to do this? I was thinking of a Counting loop just to do nothing but to provide a time out. This interrupt is used for several subs/functions but not at the same time. Any suggestions for managing this with best practices?
Thanks,
Tim

(BASCOM-AVR version : 2.0.7.7 )
Back to top
View user's profile
Arera

Bascom Member



Joined: 23 Sep 2007
Posts: 386
Location: Wuppertal, Germany

germany.gif
PostPosted: Sun Nov 23, 2014 2:17 pm    Post subject: Reply with quote

Hello Tim,

after a couple of hours here is the firt reply to you question. It might have take so long, because it seems there is a deeper fault in the structure of your prog.
I think the core of the problem is the general structure of the prog, and I think many people find that to be unclear. To me, it has been the hardestt part of programming in the beginning years.
It's hard to figure out where to begin, but here's my attempt:

Let's split up your taks in two problems:
1st: waiting for the interrupt
2nd: do something after a timeout

In this post, let's have a look a 1st, and step over to 2nd as soon as 1st is clear.

Generally, no prog should ever wait for anything for more than a few milliseconds.
If that idea sound wired to you, think about this procedure:

A prog should have a main routine, which is executed regulary (do...loop).
Inside this main-loop thre are all the steps and procedures you need, even those that you need only once a year at chistmas.
Outside the main-loop there are interrupt-routines, and things that need to be done only once at all, like configuring external HW.

Now a problems occurs:
How to prevent the chistmas part from beeing executed EVERY run of the main-loop?
The answer might be a flag. A flag might be a bit-var.
The chistmas loop only executes if the flag is SET. The routine must not forget to RESET the flag!

fake-example:

do 'main loop
if christmas_flag = 1 then
reset chistmas flag
toggle led1 'it toggles if the ISR_chistmas occurs (triggered by who knows, it's a fake prog...)
end if

toggle led2 'it toggles very fast....

loop 'end main loop

ISR_christmas:
set chistmas_flag
return

end

As you can see, you don't have to wait until chistmas to toggle led2!
Important: you do not "wait" (halt your prog) until the interrupt occurs, instead you "switch active" the christmas-part of the always-running main-loop to be executed once an interrupt occurs.

So far for now, please let me know if that ideas are helpfull...
Marc
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 971

poland.gif
PostPosted: Sun Nov 23, 2014 4:19 pm    Post subject: Reply with quote

State of program You can change in any place of your code and other decisions may be depend on te Program state

Code:
Dim Program_state As Byte
Dim Timeout As Word

Do

If Switch = 0 Then
    Program_state = 1
    Timeout = 1000
End If

 If Program_state = 1 Then
  ' we waiting for something
 End If

 If Program_state <> 0 Then
  If Timeout = 0 Then Program_state = 0                     'choose state You want
 End If

Loop

Timer_isr:
 If Timeout > 0 Then Decr Timeout                           'work only if needed
 


I have one more example of program do nothing whole day Very Happy and waiting for trigerring

This is programm for stairs or driveway highlighting . To facilitate the movements through the code I used aliases and this works. If anyone interessted i have whole working code with PWM and sequentialy one by one raising bulbs/LED`s.

Code:

Const Waiting = 0
Const Switch_on_from_down = 1
Const Lighted_from_up = 2
Const Switch_off_from_down = 3
Const Switch_on_from_up = 4
Const Lighted_from_down = 5
Const Switch_off_from_up = 6

'---------------------------------------------------
Do

 Select Case Satus

  Case Waiting
   If Sw1 = 0 Then Status = Switch_on_from_down             'sensors
   If Sw2 = 0 Then Status = Switch_on_from_up

  Case Lighted_from_down
   If Timeout = 0 Then Status = Switch_off_from_down

  Case Lighted_from_up
   If Timeout = 0 Then Status = Switch_off_from_up

 End Select

  Gosub Control

Loop
End
'----------------------------------------------------
Control:
 Select Case Status
   'slowly one by one
     Case Switch_on_from_down
      'Switch_on_from_down and then..
        Status = Lighted_from_down
        Timeout = Timeout_time

     Case Switch_off_from_down
       'Switch_off_from_down and then..
         Status = Waiting

     Case Switch_on_from_up
      'Switch_on_from_up and then..
        Status = Lighted_from_up
        Timeout = Timeout_time

     Case Switch_off_from_up
      'Switch_off_from_up and then..
        Status = Waiting

  End Select

Return


So Status can be changed in any place.
Back to top
View user's profile Visit poster's website
TSEYFARTH

Bascom Member



Joined: 01 Jul 2006
Posts: 1054

usa.gif
PostPosted: Sun Nov 23, 2014 8:37 pm    Post subject: Reply with quote

Thanks for the replies.

The problem is, that I have to wait for a radio uC to get to a state before sending a command. This is true for most all of the commands that are sent to the uC. So a command is sent, then you have to wait for the radio to respond back that it is ready to accept the next part of the command. True using flags is appropriate in many case. However in this case, I want to prevent another process from occurring without preventing the interrupt from occurring. This would be easy using waitus... but that also stops all other processes including interrupts, I believe. This is why my thought of a do-nothing or do little loop might make sense.

Code:

Do
 waitus 1
 incr cntr
  If IntFlag = 1 Then Exit Do
Loop Until Cntr = 1000

 


This, BTW, was an effort to improve code that did similar:

Code:

Function Api_WaitforCTS() as byte   'returns 1 if CTS is ready.
   local w_TO as word
   w_TO=0
   Api_WaitforCTS=1
   while rfm24_CTS_pin = 0 '
      waitus 1
      incr w_TO
      If w_TO = 5000 Then   '3000 then 'Time out in 3+mS. Power up is longest command so far. It takes 2.5mS.
         Api_WaitforCTS=0
         Print  "No CTS "
         exit function
      End If
   wend
end function

 


Code such as this calls the above function. There are many other commands code sets that also call the function - waiting for a pin to change, which can also be tied to an Isr - either a Int1 or PCINT10.

Code:

sub Read_Cmd_Buf(byref b_dat() as byte, byval b_Length as byte)
   'Max value of b_Length is 16, no check is done.
   local b_Cmd as byte
   local b_temp as byte
   b_temp=Api_WaitforCTS()

   'READ_CMD_BUF
   b_Cmd=&h44
   reset rfm24_Nsel
      spiout b_Cmd,1
      b_temp=Api_WaitforCTS()
      spiin b_dat(1),b_Length
   set rfm24_Nsel
end sub
 



The sub above can be called from many other code sections throughout the program, and as previously stated the Function Api_WaitforCTS is called from any other subs each performing different operations.

So using a flag, or series of flags, at least to me at the moment, would be very complicated.

Finally, it was an effort to speed up the operation overall. In the end, I left it as it is shown above without the use of an Isr.

Thanks again for your responses. I apologize too, it may have been better to include in the original post, what has been included here.
Tim
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 971

poland.gif
PostPosted: Sun Nov 23, 2014 8:50 pm    Post subject: Reply with quote

Today I`m working on "Speaking Clock" with WTV020. I must wait till first word about hours is finish (different lenght) to send next Address for minutes. I don`t know is this is good practice but works :F
Code:
Do
If Busy = 0 Then
Exit Do
End If
Loop

Now I see U have this with timeout Smile
Back to top
View user's profile Visit poster's website
i.dobson

Bascom Expert



Joined: 05 Jan 2006
Posts: 1570
Location: Basel, Switzerland

switzerland.gif
PostPosted: Mon Nov 24, 2014 6:09 am    Post subject: Reply with quote

Hi EDC,

Your solution would work, but it doesn't look ready nice. This looks much nicer:

Code:

while busy=0
wend
 


or

Code:

do
loop until busy=1
 


Regards
Ian Dobson

_________________
Walking on water and writing software to specification is easy if they're frozen.
Back to top
View user's profile
TSEYFARTH

Bascom Member



Joined: 01 Jul 2006
Posts: 1054

usa.gif
PostPosted: Mon Nov 24, 2014 6:20 am    Post subject: Reply with quote

Ian,
When being executed, I think it is also faster for the uC to use a single line of code rather than If/Then/End If. I did some tests some years back and that ws the case. Mark may have improved that making my comment be false, but I am not sure.

Tim
Back to top
View user's profile
Paulvk

Bascom Member



Joined: 28 Jul 2006
Posts: 1257
Location: SYDNEY

australia.gif
PostPosted: Mon Nov 24, 2014 9:06 am    Post subject: Reply with quote

Hello Tim

I found myself that using the case statement was faster and created less code in some of the matrix clock program where I kept running out of flash.
But this does not hold true all the time sometimes it was the same.
Mark said at the time that with the case it loads the value then keeps comparing it each time
but with If Then Else it has to load it each time it tests.

Regards Paul
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Mon Nov 24, 2014 11:15 am    Post subject: Reply with quote

TSEYFARTH wrote:
using waitus... but that also stops all other processes including interrupts, I believe.

You believe wrong in regard of interrupts.
In contrary, a heavy interrupt load will lengthen any wait.
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 971

poland.gif
PostPosted: Mon Nov 24, 2014 12:48 pm    Post subject: Reply with quote

What about open Library for LCD4busy or LCD4busy_anypin and grab ASM procedure from that (for RW pin) Razz Then make Your own Macro Very Happy I test this later
Back to top
View user's profile Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum