Keypad help.

Captain Haddock

Senior Member
I am looking to use a keypad I have with a ready made pcb but can't figure out how to do the logic, theres 12 buttons on 7 wires, all the wires are connected to +5V via 10K resistors and picaxe pins B.0 - B.6, I can see that no button connects the same two wires but can't get my head round it, it can't be ADC as B.6 isn't an ADC pin (40X2 picaxe).
The PCB was originally for a regular pic and not a picaxe so it's possible pin B.6 was ADC capable on the pic.
Does this configuration match any of the 3x4 keypads available?
Attached is a scan of the button matrix, I have scribbled a few notes on it, any help greatly appreciated.

keypad.jpg
 

nick12ab

Senior Member
Is this still the heating controller where you said that it uses ADC? If each pin of the keypad is connected to a PICAXE pin then it is certainly not ADC but instead it is just a normal scanning circuit (it looks like a normal keypad). It just uses pull-up resistors instead of pull-downs.

Here is some example scanning code for a 4x3 matrix:
Code:
prc_X:    let varA = 15            'Resets the keypad variable so that repeat events do not happen when key is released
        high 1                'Turns on the output connected to the first column
        low 2                    'Turns off the output connected to the second column
        low 3                    'Turns off the output connected to the third column
        if pin0 = 1 then : if varQ = 1 then label_39 : varA = 1 : goto finishcheck : end if        'Checks whether input 0 is high
        if pin1 = 1 then : if varQ = 4 then label_39 : varA = 4 : goto finishcheck : end if        'Checks whether input 1 is high
        if pin2 = 1 then : if varQ = 7 then label_39 : varA = 7 : goto finishcheck : end if        'Checks whether input 2 is high
        if pin3 = 1 then : if varQ = 10 then label_39 : varA = 10 : goto finishcheck : end if    'Checks whether input 3 is high
        low 1                    'Turns off the output connected to the first column
        high 2                'Turns on the output connected to the second column
        low 3                    'Turns off the output connected to the third column
        if pin0 = 1 then : if varQ = 2 then label_39 : varA = 2 : goto finishcheck : end if        'Checks whether input 0 is high
        if pin1 = 1 then : if varQ = 5 then label_39 : varA = 5 : goto finishcheck : end if        'Checks whether input 1 is high
        if pin2 = 1 then : if varQ = 8 then label_39 : varA = 8 : goto finishcheck : end if        'Checks whether input 2 is high
        if pin3 = 1 then : if varQ = 0 then label_39 : varA = 0 : goto finishcheck : end if        'Checks whether input 3 is high
        low 1                    'Turns off the output connected to the first column
        low 2                    'Turns off the output connected to the second column
        high 3                'Turns on the output connected to the third column
        if pin0 = 1 then : if varQ = 3 then label_39 : varA = 3 : goto finishcheck : end if        'Checks whether input 0 is high
        if pin1 = 1 then : if varQ = 6 then label_39 : varA = 6 : goto finishcheck : end if        'Checks whether input 1 is high
        if pin2 = 1 then : if varQ = 9 then label_39 : varA = 9 : goto finishcheck : end if        'Checks whether input 2 is high
        if pin3 = 1 then : if varQ = 12 then label_39 : varA = 12 : goto finishcheck : end if    'Checks whether input 3 is high
        let varQ = 15            'This code only executes if no key is pressed
label_39:    return                'Exits from the keypad-checking procedure
finishcheck:varQ = varA
        return
(varA and varQ are byte variables)

The code above was from a 28X1 so don't forget to change the pin variables.
 

premelec

Senior Member
6R + ADC pin

@CptHad - there's a circuit with 6 resistors in a divider network and using READADC for reading keypads that works well - it has been reviewed on this forum a number of times... it's not just what you have set up but I thought I'd mention it in case you run out of pins...
 

Captain Haddock

Senior Member
Is this still the heating controller where you said that it uses ADC?
Oops I lied about the ADC, assumption being the mother of all c*ck-ups and all that.:eek: It is still the same controller that I'm slowly working through getting each bit to work from a picaxe, I've had to do a bit of re-mapping on the pins due to differences on the chip but it's starting to make sense now, never used a keypad before.
I'll have a go with that scanning code and see how I get on, thanks for that.
 

nick12ab

Senior Member
Oops I lied about the ADC, assumption being the mother of all c*ck-ups and all that.:eek: It is still the same controller that I'm slowly working through getting each bit to work from a picaxe, I've had to do a bit of re-mapping on the pins due to differences on the chip but it's starting to make sense now, never used a keypad before.
I think it would be a good idea to practice with some tactile switches on a breadboard. Going back to my code, it would appear that if two switches were pressed together a direct short between a high output and a low output could be made - and the code was originally made for a keypad with pull-down resistors so it will need lots of modification before you stick it in your heating controller. The outputs shorting problem can be solved either by using input/low states rather than high/low states or by using 1k resistors in series with each keypad control line.

My code does offer anti-repetition functionality that would mean that if a key was held down the procedure would only return its value once and after that it would return the no key pressed value until that key was released. My code also requires that it is executed in a loop constantly when expecting input but this won't be difficult at all to do since after all, the rest of your code will be running in a loop so a simple 'gosub prc_X' will suffice.
 

Captain Haddock

Senior Member
Thanks for the heads up on the shorting issue Nick, I've spotted a glaring error in my original post, they are tied to +5V by 100k reistors not 10k as typed.
It does indeed work out as a regular 3x4 keypad.
 
Last edited:

hippy

Ex-Staff (retired)
Going back to my code, it would appear that if two switches were pressed together a direct short between a high output and a low output could be made - and the code was originally made for a keypad with pull-down resistors so it will need lots of modification before you stick it in your heating controller.
The trick to avoid shorting when multiple keys are pressed is to only assert one keypad row signal at a time, keep the other row signals as input. The row signals shouldn't be controlled by HIGH and LOW but by HIGH ( or LOW ) and INPUT.

While using pull-ups makes code more complicated when thinking in terms of positive logic, it makes hardware easier using negative logic; with the pull-ups, using LOW and INPUT, every input signal becomes an open collector input so it's electrically safe if all row drives are accidentally set to LOW and buttons short outputs to outputs.

Additionally, by setting all row signals LOW a single read of the inputs will tell if any key is pressed; all inputs will be high if not. This allows for very quick keypad scanning such as for a remote control that may wake up periodically and check if any key is pressed and sleep if not. It also simplifies handling looking for all keys released to prepare for a new key press.

By using the internal pull-ups it's possible to create an electrically safe key pad without using any external components other than the keypad itself, no resistors, no diodes ...

http://www.picaxeforum.co.uk/showthread.php?14001-20X2-4x4-keypad-scanner
 

Captain Haddock

Senior Member
Thanks Hippy, you're a top guy.:)
Would I leave the 100k resistors to +V on B.4 B.5 B.6 and remove the rest or let the pullup command take care of it and remove all the resistors?
 

hippy

Ex-Staff (retired)
The advantage in using the internal pull-ups is if not already fitted externally and you want to save a few pennies, board space, or assembly time.

As already fitted I'd say leave them and take the PULLUP command out of any code if present. You'll need them if the PICAXE doesn't have pull-ups on the pins you are using ! If nothing else it saves even having to look in the datasheets to see if the PICAXE does :)
 

hippy

Ex-Staff (retired)
Having taken another look at the photo; it may seem odd that all keypad lines are pulled up, when only the inputs normally would be.

My guess is that this is to allow the controller to be able to handle multiple buttons pushed simultaneously by scanning rows and scanning columns rather than just row or column. This way you can detect two buttons held together, such as "MIN and + or -" and "MAX and + or -".

That makes for more complicated code so I wouldn't worry about that for the time being, and you may not have to depending on how you want to use the buttons.
 

Captain Haddock

Senior Member
I've taken the resistors off of pins B.3 B.4 B.5 B.6 and left them on B.0 B.1 B.2 and commented out the pullup command and it works a treat, thanks Hippy.
Now to work out how to use it usefully, pub first...
 
need help with my keypad

ive used the keypad kit from the picaxe shop the only thing is that ive changed the the chip from an 18 to an 18m2 at the moment ive used this programme but this one unlocks after 5 seconds and i need it to stop when ive put the code again if someone can help me:
#picaxe 18m2

;output 7 - FET to drive solenoid bolt
;output 6 - piezo sounder
;output 4,5 - bicolour LED
;output 3 - row 4
;output 2 - row 3
;output 1 - row 2
;output 0 - row 1

;input 0 - column 1
;input 1 - column 2
;input 2 - column 3

symbol key_pos = b0 ; number of keys pressed
symbol key_value = b1 ; value of key pressed

; *** reset position to zero ***

init:
let dirsB = 255
let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***

scan:
let key_value = 0
let pinsB = %00010001
gosub key_test

let key_value = 3
let pinsB = %00010010
gosub key_test

let key_value = 6
let pinsB = %00010100
gosub key_test

let key_value = 9
let pinsB = %00011000
gosub key_test

goto scan

; *** Score sub procedure. ***
; *** return straight away if no key pressed ***

key_test:
if pinC.0 = 1 then add1
if pinC.1 = 1 then add2
if pinC.2 = 1 then add3
return

; *** key value will already be 0, 3, 6, or 9 ***
; *** so add 1, 2 or 3 to this value ***

add3: let key_value = key_value + 1
add2: let key_value = key_value + 1
add1: let key_value = key_value + 1

; *** Make a beep ***

sound B.6,(60,50)

; *** Now increase position counter by 1 ***
; *** and test for 1st, 2nd 3rd or 4th push ***

let key_pos = key_pos + 1

if key_pos = 1 then test1
if key_pos = 2 then test2
if key_pos = 3 then test3
; if key_pos = 4 then test4

; *** Now test the value for each position individually ***
; *** If value is wrong restart, if correct loop until ***
; *** fourth go. If fourth is correct open lock! ***

; *** Key code is set to 9-3-5-1 ***

test4:
if key_value = 1 then open
goto reset1

test3:
if key_value = 5 then continue
goto reset1

test2:
if key_value = 3 then continue
goto reset1

test1:
if key_value = 9 then continue
goto reset1

; *** Got here so open lock and set LED green for 5 sec ***

open: let pinsB = %10100000
wait 5
goto reset1

; *** Not correct value so reset position counter then return ***

reset1:
let key_pos = 0

; *** Okay so continue by returning back to main loop ***

continue:
return
 

nick12ab

Senior Member
ive used the keypad kit from the picaxe shop the only thing is that ive changed the the chip from an 18 to an 18m2 at the moment ive used this programme but this one unlocks after 5 seconds and i need it to stop when ive put the code again if someone can help me:
Welcome to the PICAXE Forum.

Can you be a bit clearer? It unlocks 5 seconds after you enter the code? You need what to stop?
 
what happens is that once you put the code, it stays activated 5 seconds and after these it returns to the beginig so i need to put the code to activated again, but what i want to do is that when i put thecode it stays activated until the code is pressed again.

Once I have entered the code the keypad activiates,making the LED on the circuit flash. The keypad should continue to be activiated until the code is re-entered to disactivate it. The problem is that with the program above it only activiates for 5 second after the code has been entered and then it goes back to the beginning of the program and I have to start again. I have used the keypad kit from the picaxe store but I have changed the chip to a 18m2, I am required to use this program as other programs tried have not worked for this circuit.
 

nick12ab

Senior Member
I'm not going to write all the code for you (because then you won't learn much and mainly because you've used far too many labels and I can't easily follow the code), but what you have to do is get rid of the 'wait 5' and also just toggle the solenoid and bicolour LED pins when the code is entered rather than set them with the pinsB variable.

Then whenever you set the pinsB variable to something for the keypad scanning you need to use an OR bit mask in order to retain the solenoid/LED state and put 0 for those pins in the variable so 'let pinsB = %00010010' becomes 'let pinsB = pinsB | %00000010'.

Finally, always use [code][/code] tags around long bits of code in order to enable easy access to indented code. Failure to use the tags mean that the only way to get the indents is to click Reply with Quote and copy and paste the code from there and it also looks bad.
 
Thank you for your reply i understand I have to learn and I am trying to make the changes you explained. I am a beginner using this program and have probably made it more complicated than necessary. I have tried taking the wait 5 off,can you give me a bit more help with "just toggle the solenoid" I dont understand this phrase, can you give me a little more info and I will try to make the corrections.

Thanks
 
im doing a motorbike alarm and at the moment ive done the keypad
Code:
#picaxe 18m2

;output 7 - FET to drive solenoid bolt
;output 6 - piezo sounder
;output 4,5 - bicolour LED
;output 3 - row 4
;output 2 - row 3
;output 1 - row 2
;output 0 - row 1

;input 0 - column 1
;input 1 - column 2
;input 2 - column 3

symbol key_pos = b0    ; number of keys pressed
symbol key_value = b1    ; value of key pressed

; *** reset position to zero ***

init:    
    let dirsB = 255
    let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***


;*********************lock close,enter code to open ***************
scan:
    let key_value = 0
    let pinsB = %00010001
    gosub key_test

    let key_value = 3
    let pinsB = %00010010
    gosub key_test

    let key_value = 6
    let pinsB = %00010100
    gosub key_test

    let key_value = 9
    let pinsB = %00011000
    gosub key_test

    goto scan

; *** Score sub procedure. ***
; *** return straight away if no key pressed ***

key_test:
    if pinC.0 = 1 then add1
    if pinC.1 = 1 then add2
    if pinC.2 = 1 then add3
    return

; *** key value will already be 0, 3, 6, or 9 ***
; *** so add 1, 2 or 3 to this value *** 

add3:    let key_value = key_value + 1
add2:    let key_value = key_value + 1
add1:    let key_value = key_value + 1

; *** Make a beep ***

    sound B.6,(60,50)

; *** Now increase position counter by 1 ***
; *** and test for 1st, 2nd 3rd or 4th push ***

    let key_pos = key_pos + 1

    if key_pos = 1 then test1
    if key_pos = 2 then test2
    if key_pos = 3 then test3
     if key_pos = 4 then test4 
    
; *** Now test the value for each position individually ***
; *** If value is wrong restart, if correct loop until ***
; *** fourth go. If fourth is correct open lock! ***

; *** Key code is set to 9-3-5-1 ***

test4:
    if key_value = 1 then open
    goto reset1

test3:
    if key_value = 5 then continue
    goto reset1

test2:
    if key_value = 3 then continue
    goto reset1

test1:
    if key_value = 9 then continue
    goto reset1

; *** Got here so open lock and set LED green  ***

open:    let pinsB = %10100000
    'wait 5
    goto init2 

; *** Not correct value so reset position counter then return ***

reset1:
    let key_pos = 0

; *** Okay so continue by returning back to main loop ***

continue:
    return
    




'****************** lock open, enter code to close***********    
init2:    
    
    let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***

scan2:
    let key_value = 0
    let pinsB = %10100001
    gosub key_test2

    let key_value = 3
    let pinsB = %10100010
    gosub key_test2

    let key_value = 6
    let pinsB = %10100100
    gosub key_test2

    let key_value = 9
    let pinsB = %10101000
    gosub key_test2

    goto scan2

; *** Score sub procedure. ***
; *** return straight away if no key pressed ***

key_test2:
    if pinC.0 = 1 then add12
    if pinC.1 = 1 then add22
    if pinC.2 = 1 then add32
    return

; *** key value will already be 0, 3, 6, or 9 ***
; *** so add 1, 2 or 3 to this value *** 

add32:    let key_value = key_value + 1
add22:    let key_value = key_value + 1
add12:    let key_value = key_value + 1

; *** Make a beep ***

    sound B.6,(60,50)

; *** Now increase position counter by 1 ***
; *** and test for 1st, 2nd 3rd or 4th push ***

    let key_pos = key_pos + 1

    if key_pos = 1 then test12
    if key_pos = 2 then test22
    if key_pos = 3 then test32
     if key_pos = 4 then test42 
    
; *** Now test the value for each position individually ***
; *** If value is wrong restart, if correct loop until ***
; *** fourth go. If fourth is correct close lock! ***

; *** Key code is set to 9-3-5-1 ***

test42:
    if key_value = 1 then close2
    goto reset12

test32:
    if key_value = 5 then continue2
    goto reset12

test22:
    if key_value = 3 then continue2
    goto reset12

test12:
    if key_value = 9 then continue2
    goto reset12

; *** Got here so open lock and set LED red ***

close2:    let pinsB = %00010000
    'wait 5
    goto init

; *** Not correct value so reset position counter then return ***

reset12:
    let key_pos = 0

; *** Okay so continue by returning back to main loop ***

continue2:
    return

and know i need to add vibration sensor to the circuit, can someone tell me how can i do it in this same program
thank you
russell
 
Last edited by a moderator:

nick12ab

Senior Member
and know i need to add vibration sensor to the circuit, can someone tell me how can i do it in this same program
thank you
russell
What vibration sensor do you want to add? Does it just output a high or low signal depending on the amount of vibration?

If that is the case, then use an if statement after the scan label to check if the pin the sensor is connected to is at the activated state, and if it is, make the output pin the sounder is connected to high. Then after the init2 label make the pin the sounder is connected to low. This should mean that the alarm will stop sounding once the code is entered.
 
scan:
let key_value = 0
let pinsB = %00010001
gosub key_test

let key_value = 3
let pinsB = %00010010
gosub key_test

let key_value = 6
let pinsB = %00010100
gosub key_test

let key_value = 9
let pinsB = %00011000
gosub key_test

if pin3= 1 then gosub alarm
goto scan

alarm:

high 0
wait 2
low 0
goto scan
this is what ive done for the vibration sensor but i dont know to do ''and if it is, make the output pin the sounder is connected to high. Then after the init2 label make the pin the sounder is connected to low''
if you can help me with that part and check if the programming for the sensor its okay as havent had time to test it.
 

nick12ab

Senior Member
this is what ive done for the vibration sensor but i dont know to do ''and if it is, make the output pin the sounder is connected to high. Then after the init2 label make the pin the sounder is connected to low''
if you can help me with that part and check if the programming for the sensor its okay as havent had time to test it.
You haven't told me what sensor you are using. Assuming that when vibration is detected, it outputs a high pulse then use this code in the keypad-checking procedure that is constantly executed:
Code:
if armed = 1 and sensor = 1 then alarm
alarm appears to be the part of your code that sounds the alarm. Use symbol definitions to define the pin variable for sensor and the bit variable for armed - this bit variable indicated whether the alarm is armed or not.

P.S. In your code:
Code:
if pin3= 1 then gosub alarm
goto scan

alarm:

high 0
wait 2
low 0
goto scan
you've used gosub alarm but the alarm sub uses a goto at the end instead of a return so you'll eventually get a stack overflow.
 
so do i put ''if armed = 1 and sensor = 1 then alarm'' in the scan label. i know what you mean, as i need let the chip know when the sensor goes but im not sure where to put this commands.
 
what will be my bit variable
symbol armed=
symbol sensor= pin3
symbol key_pos = b0 ; number of keys pressed
symbol key_value = b1 ; value of key pressed

; *** reset position to zero ***

init:
let dirsB = 255
let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***


;*********************lock close,enter code to open ***************
scan:
let key_value = 0
let pinsB = %00010001
gosub key_test

let key_value = 3
let pinsB = %00010010
gosub key_test

let key_value = 6
let pinsB = %00010100
gosub key_test

let key_value = 9
let pinsB = %00011000
gosub key_test
'********************* checks the vibration sensor *********************
'the sensor is conected to this pin
if armed = 1 and sensor = 1 then alarm
goto scan

alarm:

high 0 ' switch output on
wait 2 'wait for 2 seconds
low 0 'turns the output off
goto scan
 

nick12ab

Senior Member
Is that your complete code there? I cannot see how that code has armed and disarmed modes.

If you have an LED that lights continuously when the alarm is armed then just use the pin variable for that LED as the bit variable.
 
no what i mean when i use there ''if armed = 1 and sensor = 1 then alarm''
and i put:
symbol armed= 5
symbol sensor= pin3
my LED doesnt stop flashing when it should ony stay red
 

nick12ab

Senior Member
So this one is your complete code?
Code:
#picaxe 18m2

;output 7 - FET to drive solenoid bolt
;output 6 - piezo sounder
;output 4,5 - bicolour LED
;output 3 - row 4
;output 2 - row 3
;output 1 - row 2
;output 0 - row 1

;input 0 - column 1
;input 1 - column 2
;input 2 - column 3

symbol key_pos = b0    ; number of keys pressed
symbol key_value = b1    ; value of key pressed

; *** reset position to zero ***

init:    
    let dirsB = 255
    let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***


;*********************lock close,enter code to open ***************
scan:
    [B]if sensor = 1 then alarm[/B]
    let key_value = 0
    let pinsB = %00010001
    gosub key_test

    let key_value = 3
    let pinsB = %00010010
    gosub key_test

    let key_value = 6
    let pinsB = %00010100
    gosub key_test

    let key_value = 9
    let pinsB = %00011000
    gosub key_test

    goto scan

; *** Score sub procedure. ***
; *** return straight away if no key pressed ***

key_test:
    if pinC.0 = 1 then add1
    if pinC.1 = 1 then add2
    if pinC.2 = 1 then add3
    return

; *** key value will already be 0, 3, 6, or 9 ***
; *** so add 1, 2 or 3 to this value *** 

add3:    let key_value = key_value + 1
add2:    let key_value = key_value + 1
add1:    let key_value = key_value + 1

; *** Make a beep ***

    sound B.6,(60,50)

; *** Now increase position counter by 1 ***
; *** and test for 1st, 2nd 3rd or 4th push ***

    let key_pos = key_pos + 1

    if key_pos = 1 then test1
    if key_pos = 2 then test2
    if key_pos = 3 then test3
     if key_pos = 4 then test4 
    
; *** Now test the value for each position individually ***
; *** If value is wrong restart, if correct loop until ***
; *** fourth go. If fourth is correct open lock! ***

; *** Key code is set to 9-3-5-1 ***

test4:
    if key_value = 1 then open
    goto reset1

test3:
    if key_value = 5 then continue
    goto reset1

test2:
    if key_value = 3 then continue
    goto reset1

test1:
    if key_value = 9 then continue
    goto reset1

; *** Got here so open lock and set LED green  ***

open:    let pinsB = %10100000
    'wait 5
    goto init2 

; *** Not correct value so reset position counter then return ***

reset1:
    let key_pos = 0

; *** Okay so continue by returning back to main loop ***

continue:
    return
    




'****************** lock open, enter code to close***********    
init2:    
    
    let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***

scan2:
    let key_value = 0
    let pinsB = %10100001
    gosub key_test2

    let key_value = 3
    let pinsB = %10100010
    gosub key_test2

    let key_value = 6
    let pinsB = %10100100
    gosub key_test2

    let key_value = 9
    let pinsB = %10101000
    gosub key_test2

    goto scan2

; *** Score sub procedure. ***
; *** return straight away if no key pressed ***

key_test2:
    if pinC.0 = 1 then add12
    if pinC.1 = 1 then add22
    if pinC.2 = 1 then add32
    return

; *** key value will already be 0, 3, 6, or 9 ***
; *** so add 1, 2 or 3 to this value *** 

add32:    let key_value = key_value + 1
add22:    let key_value = key_value + 1
add12:    let key_value = key_value + 1

; *** Make a beep ***

    sound B.6,(60,50)

; *** Now increase position counter by 1 ***
; *** and test for 1st, 2nd 3rd or 4th push ***

    let key_pos = key_pos + 1

    if key_pos = 1 then test12
    if key_pos = 2 then test22
    if key_pos = 3 then test32
     if key_pos = 4 then test42 
    
; *** Now test the value for each position individually ***
; *** If value is wrong restart, if correct loop until ***
; *** fourth go. If fourth is correct close lock! ***

; *** Key code is set to 9-3-5-1 ***

test42:
    if key_value = 1 then close2
    goto reset12

test32:
    if key_value = 5 then continue2
    goto reset12

test22:
    if key_value = 3 then continue2
    goto reset12

test12:
    if key_value = 9 then continue2
    goto reset12

; *** Got here so open lock and set LED red ***

close2:    let pinsB = %00010000
    'wait 5
    goto init

; *** Not correct value so reset position counter then return ***

reset12:
    let key_pos = 0

; *** Okay so continue by returning back to main loop ***

continue2:
    return
You're using two separate keypad check routines so you can get rid of the arming = 1 part from the IF statement and only have the IF statement in the keypad checking bit for disarming the alarm like this:
Code:
#picaxe 18m2

;output 7 - FET to drive solenoid bolt
;output 6 - piezo sounder
;output 4,5 - bicolour LED
;output 3 - row 4
;output 2 - row 3
;output 1 - row 2
;output 0 - row 1

;input 0 - column 1
;input 1 - column 2
;input 2 - column 3

symbol key_pos = b0    ; number of keys pressed
symbol key_value = b1    ; value of key pressed

; *** reset position to zero ***

init:    
    let dirsB = 255
    let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***


;*********************lock close,enter code to open ***************
scan:
    let key_value = 0
    let pinsB = %00010001
    gosub key_test

    let key_value = 3
    let pinsB = %00010010
    gosub key_test

    let key_value = 6
    let pinsB = %00010100
    gosub key_test

    let key_value = 9
    let pinsB = %00011000
    gosub key_test

    goto scan

; *** Score sub procedure. ***
; *** return straight away if no key pressed ***

key_test:
    if pinC.0 = 1 then add1
    if pinC.1 = 1 then add2
    if pinC.2 = 1 then add3
    return

; *** key value will already be 0, 3, 6, or 9 ***
; *** so add 1, 2 or 3 to this value *** 

add3:    let key_value = key_value + 1
add2:    let key_value = key_value + 1
add1:    let key_value = key_value + 1

; *** Make a beep ***

    sound B.6,(60,50)

; *** Now increase position counter by 1 ***
; *** and test for 1st, 2nd 3rd or 4th push ***

    let key_pos = key_pos + 1

    if key_pos = 1 then test1
    if key_pos = 2 then test2
    if key_pos = 3 then test3
     if key_pos = 4 then test4 
    
; *** Now test the value for each position individually ***
; *** If value is wrong restart, if correct loop until ***
; *** fourth go. If fourth is correct open lock! ***

; *** Key code is set to 9-3-5-1 ***

test4:
    if key_value = 1 then open
    goto reset1

test3:
    if key_value = 5 then continue
    goto reset1

test2:
    if key_value = 3 then continue
    goto reset1

test1:
    if key_value = 9 then continue
    goto reset1

; *** Got here so open lock and set LED green  ***

open:    let pinsB = %10100000
    'wait 5
    goto init2 

; *** Not correct value so reset position counter then return ***

reset1:
    let key_pos = 0

; *** Okay so continue by returning back to main loop ***

continue:
    return
    




'****************** lock open, enter code to close***********    
init2:    
    
    let key_pos = 0

; *** now scan each row in turn ***
; *** by setting only 1 row (and LED) high ***
; *** if a switch is hit jump call score sub below ***

scan2:
    let key_value = 0
    let pinsB = %10100001
    gosub key_test2

    let key_value = 3
    let pinsB = %10100010
    gosub key_test2

    let key_value = 6
    let pinsB = %10100100
    gosub key_test2

    let key_value = 9
    let pinsB = %10101000
    gosub key_test2

    goto scan2

; *** Score sub procedure. ***
; *** return straight away if no key pressed ***

key_test2:
    if pinC.0 = 1 then add12
    if pinC.1 = 1 then add22
    if pinC.2 = 1 then add32
    return

; *** key value will already be 0, 3, 6, or 9 ***
; *** so add 1, 2 or 3 to this value *** 

add32:    let key_value = key_value + 1
add22:    let key_value = key_value + 1
add12:    let key_value = key_value + 1

; *** Make a beep ***

    sound B.6,(60,50)

; *** Now increase position counter by 1 ***
; *** and test for 1st, 2nd 3rd or 4th push ***

    let key_pos = key_pos + 1

    if key_pos = 1 then test12
    if key_pos = 2 then test22
    if key_pos = 3 then test32
     if key_pos = 4 then test42 
    
; *** Now test the value for each position individually ***
; *** If value is wrong restart, if correct loop until ***
; *** fourth go. If fourth is correct close lock! ***

; *** Key code is set to 9-3-5-1 ***

test42:
    if key_value = 1 then close2
    goto reset12

test32:
    if key_value = 5 then continue2
    goto reset12

test22:
    if key_value = 3 then continue2
    goto reset12

test12:
    if key_value = 9 then continue2
    goto reset12

; *** Got here so open lock and set LED red ***

close2:    let pinsB = %00010000
    'wait 5
    goto init

; *** Not correct value so reset position counter then return ***

reset12:
    let key_pos = 0

; *** Okay so continue by returning back to main loop ***

continue2:
    return
 
ive done a subroutine
scan:
if sensor = 1 then alarm
let key_value = 0
let pinsB = %00010001
gosub key_test

let key_value = 3
let pinsB = %00010010
gosub key_test

let key_value = 6
let pinsB = %00010100
gosub key_test

let key_value = 9
let pinsB = %00011000
gosub key_test
alarm:
high C.4
high B.6
wait 65
low C.4
low C.6
goto scan
but i get as error ''Error: Pin C.4 is input only'' when my ssensor is conected as an input
 

hippy

Ex-Staff (retired)
i get as error ''Error: Pin C.4 is input only'' when my ssensor is conected as an input
That would seem to be a correct error as you are using "high C.4" and "low C.4", when C.4 is input only ( download cable Serial In ) on an 18M2.
 

Buzby

Senior Member
In your routine you have C.4 being driven high and low as an output :

high C.4
high B.6
wait 65
low C.4

so you will get a warning.
 
Top