Need a bit of help making a double knock input

Hi

Have an alarm circuit day time buzzer only, night time buzzer and lights. All works great for a single input device. I now have a sensor that provides a pulse each time it is triggered.

I would like the circuit to count if it is triggered two or more times in a 15 second period and then go into alarm.

If no second trigger reset and start again.

Thought I had it with attached script but off the simulator and in real life if input is left on it counts round the loop twice and then goes into alarm.

Any help would be much appreciated, it would be great to be able to increase the input count to 3 etc.

Also if anyone can tell me where to find the "greater than or equal to" and "less than or equal to" signs I would be most grateful


Code:
[code]
start0:
#Picaxe18M2
 
let dirsB = %11111111 ; sets B to outputs 
let pinsb = %11111111
pause 1000
let pinsb = %00000000 ;start up sequence
pause 1000
let pinsb = %11111111
pause 500
let pinsb = %00000000
pause 500
let pinsb = %11111111 
pause 250
let pinsb = %00000000
pause 250 
let pinsb = %11111111
pause 100
let pinsb = %00000000  
let b7 = pinC.6 		; double knock input
 
 Main:  
	b7=0	; clear the input counter

do while b8 < 30	;15 second input window for two knocks
      
	debug		
	pause 50	 	
  
	readadc C.0,b2  	; read an analogue value for photo transistor
 	
 	if pinc.6 = 1 then  inc b7 endif; double knock input
	pause 100; debounce
	
	if  b2>55 and b7 > 1 then gosub buzz  ;daytime
	
	if b2=55 and b7 = 1 then gosub lights  ;night
	
	if b2 < 55 and b7 > 1 then gosub lights ; nighttime
	
	pause 500	;loop time
	
	inc b8
	
	loop 
	
	b8=0

goto main

buzz: ;on for 5 secs 

	high b.0, b.2 ; buzzers on
	
	debug 
	
	for b5 = 0 to 5  
	pause 1000
	next b5
	
	low b.0, b.2 ;buzzers off 
	b7 = 0 	;reset counter
	b8 = 0 	; reset counter

return 
 

lights:; on for 4 mins
	high b.1, b.3,b.0, b.2 ;lights and buzzers on
	
	debug
	
	for b5 = 0 to 3  		; bleeper on time
	pause 1000
	next b5
	
	low b.0, b.2		; buzzers off

	for b6 = 0 to 5  ; lights on time normally 240
	pause 1000
	next b6
	low b.1, b.3	;lights off
	b7 = 0	;reset counter
	b8 =0		;reset counter

return
[/CODE]
 
The manual is where I started and this would work for me perfectly but:

The stumbling block is in my lack of programming ability to get this to reset the variable to 0 every 15 seconds if it has not received a second trigger. So the input or variable is only acted up on if it if triggered 2 or more times in 15 seconds.

If it is triggered twice but with say 20 seconds or longer apart then the inputs are ignored and 15 seconds after the last single trigger it all goes back to 0 waiting again.

With my script if the input stays on for two cycles of the loop a second input is counted and so the program operates.

The problem is the ability for the program to keep clearing itself if only one input is received.

For the symbols is the equals not part of the gradient normally, if this is how you write it in Picaxe that answers why I have not been able to find them.
 
To save confusion it is a switch opening or closing a number of times.

Is it possible to demonstrate how to save an input value to a byte and then be able to reset the value after a period of time, but do this repeatedly.

Depending on the value an action can occur or not.

If someone can demonstrate the or a way of doing this I can then adapt it to my script.

This would make a simple switch have a double knock effect before operating the program.

The number of knocks and the time window which they occur in are adjusted to the device and its position.
 

geoff07

Senior Member
Your prog was hard to follow but this may be the heart of the matter:

pseudo code (making a few assumptions due to lack of schematic):
Code:
do
       trigger_count = 0
       time = 0
       do
       select trigger_count
            case 0
               inc trigger_count
            case 1 
                call twice_triggered_in_15secs
       endselect
       loop until time=15
loop
 
Last edited:

boriz

Senior Member
I coded a solution to a similar question a few years ago. Based upon a 'leaky bucket' algorithm. It's on the forum somewhere. I'll look for it when I have time.
 

boriz

Senior Member
Found it. Updated it a bit.

Code:
symbol water=w0
start:
do
	pause 5
	if pin1=1 then
		water=water+3000
		do:loop until pin1=0
	elseif water>0 then
		dec water
	endif
loop until water>3000
'your code here
goto start
Works a bit like this. Imagine...

A 1L bucket of water has a hole in the bottom. The full bucket takes 15 seconds to empty. At any time you can push a button which adds 1L of water. The bucket starts empty, you press the button once, it fills to the brim and 15 seconds later it's empty again. If at any time during that 15 seconds you push the button again, the water will overflow.

The program loop checks the button (on pin1) and for overflow, every 5mS. Their are 3000 5mS intervals in 15 seconds. When the button is not pressed, the Water variable decrements by one each pass through the loop. Pressing the button adds 3000 to the Water variable, and should nothing else happen, Water will count down to zero in 15 seconds. If the button is pressed again before Water is zero, it will be greater than 3000 and exit the loop to execute the rest of the program.

It's about as minimal as I could make it, and it does have a flaw. The countdown will be suspended until the button is released, extending the 15 second interval by however long the button was held down. This may not be a problem, but if it is, I can fix it at the expense of using an additional variable and slightly more complicated code.

It could be tweaked for any number of events in any interval.
 

westaust55

Moderator
Difficult to follow the program on a small screen but you seem to be using a variable and incrementing in a loop for timing purposes.
As you have an M2 part, why not consider the "time" system variable to check for an expired duration from a first pulse if no further pulse received in the allotted time.
 

boriz

Senior Member
Good idea. Never used TIME before.

Code:
time=15
do
	if pin1=1 then
		do: loop until pin1=0
		if time>15 then
			time=0
		else
			exit
		endif
	endif
loop
This works better than the original code, and uses no (user) variables at all :)
 

Paix

Senior Member
You have it right e.

Mark, you are thinking about mathematical symbols where
> < both have an underscore to indicate greater than or equal and less than or equal., but in general computing terms it is >= and <=, in the same way that we use * for multiplication and != or <> for inequality.

Of course, it won't catch on. The mathematical way of expressing greater than and less than (a range) really makes my brain hurt as it is not actually intuitive to my non-mathematical noggin. :)

By now all should be eminently clear and the code sort of sorted too. Shriek, it didn't need sorted, it needed fixed . . . ho hum!
 
Thanks for making the symbols clear it really is easy, once you understand.

Tried the code snips; my simulator does not like "call" tried to look it up but found nothing, "time" I could not get to show itself for debugging so used a variable instead as this allowed me to see it operating with out having to hope it was working. "Time" I could not find in the manuals or in BASIC commands but found the info in the forums.

Any way from the various help I have now rewritten the script and it works how I need it to. All messages about being hard to read are noted and hopefully addressed in the latest version.

What most of you have to remember is, "what you know, a great many of us are yet to learn".

Thanks for patience and help.

Mark

P.S. if there are ways to tidy up the script I am always willing to learn. The initial on and off pulsing section I find useful for testing on site and checking that the system does not crash.


Code:
start0:
#picaxe18m2 ;Double knock input circuit switching buzzer and lights 
 
let dirsB = %11111111 ; sets B to outputs 
let pinsb = %11111111
pause 1000
let pinsb = %00000000	; gives outputs a test
pause 1000
let pinsb = %11111111
pause 500
let pinsb = %00000000
pause 500
let pinsb = %11111111  
pause 250
let pinsb = %00000000
pause 250
let pinsb = %11111111 
pause 100
let pinsb = %00000000 

symbol ldr_ 		= C.0 	; LDR to + leave 10k to 0v
symbol timepot	 	= C.1		; potentiometer 
symbol alarm_input 	= pinc.2	; alarm input open Collector 
symbol lights_relay 	= b.0		; Output for light relay
symbol buzzer 		= b.1		; output for sounders 
symbol night_or_day	= b0
symbol lights_on_time 	= b1
symbol alarm_tripped 	= b2
symbol DKloop		= b3		; time window for 2nd knock
symbol Buzzing		= b4		; buzz time
symbol illuminated	= b5		; lights time
symbol alarm_loops	= W1		; contain b2 & b3

 




main:

	alarm_loops = 0

	do				; loop waiting for single trigger
	
		readadc ldr_ , night_or_day
		readadc timepot , lights_on_time
	
		if alarm_input = 0 then inc alarm_tripped endif   
	
		pause 10
	
	loop while alarm_tripped = 0 


	do 				; Window for 15 seconds waiting for second knock
		pause 1000 		; wait for first i/p to clear
		 	
  		if alarm_input = 0 then inc alarm_tripped endif	; second Knock
		
		inc DKloop 
	
		pause 100; debounce  
	 
	
		if night_or_day => 55 and alarm_tripped => 2 then goto buzz  ;daytime
		if night_or_day < 55 and alarm_tripped => 2 then goto lights ; nighttime
	
		
	
	loop while DKloop < 15 
	 
		alarm_loops = 0		; resets alarm loops
	 
	
goto main 



buzz: ;on for 5 secs sounder circuit

	high buzzer 
	
		for buzzing = 0 to 5  
		pause 1000
		next buzzing
	
	low buzzer 
	 
		alarm_loops = 0		; resets alarm loops
	 

goto main 
 

lights:						; on for time set by potentiometer
	high buzzer , lights_relay
	
		for buzzing = 0 to 3    		; bleeper on time
		pause 1000
		next buzzing
	
	low buzzer

		for illuminated = 0 to lights_on_time  ; lights on time
		pause 10						; set to 1000 for seconds
		next illuminated
	
	low buzzer , lights_relay
	
		alarm_loops = 0		;resets alarm loops
	

goto main
 

eclectic

Moderator
" my simulator does not like "call" tried to look it up but found nothing"

Use the PDF Find on Manual 2.

It's there.

e
 
Top