using readadc on a button

Prototype

New Member
hello i was wondering if anyone could point me in the right direction.

im using setint and a interrupt to change modes when the button is released. however i want to use readadc to change through modes nicly. i also want to use the readadc within my interupt.

here is the snippet of the code i have now:
Code:
interrupt:

   do loop while pin2 = 1 'wait for button release 
   mode = mode + 1 & %00000111 
   setint %00000100,%00000100 'pin2 high
return

do
loop
when i debuged the readadc on the button i want to use the values i recieved where 255 when not pressed and when the button was pressed i brought the value down to 0.

heres what i have attempted to combine the readadc.
Code:
interrupt:

   readadc 2, b0
   if b0 < 200 then
   do loop while b0 < 200  
   endif  
   mode = mode + 1 & %00000111 
   setint %00000100,%00000100 
return

do
loop
however the code that i have attempted is incorrect can sombody point me on the correct lines?

thanks
 

westaust55

Moderator
Code:
interrupt:
   do
     readadc 2, b0
  loop while b0 < 200  
   mode = mode + 1 & %00000111 
   setint %00000100,%00000100 
return
I won't ask why you are trying to use READADC for what is seemingly a digital (ON/OFF HIGH/LOW) function
 

westaust55

Moderator
try changing
loop while b0 < 200
to
loop while b0 >= 200

otherwise you may need to give some further description of how the hardware andsoftware works
 

Prototype

New Member
thank you for your help i can now change modes using that the only problem is my modes are now faulty. in the stimulator how would i change modes? imean like would i have to enter a value of 200?

or like you said earlier what would i change to the if

"pin2 = 1 then" part of the code without using readadc with a digital output
 
Last edited:

Prototype

New Member
hmmm.. it seems to be doing the opposite of what i need it to do.
what i am trying to program it do do is:

when the button is pressed and is <= 200 the code should go into the interrupt untill the button is >= 200, where it should come out of the interrupt and into the next mode and so on.

no matter how much i mess with different elements within the code i just cant seen to get it to do that.
 

KMoffett

Senior Member
Why are you trying to use the adc input when you are only looking for 2 states...<200 or >=200? That's basically the definition of a digital input. Are you trying to resolve contact bounce. Or is there something analog that's connected to the button that would be connected to the adc input that you need elsewhere in the program?

ken
 
Last edited:

MartinM57

Moderator
when the button is pressed and is <= 200 the code should go into the interrupt untill the button is >= 200, where it should come out of the interrupt and into the next mode and so on.
I'm afraid that really doesn't make a lot of sense and sounds like a misunderstanding of what interrupts are for - unless I'm (and most here, it seems) are just not understanding what you are trying to do.

Can you explain EXACTLY what you are trying to do - what are these "modes" you talk about, in reality?
 

Prototype

New Member
i have 4 modes that cycle through using setint and a interrupt.
Code:
symbol mode = b0
symbol Led = 4

mode = 0
setint %00000100,%00000100 'pin2 high
do
'---------------------------------------- 
   do				'Mode 0
   loop while mode = 0		'Mode 0
'----------------------------------------
   do				'Mode 1
   high Led			'Mode 1
   pause 25			'Mode 1
   low Led			'Mode 1
   pause 25			'Mode 1				
   loop while mode = 1		'Mode 1
'----------------------------------------
 
   do				'Mode 2
   high Led 			'Mode 2
   pause 100			'Mode 2
   low Led 			'Mode 2
   pause 100         		'Mode 2
   loop while mode = 2		'Mode 2
'----------------------------------------
   do				'Mode 3
   high Led			'Mode 3
   pause 250			'Mode 3
   low Led			'Mode 3
   pause 250			'Mode 3
   loop while mode = 3		'Mode 3
'----------------------------------------
loop

interrupt:    
   do loop while pin2 = 1
   setint %00000100,%00000100 
return
do
loop
what i am trying to achieve is (imagen where in mode0) when the button connected to pin2 is pressed i want the code to go to the interrupt and when the button is released i want the code to go the the next mode (mode1) and so forthe.

the button i am using has the values of 254 when not pressed and when pressed 0.

i though using readadc would make matters better that using do loop while pin2 =1?
 

hippy

Ex-Staff (retired)
I was getting very confused by this thread's "using readadc on a button" similarity with "readadc to change modes in setint?" :)

IN this case you seem to have what you need, except you are not incrementing the 'mode' variable within the interrupt. Return from interrupt and 'mode' will be same as it was.

You need 'mode' to cycle 0, 1, 2, 3, 0 etc so add into the interrupt handler ....

mode = mode + 1 // 4

Forget READADC with the button; it won't make it any easier, just make it more confusing.
 

Prototype

New Member
mode = mode + 1 // 4
thanks for that but i still have the same problem. you have to hold down the button for the LED to blink.

the button that i am using goes low when pressed and is high when not pressed. so i need the code to enter the interup when it detects the button is low and come out of the interrupt into the next mode when it detects the button is high (not pressed)

then it should cycle through that mode untill the button is pressed and is low where it will enter the interrupt again.
 

BeanieBots

Moderator
I was getting very confused by this thread's "using readadc on a button" similarity with "readadc to change modes in setint?" :)
[/qoute]

So was I, so I did a quick and easy check.
Both posters have the same IP, so it's either the same person or two people (at school?) with the same homework.

The code you posted in post #11 plus Hippy's reply in post #12 will give you what you want.
 
Last edited:

Prototype

New Member
not quite homework room mate with a shared project. sorry for the double thread.

the code does slightly give me/us what we want but if i use
Code:
do loop while pin2 = 1
or
Code:
do loop while pin2 = 0
i cannot get the LED to go high and low reapeately in one mode without having to hold the button down.

is there any other way to make the code enter the interrupt when the switch is open and when the switch is closed exit the interrupt into the next mode?
 
Last edited:

MartinM57

Moderator
I haven't looked at the code in detail, but have you heard of "switch bounce" and do you think you might be suffering from it? First sledgehammer approach to minimise the effect of switch bounce is to put a 100nF/0.1uF capacitor from the PICAXE input to ground.

Also, is your switch between the positive supply and the PICAXE or between ground and the PICAXE pin. Either way round, have you got a resistor (10K will do) from the PICAXE pin to "the other supply" - have a look at Manual 3 page 25.

Bouncing switches or missing pull up/down resistors will make your code do all sorts of weird things...
 

Prototype

New Member
thanks for the advice, i introduced the capacitor but still the same, i thing its down to how i word the interrupt,

i cannot seem to make it enter the interrupt when the switch is low and make it come out of the interrupt when the switch is high.

thanks
 

westaust55

Moderator
Please post your entire code

Why you cannot just use a simple digital input is unclear but lets look at the entire "picture"
 

Prototype

New Member
alright here goes:
Code:
symbol mode = b0
symbol Led = 4

mode = 0
setint %00000100,%00000100 'pin2 high
do
'---------------------------------------- 
   do				'Mode 0
   loop while mode = 0		'Mode 0
'----------------------------------------
   do				'Mode 1
   high Led			'Mode 1
   pause 25			'Mode 1
   low Led			'Mode 1
   pause 25			'Mode 1				
   loop while mode = 1		'Mode 1
'----------------------------------------
   do				'Mode 2
   high Led 			'Mode 2
   pause 100			'Mode 2
   low Led 			'Mode 2
   pause 100         		'Mode 2
   loop while mode = 2		'Mode 2
'----------------------------------------
   do				'Mode 3
   high Led			'Mode 3
   pause 250			'Mode 3
   low Led			'Mode 3
   pause 250			'Mode 3
   loop while mode = 3		'Mode 3
'----------------------------------------
loop

interrupt:    
   
    do loop until pin2 = 1
    mode = mode + 1 // 4 
    setint %00000100,%00000100 
   
return
do
loop
 

westaust55

Moderator
For starters change the interrupt routine to:
Code:
interrupt:    
   
    do loop until pin2 = [COLOR="Red"][B]0[/B][/COLOR]
    mode = mode + 1 // 4 
    setint %00000100,%00000100 
   
return
Depending upon you final objectives, the entire code can be reduced to a single simple loop by using the variable mode to pick a delay period

leave it to you to think about but the lines needs are:

SYMBOL delay = b1

LOOKUP mode (1, 25, 100,250), delay

then use PAUSE delay

after midnight here so may look further in the morning
 

Prototype

New Member
Thanks westaust your advice is much aprriceated.

this is what i was trying to explain, even when i change the interrupt to
Code:
do loop until pin2 = 0
i use the simulator and it what i get is it cycling through say mode0 when pin2 is low and then when pin2 is high it enters the interrupt. and exits the interrupt in the next mode (mode1) when pin 2 is low.

whereas i want it to enter the interrupt when pin2 is low and the exit the interrupt when pin2 is high into the next mode.

Thanks
 

hippy

Ex-Staff (retired)
thanks for that but i still have the same problem. you have to hold down the button for the LED to blink.

the button that i am using goes low when pressed and is high when not pressed. so i need the code to enter the interup when it detects the button is low and come out of the interrupt into the next mode when it detects the button is high (not pressed)
You'll need to change the SETINT command so interrupts activates when pin2 is low ( not high as it currently does ).

Hint - SETINT <matchedValue>, <pinMask>

You'll need to change the interrupt routine so it loops while pin2 is low.

Hint - DO : LOOP WHILE pin2 = <level>
 

Prototype

New Member
Hahaa i am liking the hint's very much :) thanks for the hints Hippy i read up on manual 2 setint section and played around with the code and in addition with your hint's i have the code working to how i wanted it :D
 

westaust55

Moderator
Great to read that your code is now worked as desired.

I guess there was confusion over what you were trying to achieve.
Not specifically having a go at you as it is a common problem with questions raised. The moral here is:
make sure that you properly describe what you are trying to do.

For example:
"im using setint and a interrupt to change modes when the button is released."

Is the input with the button pulled high or low
Is the button switch normally open or normally closed.

This is where both a schematic/circuit diagram and the program listing can be helpful.
 

westaust55

Moderator
And as sugegsted last night (well last nioght my time)

Here is a smaller version (down from about 70 to 47 bytes):
Code:
SYMBOL delay = b1
symbol mode = b0
symbol Led = 4

mode = 0
delay =0

setint %00000000,%00000100 'interrupt when pin2 geos low
DO
LOOKUP mode, (0, 25, 100, 250), delay
 IF mode > 0 THEN
   HIGH Led
   PAUSE delay
 ENDIF  
 LOW Led
 PAUSE delay
LOOP   


interrupt:    
   
    do loop until pin2 = 1
    mode = mode + 1 // 4 
    setint %00000000,%00000100 
   
return
Not sure I have the setint bits as you need, so same adjustment as you have already done may need repeating
 

Prototype

New Member
Thank you for the help westaust on trying to reduce the size of the code, i will have a play around with it and see if i can get it smaller as i have added a readadc command to one of my modes.

Thanks.
 
Top