ADC Channel Numbers

piclt

Member
input 8,9,1,2,4,5,6,7
main:
for b0 = 0 to 7
lookup b0,(8, 9, 1, 2, 4, 5, 6, 7),b8
readadc b8, b7
if b8 = value do something.....
next b0

I have used this type of program to read list of analog inputs. The manual say readadc channel, variable.?
What are channel numbers...??
The numbers I used above are for the pins in the line below on an 18M2
;lookup b0,(c.0, c.1, b.1, b.2, b.4, b.5, b.6, b.7),b8

Is there an equivalent way of reading a list of digital inputs...... They would be value 1 or value 0. ....?
 
Last edited:

piclt

Member
Ok, more numbers to remember..?? for readadc inputs etc...
Use b0 = pinsB type of command to read inputs
This for digital inputs..... OK read it into variable then see what bits are high or low..??
I used b0 for B port and b1 for C port etc.
C.0 and C.1 are pins 8 and 9 and called bit8 and bit9 when sertxd to terminal. also can use pinC.0 etc.
These are actually bit0 and bit1 of variable b1...... how do I print that out on sertxd.
The command....... if b1 bit 0 clear then...... is OK for an if statement but b1 bit0 or b1.0 not ok for setexd....???


sertxd("Value C.0 C.1 B.3 >>> ",#pinC.0," .. ",#bit9," .. ",#bit3,13,10)
 

AllyCat

Senior Member
Hi,
...... if b1 bit 0 clear then...... is OK for an if statement
Is it? I thought that the IF bn bitn CLEAR ... etc. is an X2 construct only?
For M2s it's for example: IF bit9 = 0 ...... for variables b0 to b3 only (bit0 to bit23) which you can print with SERTXD(#bit9,.....) etc.

Cheers, Alan.
 

piclt

Member
Yes, but how do I do a numerical list of pin values for digital inputs.
;readadc b8, b7 seems to work OK in for/next loop with lookup for analog
probably because of it uses adc channel nums......
for b10 = 0 to 9
lookup b10,(c.0, c.1, b.0, b.1, b.2, b.3, b.4, b.5, b.6, b.7),b8
readadc b8, b7
and print out list sertxd("Pin list...", #b10, "..pin num..",#b8," ..Value.. ",#b7,13,10)
But for Digital....???
for b10 = 0 to 9
"what goes in to print pin value (0 or 1) instead of #b7 that can be enumerated instead of fixed for a pin"
next b10
 

piclt

Member
I think this works...... need 2 lookup tables one to get pin numbers and 2nd to get pin values......
lookup b10,(c.0, c.1, b.0, b.1, b.2, b.3, b.4, b.5, b.6, b.7),b8
lookup b10,(pinc.0, pinc.1, pinb.0, pinb.1, pinb.2, pinb.3, pinb.4, pinb.5, pinb.6, pinb.7),b7
sertxd("Pin list...", #b10, "..pin num..",#b8," ..Value.. ",#b7,13,10)
but maybe someone knows a better way....
Sorry for causing the hassle......... BT always said it is good to talk...! ! ! :D
 

AllyCat

Senior Member
Hi,

With M2 chips, only registers b0 to b3 are directly bit-addressable. Personally, in my programs I nearly always reserve b0 for "Global Flags" (8 off = bit0 to bit7), b1 as a "Temporary/Local Byte" and b2 - b3 (w1) as a "Temporary/Local Word", for when bit-addressing is required or to pass data to/from standardised subroutines, etc..

So to show all the bits of any particular byte (or port) I would generally use something like :
Code:
b1 = b10     ; Or any desired target byte, etc.
b2 = 10       ; Optional if you want to quote the source register
GOSUB  showbits
;   ....
end
showbits:
     SERTXD ( cr , lf , "b" , #b2 , " = " )             ; Optional formatting and labeling
     SERTXD ( #bit15 , #bit14 , #bit13, #bit12, #bit11, #bit10, #bit9, #bit8 )    ; Print the bits hi -> lo
return
Cheers, Alan.
 

Technical

Technical Support
Staff member
>> lookup b10,(c.0, c.1...

Reading ADC - this works for ADC only because the ADC channel number constant is the same as the pin name constant on the M2 parts. But that doesn't make it right - you really should be using the ADC channel number in the lookup (lookup b10,(8, 9... ). The ADC channel number is shown on the pinout diagrams ADC8, ADC9 etc.

>> lookup b10,(pinc.0,...

Reading digital inputs - pinC.0 is a bit variable, containing the value 0 or 1 depending on the digital state of that pin. It is the name of a variable, not just the name of a pin. So if you then use that variable within a lookup command it will only ever give you 0 or 1 for every pinC.x variable you use.

The correct way to read inputs in a routine (as opposed to multiple 'if pinC.0 = 1 then' commands) is to read portC as a whole and then test each bit as required - see examples above.
 

piclt

Member
Maybe we are going around in circles, most of the answers don't relate to post #1 of this thread.
My original post #1..... lookup list of ADC channels used and readadc b8, b7...... for/next loop b0 is a numerical sequence 0 to 7 and each b0 looks up the table depending on its value to find the ADC num and puts that value into b8. So if b0 was 3 it would lookup and find ADC2 and put 2 in b8, then readadc b8 would actually do readadc 2 and put its value into b7. Next it would check if b8 = "a value" (say<=100) then go and do something. Within the "do something" would be an "exit" so as to exit the for/next after "do something" and not continue to scan pins with next b0 because it had already found the first ADC pin that was say <= 100. The rest of the main loop would be processed and b0 would start again at 0 at the top of the next repeat of main loop.
Perhaps was misleading that I didn't explain the "do something" process but that was not purpose of my post. The point is that I can "pass in" or "use" a variable (b0 to find a b8 value) that contains an ADC num. into the readadc and read a series of ADC channels. No need to read the whole port and then a series of if/then until I come to it.
There does not seem to be a similar functionality for Digital Inputs.
 

Technical

Technical Support
Staff member
You need to understand the difference here between commands and variables.

readadc is a command, you pass to it a value that tells it which ADC channel to read. After the adc is read you then have the result, in a variable, to use in your 'do something' loop

pinsC (or pinC.0 etc) are variables already. They are not a command and so you can't pass a value to them. They already have, by default, the current digital inputs value so are ready to use straight away. Therefore there is simply no need for any command to pass a pin name to - instead you can skip straight to your 'do something' processing using the variable.
 

piclt

Member
we are getting bogged down in a specific example...
If we compare to say Arduino
There is AnalogRead for reading Analog Input values.
There is DigitalRead for reading Digital Input values
Both can be passed a variable (number) that says which pin to read.
If I want something to happen for each pin but only for it to happen if the button is pressed
It is a bit like a priority decoder...... When I scan the pins I want to find the first in the list that is pressed and do the something for that pin. then scan no more pins in that scan as it wastes time and they are don't care at that stage anyway.
Then during the next loop of main the pins will ALL be scanned from start again to find the one in the list that is pressed now.... and do its process as before but for the pin now pressed.
In Picaxe I can do this with ADC inputs readadc but there is no similar function or command in Picaxe for Digital Inputs that I can find.
 

Technical

Technical Support
Staff member
Pin scanning one by one is much simpler like this:

Rich (BB code):
main:
      if pinC.0 = 1 then process0
      if pinC.1 = 1 then process1
      ;if pinC.2 = 1 then process2
      ;if pinC.3 = 1 then process3
      ;if pinC.4 = 1 then process4
      ;if pinC.5 = 1 then process5
      ;if pinC.6 = 1 then process6
      ;if pinC.7 = 1 then process7
      goto main
      
process0: 
      sertxd("Do C.0",cr)
      pause 500
      goto main   
      
process1: 
      sertxd("Do C.1",cr)
      pause 500
      goto main   

However please simulate this in PE6 to show how you can use the pinsC variable if you prefer to use that. There is no DigitalRead type command because it is simply not required, the digital pins values are already in the pinsC / pinC.0 variables without the need for any command.

Rich (BB code):
symbol mask = b4
symbol loop_cnt = b5
symbol temp = b6


main:
      mask = 1 ; %00000001
      for loop_cnt = 0 to 7               ; test pins 0 to 7 in turn
            let temp = pinsC and mask     ; mask out the input we want
            if temp = mask then process   ; is it high?
            mask = mask * 2               ; next mask
      next loop_cnt                       ; next loop

      goto main

process:
      sertxd("First high pin is C.",#loop_cnt,cr)
      pause 500
      goto main
 

piclt

Member
Thanks for your code, Yes, IF/THEN would be the normal way I would do it but some don't like a list of IFs. and I thought there may have been other commands that would give a more streamlined solution
I did a rough check on speed and the IF/Then would be the fastest for checking a list....less checks and commands in the loop.
The masking example would be slower.
 
Top