Why can't I "make" a 3 pole 4 throw switch in basic

bigg_al

New Member
I may be expecting too much of this platform. It seems like it should be a simple matter to do this, but it seems that I cannot indirectly address in/out pins.
In simplified terms, I need to read a number from the serial port then select which group (1 of 4) of three pins (out of 12 pins total) are used when a interrupt occurs. I didn't want to have to write 4 copies of the interrupt with specific pin numbers in each. I assigned symbols to the pin numbers but you can't say symbol1=symbol2 in the program.
What am I missing?
Some code:
Code:
'if b13="1" then rxa=b5rxa:let xvrt=b5xvrt:let pa=b5pa '1296M
    'else if b14="4" then let rxa=b4rxa and let xvrt=b4xvrt and let pa=b4pa '432M
    'else if b14="1" then let rxa=b2rxa and let xvrt=b2xvrt and let pa=b2pa '144M
    'else if b15="5" then let rxa=b1rxa and let xvrt=b1xvrt and let pa=b1pa '50M
    'else if b15="2" and b16="8" then let rxa=b2rxa and let xvrt=b2xvrt and let pa=b2pa '222M
    'else
'endif
 

Flenser

Senior Member
You know what your code is trying to do. We do not.

You will need post the whole program so that we can see what rxa, b1rx, etc are.

You are correct, you can't say symbol1=symbol2 in PICAXE BASIC.
These symbol references are resolved when the program is compiled.
e.g. this code:
SYMBOL interrupt_flags1 = %10000000
SYMBOL interrupt_flags2 = %11000000
SETINTFLAGS interrupt_flags2 %01000000

will be interpreted by the compiler as this:
SETINTFLAGS %11000000 %01000000

and this code:
SYMBOL interrupt_flags1 = %10000000
SYMBOL interrupt_flags2 = %11000000
interrupt_flags2 = interrupt_flags1

will be interpreted by the compiler as this, which is not a valid statement. It makes no sense.
%11000000 = %10000000
 
Last edited:

inglewoodpete

Senior Member
Rich (BB code):
Symbol Symbol2  = pinC.0
Symbol Symbol1  = outpinB.6

Symbol1  = Symbol2  
I agree with most of what Flesner says but you CAN say symbol1=symbol2
 

Flenser

Senior Member
inglewoodpete,

Thanks for that correction. It provides another case demonstrating that if you want to use "Symbol1 = Symbol2 " then it is up to you, the programmer, to make sure that the statement is valid syntax after the values for the two symbols have been substituted by the compiler.
 

AllyCat

Senior Member
Hi,

A SYMBOL can represent either a VARIABLE (e.g. b1) or a CONSTANT (e.g. 5 or even a pin like C.3). AFAIK, what the PE won't allow you to do is an IF constant = constant because that is (usually) "pointless", (as the constants have already been defined, so cannot change when the programs runs).

As already said, it's not clear what the OP is trying to achieve, but it does look rather "untidy" (and prone to making errors). The SELECT .. CASE structure (or perhaps even the faster ON <pointer> GOTO .... ) might be more appropriate for what is trying to be done.

Cheers, Alan.
 

inglewoodpete

Senior Member
@bBigg_al
To get back to your original post:
I may be expecting too much of this platform. It seems like it should be a simple matter to do this, but it seems that I cannot indirectly address in/out pins.
In simplified terms, I need to read a number from the serial port then select which group (1 of 4) of three pins (out of 12 pins total) are used when a interrupt occurs. I didn't want to have to write 4 copies of the interrupt with specific pin numbers in each. I assigned symbols to the pin numbers but you can't say symbol1=symbol2 in the program.
What am I missing?
Some code:
'if b13="1" then rxa=b5rxa:let xvrt=b5xvrt:let pa=b5pa '1296M
'else if b14="4" then let rxa=b4rxa and let xvrt=b4xvrt and let pa=b4pa '432M
'else if b14="1" then let rxa=b2rxa and let xvrt=b2xvrt and let pa=b2pa '144M
'else if b15="5" then let rxa=b1rxa and let xvrt=b1xvrt and let pa=b1pa '50M
'else if b15="2" and b16="8" then let rxa=b2rxa and let xvrt=b2xvrt and let pa=b2pa '222M
'else
'endif
The syntax for the commented code you posted does not make much sense. Of course, no-one but you knows what rxa, b4rxa, xvrt etc are: hardware pins of variables? The use of "and" in a BASIC statement (or the PICAXE version of BASIC) is limited to bitwise logical manipulations. I think you're trying to say (in pseudo code) if <this> then do <one thing>, also do <another thing> and <another>. I think you should be doing something like the following:
Code:
if b13="1" then
    let rxa=b5rxa
    let xvrt=b5xvrt
    let pa=b5pa           '1296M
elseif b14="4" then
    let rxa=b4rxa
    let xvrt=b4xvrt
    let pa=b4pa           '432M
elseif b14="1" then
    let rxa=b2rxa
    let xvrt=b2xvrt
    let pa=b2pa           '144M
elseif b15="5" then
    let rxa=b1rxa
    let xvrt=b1xvrt
    let pa=b1pa           '50M
elseif b15="2" and let b16="8" then
    let rxa=b2rxa
    let xvrt=b2xvrt 
    let pa=b2pa           '222M
endif
However, it appears to me that you need to start small and work upward. When learning to write code, it is pointless writing reams of code without knowing if syntax is correct. Write your code (almost) line-by-line, checking the syntax and logic results in the simulator as you go.
 

bigg_al

New Member
Thanks for the responses guys. I'll try to explain what I am trying to accomplish better.
I assigned symbol names to 12 output pins. A number (1 to 4) received on the serial port will need to select which group of 3 pins will be used in an interrupt routine. I don't want to write 4 copies of the interrupt with specific pin numbers in them. I need to indirectly specify which group of 3 pins to use in the interrupt based upon the number received on the serial port. It appears that cannot be done with this variant of basic.
 

AllyCat

Senior Member
Hi,
I need to indirectly specify which group of 3 pins to use in the interrupt based upon the number received on the serial port. It appears that cannot be done with this variant of basic.
PICaxe Basic is relatively unusual in that the Port.Pin names ARE resolved to numbers , so can be assigned to a variable (e.g. Try SERTXD(#B.4) in the simulator to see the values).

As already explained, your use of AND in #1 is completely incorrect (you probably need to use ":" instead) ; and how have you symbolised "rxa" , etc.?

Cheers, Alan.
 

Flenser

Senior Member
bigg_al

if you post your full code it will make it much easier for the forum to help you.

Questions like this "and how have you symbolised "rxa" , etc.?" are unnecessary if we are able to inspect the code you are trying to run.
 

bigg_al

New Member
Why does this work?
B0=C.2 'C.2 isn't a valid byte value
low B0 'A byte value isn't a valid pin letter dot number name
 

Flenser

Senior Member
B0=C.2 works because it is valid syntax to assign the value of one variable type to another variable type.
C.2 is a bit variable with a value of either 1 or 0 and it is valid to assign a value of 1 or 0 to the byte variable B0.

The same applies to something like W2=B0 or B0=W2. Both are valid although for the B0=W2 case the value of B0 after the assignment will be only the low byte of the W2 word variable. i.e. the programmer is responsible for ensuring that the result of B0=W2 is what you want.

I don't know why low B0 works. My guess is that you have discovered an undocumented "feature" of PICAXE BASIC.
 

Aries

New Member
C.2 (and any of the other X.N pins references) is a NUMBER (as AllyCat says, try sertxd(#C.2) which gives 10.
low 10 is a perfectly valid Picaxe statement, which sets pin 10 (i.e. C.2) low.
Therefore, B0=C.2 works because C.2 is a number.
low B0 works because low takes a number
No undocumented features here.
 

AllyCat

Senior Member
Hi,
B0=C.2 ' C.2 isn't a valid byte value
C.2 is a bit variable with a value of either 1 or 0 and it is valid to assign a value of 1 or 0 to the byte variable B0.
No, as I said above C.2 IS a (constant) NUMBER which can be contained within a byte. It is NOT a bit variable (but it can have the decimal value 0 or 1).

That is why PICaxe Basic needs the (additional) BIT VARIABLE syntax PINC.2 which does indeed read the binary value 0 or 1 from the port. Or if the pin has an ADC, then that value can be read with a READADC PINC.x , B0 , etc.

Cheers, Alan.
 

Aries

New Member
That is why PICaxe Basic needs the (additional) BIT VARIABLE syntax PINC.2 which does indeed read the binary value 0 or 1 from the port. Or if the pin has an ADC, then that value can be read with a READADC PINC.x , B0 , etc.
READADC PINC.2,B0 is valid syntax, but wouldn't it actually read from ADC channel 0 or 1 (depending on whether C.2 was high or low)?
READADC C.2,B0 reads from pin C.2.
 

lbenson

Senior Member
Without an interrupt, does this do what you intend?
Code:
#picaxe 20m2

symbol pinIn1=pinC.6
symbol pinIn2=pinC.7
symbol pinIn3=pinB.7
symbol pinOut1=b5
symbol pinOut2=b6
symbol pinOut3=b7

hsersetup b4800_4,%01000 ' hserout pin normal, T, (2-byte background implied for M2) (B.6 on 20M2)
pinOut1=b.0: pinOut2=b.1: pinOut3=b.2 ' initial state

do
  b4 = $FF ' non-valid command
  hserin b4 ' if no bytes ready, no change
  if b4>"0" and b4<"5" then
    gosub clearall
    select case b4
      case "1": pinOut1=b.0: pinOut2=b.1: pinOut3=b.2
      case "2": pinOut1=b.3: pinOut2=b.4: pinOut3=b.5
      case "3": pinOut1=c.0: pinOut2=c.1: pinOut3=c.2
      case "4": pinOut1=c.3: pinOut2=c.4: pinOut3=c.5
    end select
  endif
  if pinIn1=1 then: high pinOut1: else: low pinOut1: endif
  if pinIn2=1 then: high pinOut2: else: low pinOut2: endif
  if pinIn3=1 then: high pinOut3: else: low pinOut3: endif
  
loop

clearall: low pinOut1, pinOut2, pinOut1: return
It won't work in the simulator because there, HSERIN is "blocking" (it waits for an input character), but on a real chip, HSERIN is not blocking, so if no character has been received, the variable holding the input character (b4 in this case) will contain its previously set value, "$ff". Output pins will be set according to the inputs. If "1" through "4" is received, the current 3-pin pseudo port will be cleared and the new pseudo output port will be set in accordance with the values on the input port. If you need a trigger pin to signal a change, you'll need a bigger PICAXE, e.g., a 28X2.

Not tested (other than roughly, in the simulator), but something like this should work.
 
Last edited:

bigg_al

New Member
C.2 is a pin name or symbol. There is nothing in the manual that says it can be used as a byte variable. Why does it allow b0=S.2 when S.2 isn't a valid pin name? There is other confusing stuff I have come across related to this topic, don't have time to sort it out right now.
My code that is doing what I want now. I can't use the select/case as you'll see. This code is a work in progress.
Thanks everyone for your input.
Code:
'Sequencer with manual or auto band select. Supports 5 bands

'Inputs
'Reads vfo data from PC (9600 baud) using hserin pin B6.
'Reads preamp and power amp on/off from serial in pin 6 RXD
'Reads manual band select, preamp on/off, power amp on/off buttons from ADC7 pin A7
'Reads analog PTT or digital PTT from pins A0 and A1 respectively.
'
'Outputs 
'Outputs 4 step sequence with 3 pins per band plus PTT.
'Outputs analog PTT or digital PTT on pins A2 and A3 repsectively.
'Outputs current band to OLED display
'
'ptt pins in and out
symbol apttin=pinA.0
symbol dpttin=pinA.1
symbol apttout=A.2
symbol dpttout=A.3
'band 1 pinouts
symbol b1rxa=B.0
symbol b1xvrt=B.1
symbol b1pa=B.2
'band 2 pinouts
symbol b2rxa=B.3
symbol b2xvrt=B.4
symbol b2pa=B.5
'band 3 pinouts
symbol b3rxa=D.5
symbol b3xvrt=D.6
symbol b3pa=D.7
'band 4 pinouts
symbol b4rxa=D.2
symbol b4xvrt=D.3
symbol b4pa=C.4
'band 5 pinouts
symbol b5rxa=D.1
symbol b5xvrt=D.0
symbol b5pa=C.3
'interrupt routine symbols
symbol delay=B3
symbol rxa=B4    
symbol xvrt=B5    
symbol pa=B6    
symbol ptt=b7
symbol band=B8
let delay=100                'sequence step delay in ms
let band=1
'******************************************************************************************************

setint %00000000,00000011,A        'ptt interrupt digital or analog
main:
HSERSETUP B9600_8,%111            'background, inverted input and output
do
loop while hserptr<20            'wait for at least 20 bytes of data
for b0 = 0 to 20 step 3                'parse incoming data for header "FA0"
get b0,b10,b11,b12
if b10="F" and b11="A" and b12="0" then goto string
next b0
goto main                    'no valid string, start over

string:                    'the full string is "FAxxxxxxxxxxx;"
                        'only need frequency down to the "mhz" digit
setint off                    'cannot allow interrupt during band setting

get b0,b10,b11,b12,b13,b14,b15,b16    'read string into variables
'
'parse string to determine frequency band
'and set proper pins for sequencer output pins
'
if b13= "1" then let rxa=b5rxa:let xvrt=b5xvrt:let pa=b5pa '1296M
else if b14="4" then let rxa=b4rxa:let xvrt=b4xvrt:let pa=b4pa '432M
else if b14="1" then let rxa=b2rxa:let xvrt=b2xvrt:let pa=b2pa '144M
else if b15="5" then let rxa=b1rxa:let xvrt=b1xvrt:let pa=b1pa '50M
else if b15="2" and b16="8" then let rxa=b3rxa:let xvrt=b3xvrt:let pa=b3pa '222M
endif
' need a section of code to send current band to oled display
'
'
setint %00000000,00000011,A        'turn ptt interrupt back on

'need a section of code to receive ADR2200 relay board commands to enable/disable rx amp or power amp
'
pause 1000
goto main
'
'*************************************************************************************
'ptt interrupt on either analog or digital ptt going low
'sequence outputs for the current band and correct ptt

interrupt:
if apttin=0 then let ptt=apttout        'analog ptt
else let ptt=dpttout                'digital ptt
endif                            'start sequence steps
low rxa                        'first, disable receive preamp                
pause delay
low xvrt                        'second, enable transverter
pause delay
low pa                        'third, enable power amp
pause delay
low ptt                        'fourth, enable transmitter
do                            
loop while ptt=0                     'wait for ptt unkey
high ptt                        'reverse the previous output states
pause delay
high pa
pause delay
high xvrt
pause delay
high rxa
return
 

lbenson

Senior Member
C.2 is a pin name or symbol. There is nothing in the manual that says it can be used as a byte variable.
C.2 can't be used as a byte variable because it isn't a variable, it's a constant.

Why does it allow b0=S.2 when S.2 isn't a valid pin name?
I'll assume you meant b0=C.2. Same reason as above--C.2 is a constant (to prove, try SERTXD(#C.2)). A constant can be assigned to a byte variable. What that statement does not do is assign the value of the pin C.2 (0 or 1) to the byte variable, b0. Try b0=C.2: SERTXD(#b0)
 

Aries

New Member
Let's try another tack ...
The pins of a Picaxe are numbered 0,1,... . You could always refer to them by number, but it is easier, and more understandable, to refer to them by names. The name of pin 0 is B.0, the name of pin 1 is B.1, ... the name of pin 10 is C.2 . These names are pre-defined in the Picaxe compiler, so you can use the names instead of the numbers.

There are some things that you do directly with the pin number - setting them as inputs or outputs, setting them high or low, reading ADC values, ...

If you want to know the state of a pin - whether it is high (=1) or low (=0) then you have to use something else to indicate you want the VALUE of the pin, not its NUMBER. That is the point of the pinB.0, pinB.1, ...

Talking about byte variables is a bit of a red herring (= a distraction, for those non-native English speakers). The variables b0,b1,... (which are 8-bit variables), w0,w1,... (which are 16-bit variables) and bit0,bit1... (which are 1-bit variables) can be given any value. HOWEVER, if the value is greater than the size of the variable (for example, b0 = 257), then the value is truncated to fit (meaning that you lose the higher bits, so 257 becomes 1).

The point about the b, w etc variables is that they can be given values, such as
Code:
b0 = 27
b0 = C.2
b0 = pinC.2
It doesn't matter whether the right hand side of the statement contains constants or variables, as long as it can be evaluated. What you cannot do is the reverse:
Code:
27 = b0
C.2 = b0
do not make sense becaue you cannot change the value of a constant.
Code:
pinC.2 = b0
is a valid statement, because pinC.2 is not a constant, it is "the value of pin C.2". The effect of the statement is to set the value of pin C.2 to 0 or 1, depending on the value of b0 (it will be truncated because pinC.2 is effectively a 1-bit variable).
 

inglewoodpete

Senior Member
Code:
pinC.2 = b0
is a valid statement, because pinC.2 is not a constant, it is "the value of pin C.2". The effect of the statement is to set the value of pin C.2 to 0 or 1, depending on the value of b0 (it will be truncated because pinC.2 is effectively a 1-bit variable).
Almost correct but pinC.2 refers to an input pin. The correct syntax would be outpinC.2 = b0. I note that both seem to pass the syntax check, though.
 

Aries

New Member
Almost correct but pinC.2 refers to an input pin. The correct syntax would be outpinC.2 = b0. I note that both seem to pass the syntax check, though.
This is from Picaxe manual 2:
All pins are configured as inputs on first power-up (unless the pin is a fixed
output). Fixed pins are not affected by this command. These pins are:
08, 08M, 08M2 0 = fixed output 3 = fixed input
14M2 B.0 = fixed output C.3 = fixed input
18M2 C.3 = fixed output C.4, C.5 = fixed input
20M2, 20X2 A.0 = fixed output C.6 = fixed input
28X2, 40X2 A.4 = fixed output

Picaxe Manual 1 shows all C.2 as In/Out
 

premelec

Senior Member
"As a last resort, read the manual." - and hope that it is correct and complete and that you have time to make something after reading the whole thing... ;-0 [and make sure it is the latest version and you know what your chip version is... ]
 

AllyCat

Senior Member
Hi,
Picaxe Manual 1 shows all C.2 as In/Out
Yes, most PICaxe pins are configurable as either Inputs or Outputs, but that text refers to the physical/hardware limitations of a few "special" pins. IWP was referring to the Program Syntax specification and, to to be pedantic, perhaps he should have written "pinC.2 refers to a pin configured as an input". In (PICaxe) Basic, the Left-Hand Side of the (=) assignment is the "destination" (or output) and the RHS is the "input", so the correct syntax is indeed of the form : OUTPINSx = PINSx . However, PICaxe Basic attempts to be "helpful" to Novices, so it sometimes accepts "incorrect" syntax when the intention is clear.

The PIC(axe) Port.Pin hardware is quite complex (with many different modes) so the PICaxe syntax needs to reflect this. The LOW, HIGH and INPUT commands do fully specify an output, but there are also the TOGGLE, REVERSE (a toggle of the I/O state) and of course the DIRS (direction) commands. Thus the hardware needs to "remember" the (previous) state of the Output Pins (Latches), even if they are currently in an Input mode. Then there are the Weak Pullup Resistors, the ADC Input mode and numerous "switches" for additional output (hardware) modes such as PWM, DAC/Reference, Digital Modulator, S-R Latch and Comparators, etc. (all of which exist in the M2's silicon, but not necessarily directly supported by PICaxe Basic).

Cheers, Alan.
 
Top