How do I make this code more responsive?

Jeff Haas

Senior Member
I'm starting a new project and have a short bit of code that I'd like to be more responsive.

An 08M should blink a series of three LEDs while waiting for a button to be pressed. When it's pressed it will then trigger an MP3 (played via the Tenda MP3 board) and change the pattern of blinking LEDs. My first pass at this is to have one LED blink, wait for the button press and then trigger another LED. However, I find that my first instance of this code is not that responsive - I have to hold down the button for a couple of seconds to get the second LED to trigger.

How can this be improved? I figure there's a better way. Thanks for any insight!

Code:
; *******************************
;    Filename: LED Blinker and button test
;    Date: 			
;    File Version: 	
;    Written by:  Jeff Haas	
;    Function:		
;    Last Revision: 3/19/2012
;    Target PICAXE: 08M	
; ******************************* 


#picaxe 08M
#no_end
SetFreq m8   'Required for Tenda board communication 

symbol PBUTTON = pin3  	'Assigns pin3 to Button.

main:


	b0 = 0  			'Set byte 0 to 0
	readadc 2,b0
	pause 5			'Brief pause on the checking loop
	b0 = b0 + 5 * PBUTTON	'Add 5 to byte 0 and multiply by value of PBUTTON.  Button pressed = high value.
	debug b0

	high 2			'Blink first LED as "idle" state
	pause 1000
	low 2
	pause 1000
	if b0 < 1 then Main

	high 4			'Blink second LED to show button has been pressed
	pause 1000
	low 4
	pause 500

goto main
 

tony_g

Senior Member
using the setint might respond quicker and have the second led blink as the interrupt from the switch is detected

Code:
#picaxe 08M
#no_end
SetFreq m8   'Required for Tenda board communication 

symbol PBUTTON = pin3  	'Assigns pin3 to Button.

main:
      
      setint %0001000,0001000 'set interrupt condition on pin 3 to jump to blink led 2

	b0 = 0  			'Set byte 0 to 0
	readadc 2,b0
	pause 5			'Brief pause on the checking loop
	b0 = b0 + 5 * PBUTTON	'Add 5 to byte 0 and multiply by value of PBUTTON.  Button pressed = high value.
	debug b0

	high 2			'Blink first LED as "idle" state
	pause 1000
	low 2
	pause 1000
	if b0 < 1 then Main
	
interrupt:
      low 2                   'added as if interrupt occurs whilst led 1 is high it will remain high when interrupt blinks led 2
      setint %0001000,0001000 'resets interrupt condition on pin 3
	high 4			'Blink second LED to show button has been pressed
	pause 1000
	low 4
	pause 500
      return                                     'returns back to where it left original routine to deal with interrupt request

hopefully this is a little more near what you are after,

tony
 

westaust55

Moderator
Since you have a loop with delays of the order of 3.5 seconds and once per pass of due loop you in effect look for a switch closing that means there is a high probability that the code will miss the switch operation and need to wait the 3.5 second or miss it completely if the switch operation is momentary.

Accordingly I agree with tonyg and suggest you go with the interrupt method.
The first SETINT command can be in front of the Main: if the switch closure is to be momentary.
Then for a momentary switch closure loop in the interrupt and wait for switch release.

If the switch can be left closed for an extended period, then use the interrupt to set a flag to indicate when to flash the second LED.
Also you may then need to Check when the switch is released to clear the flag.
 

inglewoodpete

Senior Member
Just to add some conjecture (!), I'm advocating a restructure of the code but not with interrupts.

Open up the program by removing all the pause statements. This allows the program to loop through many times faster. As a consequence, the program can scan the input buttons dozens of times a second. The program can then make decisions at a much faster rate and increment a loop counter on each loop. On each loop, the program would then check the counter values to measure the delays.

I have posted a program for an 08M that works using these principles in the code snippets section of the forum. Have a read of the code and get to understand how the open looping concept works.
 

Jeff Haas

Senior Member
Thanks and good morning from California! This is one of the reasons I like this forum, the terrific help that's available, and so quickly, too.

I'll give these a try tonight and see how things go.
 

vttom

Senior Member
As has been mentioned, the problem is with the pause statements that cause the LEDs to blink. You need to interleave the checking of the input pin with the blinking of the LEDs. The following code will check the input pin 10 times a second while also blinking the LED on pin 2 or 4. Pressing the button will switch which LED blinks. The "PBUTTONWASZERO" stuff is there to check that the button is released button between presses. Without it, pressing and holding the button down would cause the code to constantly toggle between which LED is lit.

Code:
#picaxe 08M
#no_end
SetFreq m8

symbol PBUTTON = pin3  	'Assigns pin3 to Button.
symbol PBUTTONWASZERO = b2

low 2, 4
b1 = 2

main:

	for b0 = 0 to 9

		if PBUTTON = 0 then
			PBUTTONWASZERO = 1
		endif

		if PBUTTONWASZERO = 1 and PBUTTON = 1 then
			PBUTTONWASZERO = 0
			low 2, 4
			if b1 = 2 then
				b1 = 4
			else
				b1 = 2
			endif
			b0 = 0
		endif

		if b0 < 5 then
			high b1
		else
			low b1
		endif

		pause 200

	next b0

	goto main
 

Jeff Haas

Senior Member
vttom, thanks for the suggested code.

I've had a chance to work with Tony's example using an interrupt, and understand the code and have it working. Hopefully I can find time this weekend to try out the others.

Jeff
 
Top