scanning multiple input pins

sghioto

Senior Member
Lets say I have a Picaxe chip with 15 seperate inputs. All input pins will be pulled high through pullup resistors. I want to scan all inputs of course and each input that goes low will "gosub" some routine. I know I can use "if pin0 = 0 then gosub routine" and so on for each input, but is there a more efficient way to do this?

Steve G
 

BCJKiwi

Senior Member
Let b1=pins
reads status of input port into b1

pins is not listed as a command in the manual but is discussed on page 13 and following of Manual2.
However this appears only to be useful for the standard input port(s). There are some variations like
Let b1=pinsB
for the 28X1
 
Last edited:

moxhamj

New Member
How about
let b0=pins
select case b0
case 1
gosub xxx
case 2
gosub xxx
case 4
case 8
gosub xxx


endselect

But this only works if only one pin is high at any time. If the two least sig bits were high at the same time that would correspond to number 3 which wouldn't match anything. If more than one pin is high then you need to test individual bits

let b0=pins
if bit0=1 then
gosub xxx
endif
if bit1=1 then
gosub yyy
endif

What are you doing with the input data? Sometimes there are other cunning optimisations.
 
Last edited:

sghioto

Senior Member
Well I'm not doing anything with the input data. Actually this was a question on another forum and after over 150 views and not a single response I was curious myself how the code might be optimized. In this case I'll assume only one input is low at any given time.

Steve G
 

westaust55

Moderator
Presuming that we are also wishing to look for multiple key presses then to identify which of the 65536 permutations use:

Code:
main: PEEK $07,b5 ; equivalent to "b0 = portc pin" 
      w1 =b5*256+ pins

      ON w1 GOSUB a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15 ; 65536 options :-))))
      GOTO main
      
a15:b5 = b5 + 1  ; commands here is just a dummy line for each destination for gosub

a14:b5 = b5 + 1 

a13:b5 = b5 + 1 

a12:b5 = b5 + 1 

a11:b5 = b5 + 1 

a10:b5 = b5 + 1 

a9:b5 = b5 + 1 

a8:b5 = b5 + 1 

a7:b5 = b5 + 1 

a6:b5 = b5 + 1 

a5:b5 = b5 + 1 

a4:b5 = b5 + 1 

a3:b5 = b5 + 1 

a2:b5 = b5 + 1 

a1:b5 = b5 + 1

a0: b5 = b5   
    
   
   return

and if you only allow one pin at a time to be activated then use:
Code:
main: PEEK $07,b0 ; equivalent to "b0 = portc pin" 
      w3 =b0*256+ pins
      b3 = 0
for   b1 = 1 to 16
      b2 = w3 AND 1
      if b2 = 1 then
      b3 = b1
      endif
      w3=w3>>1
      next b1
      on b3 gosub op0, op1, op2, ...... ,opt16
:
:
:
 
Last edited:

hippy

Technical Support
Staff member
Assuming you call the same routine for all pins going low ...

Code:
w0 = ? ' Read 16-bits of input pins
For b4 = 0 To 15
  If bit0 = 0 Then : Gosub MySub : End If
  w0 = w0 / 2
Next
The 'MySub' routine knows which pin it was which went low because pin number is held in 'b4'.

If you wanted a bit mask which showed which bit it was then that's quite easy to add as well ...

Code:
w0 = ? ' Read 16-bits of input pins
w1 = $001
For b4 = 0 To 15
  If bit0 = 0 Then : Gosub MySub : End If
  w0 = w0 / 2
  w1 = w1 * 2
Next
If you didn't want to dedicate 'w0' / 'bit0' to holding pins then ...

Code:
w6 = ? ' Read 16-bits of input pins
For b4 = 15 To 0 Step -1
  If w6 < $8000 Then : Gosub MySub : End If
  w0 = w0 * 2
Next
 
Last edited:

westaust55

Moderator
To avoid having to go thru a for next loop 16 times:
if b3 = 0 no input was active otherwise you have a value 1 to 16 equating to bit/pin pressed

Code:
main: PEEK $07,b0 ; equivalent to "b0 = portc pin" 
       w3 =b0*256+ pins
       b1 = 1
       do b2 = w3 AND 1 
          if b2 = 1 then
            b3 = b1
          endif
          b1 = b1+1
          w3 = w3 >> 1
       loop until b3>0 OR w3=0
      
       on b3 gosub op0, op1, op2, ...... ,opt16
 
Last edited:
Top