News:

Let's find out together what makes a PIC Tick!

Main Menu

Using a pot as a multipole rotary switch.

Started by david, Jun 03, 2023, 09:36 AM

Previous topic - Next topic

david

Hi All,
I've used pots with 5V applied before as multipole rotary switches but have always defined both the upper and lower values of each switch point similar to this-
If potval>50 and potval<100 then....

I recently stumbled upon an Arduino tutorial on YouTube that did much the same thing but using progressive ElseIf statements with incrementing pot values as per the attached.  This seemed simpler and easier to manage than my effort so I gave it a try but failed when using the following code.
potread: ADCON0.1=1                  '8 bit conversion
         While ADCON0.1=1 :Wend       
          If sw1<10 Then
           t=0     
           ElseIf sw1<70 Then t=4
   ElseIf sw1<130 Then t=6
   ElseIf sw1<190 Then t=8
   ElseIf sw1<255 Then t=10
          EndIf
          DelayMS 500
         SerOut PORTA.4,84, [Dec sw1," ",Dec t,13,10]  '9600 inverted   
GoTo potread
            End


So the above reads the ADC value correctly but doesn't assign a value for t other than 0.
I was hoping to be a bit further down the track on this by now and to also try some hysteresis on the ADC value such that the pot couldn't sit on a critical voltage level and flutter between values.  Right now I would settle for any ideas on why my "t" value isn't working and I'll try adding hysteresis later. 

Cheers,
David

John Lawton

I would use the SELECT statement for this sort of work as I find it much easier to understand and write.

david

Thanks for the reply. Can't say I've ever used the command so it's probably a good time to check it out.  The manual implies it is a variant of the ElseIf command. 
This task is so much easier with a real rotary switch and equal values resistors giving fairly defined steps which avoids the need to add hysteresis.

Cheers,
David

david

John - that worked out very easy and by having an undefined band between ranges it behaves like hysteresis.  So in the example below an increasing value of sw1 from 30 to 69 gives a value for t of 60.  When sw1 becomes 70 the value of t changes to 100. A decreasing value of sw1 holds the t value at 100 until sw1 reduces to 60 or less.  This is exactly what I needed to stop dither about a pot value.

 Select sw1
          Case <21
          t=20
          Case 30 To 60
          t=60
          Case 70 To 100
          t=100


Many thanks for your timely input.

Cheers,
David

joesaliba

David,

I used that method several times and always worked.

Using Select is pretty the same as the Elseif, but sometimes I find it takes more code space.

I think it is a way how to write the code.

I think that, or it is an anomaly or otherwise the compiler is not throwing a warning that ElsIf do not work as you write it.

It happened that I have a PIC connected to an LCD testing some analog and the following works: -

If m1fb < 10 Then
    t=0

    ElseIf m1fb < 70 Then
        t=4

    ElseIf m1fb < 130 Then
        t=6

    ElseIf m1fb < 190 Then
        t=8

    ElseIf m1fb < 255 Then
        t=10

 EndIf

trastikata

In the OP I would assume sw1 is an alias for the ADRESL register?


david

Quote from: joesaliba on Jun 03, 2023, 11:34 AMDavid,

I used that method several times and always worked.

Using Select is pretty the same as the Elseif, but sometimes I find it takes more code space.

I think it is a way how to write the code.

I think that, or it is an anomaly or otherwise the compiler is not throwing a warning that ElsIf do not work as you write it.

It happened that I have a PIC connected to an LCD testing some analog and the following works: -

If m1fb < 10 Then
    t=0

    ElseIf m1fb < 70 Then
        t=4

    ElseIf m1fb < 130 Then
        t=6

    ElseIf m1fb < 190 Then
        t=8

    ElseIf m1fb < 255 Then
        t=10

 EndIf


Thanks Joe.  To be honest I can't see what is different about your code snippet and mine.  I would like to get it working to check the code size because having only one parameter to check for should be smaller/faster than a check for < and > .  Sigh...another day probably lost forever.

I appreciate your quick test there on my behalf.

Cheers,
David

david

Quote from: trastikata on Jun 03, 2023, 11:51 AMIn the OP I would assume sw1 is an alias for the ADRESL register?


Indeed it is.  There's not much that gets past you is there?

Cheers,
David

trastikata

#8
Quote from: david on Jun 03, 2023, 12:05 PMIndeed it is.  There's not much that gets past you is there?

Just wanted to make sure I'm not missing anything.I think there might be a bug in the compiler.

When an Instruction is following the ElseIf command on the same line, the instruction is disregarded.

Note in the following snippet code:

ElseIf sw1<70 Then
    t=4
ElseIf sw1<130 Then t=6
ElseIf sw1<190 Then t=8

How there's no assembler code for the instruction i.e. what to do with "t" when the instruction follows the ElseIf statement:

...
F1_000016 equ $ ; in [TEST.BAS] ElseIf sw1<70 Then
_lbl__5
    movlw 70
    subwf ADRESL,W,0
    bc _lbl__6
F1_000017 equ $ ; in [TEST.BAS] T=4
    movlw 4
    movwf _T,0
    bra _lbl__4
F1_000018 equ $ ; in [TEST.BAS] ElseIf sw1<130 Then : T=6
_lbl__6
    movlw 130
    subwf ADRESL,W,0
    bc _lbl__7
    bra _lbl__4
F1_000019 equ $ ; in [TEST.BAS] ElseIf sw1<190 Then T=8
...

joesaliba

#9
David,

The difference is that I shifted the t=4, for example, a line below the then.

When I pasted your code, everything in line: -

ElseIf sw1<70 Then t=4
it stayed 0, as you perfectly said.

Changing to: -

ElseIf m1fb < 70 Then
    t=4

it worked.

I also printed on a 2-line LCD. First line the actual value, in my case M1FB, and second line value of t, and indeed it workes as you expected.

Regards

Joe


joesaliba

Quote from: trastikata on Jun 03, 2023, 12:25 PM
Quote from: david on Jun 03, 2023, 12:05 PMIndeed it is.  There's not much that gets past you is there?

Just wanted to make sure I'm not missing something.I think there might be a bug in the compiler.

When an Instruction is following the ElseIf command on the same line, the instruction is disregarded.

Note in the following snippet code:

ElseIf sw1<70 Then
    t=4
ElseIf sw1<130 Then t=6
ElseIf sw1<190 Then t=8

How there's no assembler code for the instruction i.e. what to do with "t" when the instruction follows the ElseIf statement:

...
F1_000016 equ $ ; in [TEST.BAS] ElseIf sw1<70 Then
_lbl__5
    movlw 70
    subwf ADRESL,W,0
    bc _lbl__6
F1_000017 equ $ ; in [TEST.BAS] T=4
    movlw 4
    movwf _T,0
    bra _lbl__4
F1_000018 equ $ ; in [TEST.BAS] ElseIf sw1<130 Then : T=6
_lbl__6
    movlw 130
    subwf ADRESL,W,0
    bc _lbl__7
    bra _lbl__4
F1_000019 equ $ ; in [TEST.BAS] ElseIf sw1<190 Then T=8
...

That is why I said, either is an anomaly within the compiler, or the compiler should throw an error about syntax.

Joe

david

OK.  A big thanks to Joe and trastikata - I think I've got that now.  I know I had it written as you have but can't remember if I ran a test before finding I could write it on a single line without warnings.  This was my downfall.
I will try it again as it is very compact for when using a rotary switch with resistors.  The use of Select/Case with gaps between ranges appears to offer a good method of adding hysteresis to the readings which is really essential when using pots that could be set on a boundary.
Joe - Thanks for taking time out to run those tests.  I shall try to redeem myself again in the morning.

Cheers,
David

joesaliba


Frizie

As far as I know as a single line command, only IF...THEN... is allowed.
ELSEIF (and probably ELSE as well) are not one of them.
Read the manual to be sure.
Ohm sweet Ohm | www.picbasic.nl

trastikata

It looks like a problem with the parser because even with colon ":" after "Then", which is supposed to indicate a new line, doesn't generate the correct assembler code:

ElseIf sw1<130 Then : t=6
results in incomplete assembler code

F1_000018 equ $ ; in [TEST.BAS] ElseIf sw1<130 Then : T=6
_lbl__6
    movlw 130
    subwf ADRESL,W,0
    bc _lbl__7
    bra _lbl__4
F1_000019 equ $ ; in [TEST.BAS] ElseIf sw1<190 Then T=8

david

Well I'm pleased to say that I got things working correctly this morning by having the ElseIf condition and its following instruction on separate lines - as shown in the manual's example.
I shall use this for some applications but at the moment the Select/Case command is doing the job nicely and has the hysteresis needed to stop pot dither.  It does have slightly bigger code and is marginally slower but then adding hysteresis to the ElseIf method would also take its toll.

So if adding a ":" doesn't work for the ElseIf command's instruction does this example from the manual work?
If X = 10 Then High LED1 : ElseIf X = 20 Then High LED2 : Else : High LED3

Cheers,
David

Frizie

Quote from: trastikata on Jun 03, 2023, 03:55 PMIt looks like a problem with the parser because even with colon ":" after "Then", which is supposed to indicate a new line, doesn't generate the correct assembler code:

You cannot say that the colon equals a newline.

Example:
SELECT CASE x
  CASE 10 : HIGH Led1
  CASE 20 : HIGH Led2
END SELECT


This isn't going to work either (Ergo: colon != new line).

What does work:
SELECT CASE x
  CASE 10
    HIGH Led1
  CASE 20
    HIGH Led2
ENDSELECT
Ohm sweet Ohm | www.picbasic.nl

trastikata

#17
Quote from: Frizie on Jun 04, 2023, 09:27 AM
Quote from: trastikata on Jun 03, 2023, 03:55 PMIt looks like a problem with the parser because even with colon ":" after "Then", which is supposed to indicate a new line, doesn't generate the correct assembler code:

You cannot say that the colon equals a newline.

Please refer to page 37 from the Manual, paragraph "General Format".

Did not check your example, but if it doesn't work, it means there's a problem with the parser.

COLON.jpg

Frizie

Trastikata, I don't want to start a discussion, but what I mean is that you can't say 1 to 1 that the colon is 100% the same as starting a new line.
But when Les comes online, he can give a definite answer.
Ohm sweet Ohm | www.picbasic.nl

trastikata

Quote from: Frizie on Jun 04, 2023, 01:19 PMTrastikata, I don't want to start a discussion, but what I mean is that you can't say 1 to 1 that the colon is 100% the same as starting a new line.

Of course it's not the same, obviously they have different ASCII codes but in the code listing a colon is supposed to have the same meaning as a new line as far as the parser is concerned.

But you are right, only Les can clarify with certainty.