PDA

View Full Version : Switch in PIC BASIC HELP!!!!



dragan77
- 13th May 2010, 09:04
Hay,all!!!!
Can somebody help me in Picbasic programing!
I need some code to switch with one button,to change to next program!
Example:
program1:
some doing
goto program 1

program2:
some doing
goto program2

program3:
some doing
goto program3 .......


and can some help me how I write some code for the button,when I press button ONE TIME,to I change to
program1
program2
program3......

to change program,when I PRESS MY BUTTON ONE TIME,TO AUTOMATIC GO TO CHANGE PROGRAM!

If some body can help me,how i do that un PIC BASIC!

HenrikOlsson
- 13th May 2010, 10:03
Hi,
There are several possible ways depending on what it is your doing on the various "programs", here's one aproach.
Set up one of the PIC's timers, say TMR0 as a counter, have your button, with some debounce circuitry connected to the external input of the timer.

Then you have a main loop which checks the value of the TMR0 register and jumps to appropriate sub program, when the value of TMR0 is lager than the "last" sub-program you reset the TMR0 register to 0.

Something like, for a 16F628:

TRISA.4 = 1
OPTION.5 = 1 'Set TMR0 as Counter, input is on RA4.
OPTION.4 = 0 'Count on rising edge.
TMR0 = 0 'Reset TMR0 register

Main:
Select Case TMR0
Case 0
Goto ProgramZero
Case 1
Goto ProgramOne
Case 2
Goto ProgramThree
Case Else
TMR0 = 0
Goto Main


ProgramZero:
'Do This
Goto Main

ProgramOne:
'Do That
Goto Main

ProgramThree:
'Do Something else
Goto Main
Another aproach is to wire the switch to an external interrupt pin and use the interrupt request flag to increment a software pointer quite similar to the TMR0 counter above. On the 16F628 PortB.0 is the interrupt pin

TRISB.0 = 1 'PortB.0 as input.
OPTION.6 = 1 'Set interrupt flag on rising edge of PortB.0

Main:
If INTCON.1 = 1 then
INTCON.1 = 0 'Reset flag
myPointer = myPointer + 1
If myPointer = 3 then myPointer = 0 'Wrap around
Select Case myPointer
and then like in the first example...

If you want "instant" switching of programs then you'll need to actually enbale the interrupt as well, not only check the flag, and then do the "program switching" in the interrupt handler.

Well, there's a couple of ideas for you.

/Henrik.

HenrikOlsson
- 13th May 2010, 12:06
Hello again,
I'm sorry but I missed the fact that you wasn't using PBP. In that case it get's a little more complicated, the Select Case (which I don't think PBC supports) can be substitutes with some If Then lines. But the reading and writing of the various register will have to be done with PEEK and POKE and you need to use the datasheet for your particular PIC to figure out which physical adresses the various registers are at.

/Henrik.

dragan77
- 13th May 2010, 12:52
Thanks, a lot Henrik,
but when I try compile your program,I have syntax error!
I am new in programing,can you write me some new code,
about PEEK OR POKE,how you write me last time,
because I do no,t now how I do that!
Thanks a lot again!!!

dragan77
- 13th May 2010, 13:09
One question more!
What you mean line
OPTION.5=1
AND
OPTION.4=0

WHAT I MUST WRITE IN THIS 2 LINES?
Because I have syntax error.

HenrikOlsson
- 13th May 2010, 15:24
Hello,
OPTION.5 = 1 simply sets bit 5 in the option register but like I said in my previous post PBC doesn't support direct register access like that so you'll have to use POKE to write the registers and PEEK to read them. Look at the memory map of the device you're working with. You'll find at which adresses the various registers are. On the 16F628 the OPTION register is at location 80h for example.

Look in the PBC manual on how to use POKE and PEEK.

Why did I want to set bit5 in the option register? That's because it is the bit that select if TMR0 is a timer or counter and I found that information in the section of datasheet dedicated to TMR0.

/Henrik.

dragan77
- 13th May 2010, 17:16
Hello,
I don.t understood how I do that.
I use device PIC16f628,

I just need when I PUSH BUTTON ONE TIME,
then working program 1,
when I push button next time,
go to next program 2,
when I push button next time,
go to next program 3,......

Can you write me code in PIC BASIC code for that,
if you cant,
thanks anyway!!!

mackrackit
- 13th May 2010, 17:40
I have not used Pic Basic so I can not help much but here is a "not very good idea" you might play with while you are working out the register reading Henrik is pointing you to.


Setup a BUT_CHECK routine with a RETURN at the end of it.
In each of the program loops have a GOSUB BUT_CHECK.
The BUT_CHECK routine will check if the button IS pressed and if it is increment a variable by one.
When the code returns to the program running the next line will have something like.
IF BUT_VAR = 2 GOTO PROG 2

Lots of problems with doing it this way but if things are not critical....
When you figure out the registers with Pic Basic you should see how bad of an idea this is.

BrianT
- 14th May 2010, 01:36
Try this idea, it works with PBP in a PIC18F4620 and should work with any PIC that has EEPROM.

I set a byte variable "ProgramState" to 1 in a data statement and write this to EEPROM when the program is loaded into the PIC.

At power up, the code reads the value stored in ProgramState, here set to 1, and jumps to the appropriate code block.

MAIN:
READ 0, ProgramState
If ProgramState = 1 then RunCode1
If ProgramState = 2 then RunCode2
If ProgramState = 3 then RunCode3

If ProgramState > 3 then
write 0, 1 'reset ProgramState to first code block
goto MAIN
endif

RunCode1:
execute codeblock 1
if ButtonDown = 1 then
write 0, 2
endif
goto MAIN

RunCode2:
execute codeblock 2
if ButtonDown = 1 then
write 0, 3
endif
goto MAIN

etc

HTH
BrianT

dragan77
- 14th May 2010, 09:58
Thanks,Braian,for help,
I try your idea,but doesn't,work.
I try explain what I need,example:

program1:
HIGH PORTB.1
PAUSE 500
LOW PORTB.1
PAUSE 500
GOTO program1

program2:
HIGH PORTB.2
PAUSE 500
LOW PORTB.2
PAUSE 500
GOTO program2

program3:
HIGH PORTB.3
PAUSE 500
LOW PORTB.3
PAUSE 500
GOTO program3 .........

and now I don't now how,how I make code for switch!

I need,when I press switch,JUST ONE TIME,
and every time when I press switch again,
to change program1,program2,program3,......

that is problem!

malc-c
- 14th May 2010, 12:36
Hope this helps.

This code will need changing as it's in PBP, but the logic should still work with PB. I've used this to select options in a menu by pressing one button and then another to jump to the option selected, so in theory it could be used to select which program you run



LCDOUT $FE,2,"Main Menu"
lcdout $FE, $C0, "Select Option"

if Option = 1 THEN lcdout $FE, $D4, "Set Time and Date "
if option = 2 then lcdout $FE, $D4, "Set Night Period "
if option = 3 then lcdout $FE, $D4, "Set Normal Temps "
if option = 4 then lcdout $FE, $D4, "Run "

IF !H_butt THEN Option = option + 1 ; if button is low
pause 150
if option >4 then option = 0

If option = 1 Then ; if option =1 and S_but is taken low then reset LCD and gosub debounce followed by jump to option selected
If S_butt = 0 Then
LCDOUT $FE,1
Gosub SetButtonRelease
goto setup
endif
endif


If option = 2 Then
If S_butt = 0 Then
LCDOUT $FE,1
Gosub SetButtonRelease
goto nitetime
endif
endif


If option = 3 Then
If S_butt = 0 Then
LCDOUT $FE,1
Gosub SetButtonRelease
goto GetSetpoint
endif
endif

If option = 4 Then
If S_butt = 0 Then
LCDOUT $FE,1
Gosub SetButtonRelease
goto main
endif
endif

Goto mainmenu


The reason I use two buttons (one to select the option and one to confirm it) is that if you don't I found it hard to get passed the first option. For example, if you had



program1:
HIGH PORTB.1
PAUSE 500
LOW PORTB.1
PAUSE 500
GOTO program1

program2:
HIGH PORTB.2
PAUSE 500
LOW PORTB.2
PAUSE 500
GOTO program2

program3:
HIGH PORTB.3
PAUSE 500
LOW PORTB.3
PAUSE 500
GOTO program3


switch =0
if portB.0 = 0 then switch = switch +1

If switch = 1 then goto program 1
If switch = 2 then goto program 2
If switch = 3 then goto program 3
if switch >3 then switch=0


then as soon as you press your switch and the variable switch=1 it would jump to program 1 and never reach program 2 or 3.

Hope this helps, and sorry it's not converted into PB that you can use directly, but hopefully that won't be too hard to cchange

flotulopex
- 16th May 2010, 22:37
Another way to do it ;)


ButtonPressCounter = 0

SWITCH-LOOP:
IF PORTx.x = 0 THEN 'this is where your button is connected to, obviously
IF ButtonPressCounter = 3 THEN ButtonPressCounter = 0
ButtonPressCounter = ButtonPressCounter + 1
IF ButtonPressCounter = 1 THEN GOSUB Program1:
IF ButtonPressCounter = 2 THEN GOSUB Program2:
IF ButtonPressCounter = 3 THEN GOSUB Program3:
ENDIF
GOTO SWITCH-LOOP:

Program1:
...do something
RETURN

Program2:
...do something
RETURN

Program3:
...do something
RETURN

dragan77
- 17th May 2010, 00:20
Thanks,Roger
but can i ask you some!
Is it finish code for compile,or some of combination,to I use!

Can you write finish code for compile, because I am new in programing!

flotulopex
- 17th May 2010, 06:40
Is it finish code for compile...

Almost!

Set the PORTx.x you are going to use for your button and program your routines and you're done.

dragan77
- 17th May 2010, 23:59
Thanks,but when I use this code:

ButtonPressCounter = 0

SWITCH-LOOP:
IF PORTA.2 = 0 THEN
IF ButtonPressCounter = 3 THEN ButtonPressCounter = 0
ButtonPressCounter = ButtonPressCounter + 1
IF ButtonPressCounter = 1 THEN GOSUB Program1
IF ButtonPressCounter = 2 THEN GOSUB Program2
IF ButtonPressCounter = 3 THEN GOSUB Program3
ENDIF
GOTO SWITCH-LOOP:

Program1:
high portb.1
RETURN

Program2:
high portb.2
RETURN

Program3:
high portb.3
RETURN

WHEN I TRY COMPILE IN PIC BASIC,THEN GIVE ME THIS ERRORS!

ERROR Line 1: Syntax error.
ERROR Line 3: Syntax error.
ERROR Line 4: IF without a matching ENDIF.
ERROR Line 5: Bad expression.
ERROR Line 5: Bad expression or missing THEN.
ERROR Line 5: IF without a matching ENDIF.
ERROR Line 6: Syntax error.
ERROR Line 7: Bad expression.
ERROR Line 7: Bad expression or missing THEN.
ERROR Line 7: IF without a matching ENDIF.
ERROR Line 8: Bad expression.
ERROR Line 8: Bad expression or missing THEN.
ERROR Line 8: IF without a matching ENDIF.
ERROR Line 9: Bad expression.
ERROR Line 9: Bad expression or missing THEN.
ERROR Line 11: Syntax error.


I DO NOT NOW WHY,WHAT IS HAPPENED?

mackrackit
- 18th May 2010, 00:02
Is that the whole code?

Is the line


ButtonPressCounter VAR BYTE

in there someplace?

dragan77
- 18th May 2010, 00:39
Thanks,for help,but can you give me one more answer!

I write this code:

ButtonPressCounter var byte

SWITCHLOOP:
IF PORTA.2 = 0 THEN
IF ButtonPressCounter = 3 THEN ButtonPressCounter = 0
ButtonPressCounter = ButtonPressCounter + 1
IF ButtonPressCounter = 1 THEN GOSUB Program1
IF ButtonPressCounter = 2 THEN GOSUB Program2
IF ButtonPressCounter = 3 THEN GOSUB Program3
ENDIF
GOTO SWITCHLOOP:

Program1:
high portb.1
PAUSE 500
LOW PORTB.1
PAUSE 500

RETURN

Program2:
high portb.2
PAUSE 500
LOW PORTB.2
PAUSE 500
RETURN

Program3:
high portb.3
PAUSE 500
LOW PORTB.3
PAUSE 500
RETURN

is Ok,code working,
but how I do it,when I switch button,to change program,and stay work in this some of this program?

mackrackit
- 18th May 2010, 00:49
but how I do it,when I switch button,to change program,and stay work in this some of this program?
Sorry, but I do not understand the question.

dragan77
- 18th May 2010, 01:03
I try ex plane,my question!
I mean!

I need when I press button one time,
then in my case go to program1,
and still working in program1!

When I press button second time then
go to program2,
and still working in program2,

When I press button 3.rd time then
go to program3,
and still working in program3,......

mackrackit
- 18th May 2010, 01:15
Maybe...


SWITCHLOOP:
IF PORTA.2 = 0 THEN ButtonPressCounter = ButtonPressCounter + 1
IF ButtonPressCounter = 1 THEN GOSUB Program1
IF ButtonPressCounter = 2 THEN GOSUB Program2
IF ButtonPressCounter = 3 THEN GOSUB Program3
IF ButtonPressCounter = 4 THEN ButtonPressCounter = 0
ENDIF
GOTO SWITCHLOOP:

maybe not... See what happens.

dragan77
- 18th May 2010, 01:33
Thanks,for your help,
but not working!

I need this program, because I try make program for some light show,when I press button,to change program,and still working,in some of this my program!

mackrackit
- 18th May 2010, 03:17
Are we seeing the whole code?
Have you turned any ANALOG off?
http://www.picbasic.co.uk/forum/showthread.php?t=561

And if that does not work tell what is happening.

malc-c
- 18th May 2010, 07:31
Thanks,for your help,
but not working!

I need this program, because I try make program for some light show,when I press button,to change program,and still working,in some of this my program!

Post your complete code (all lines) and you might get a better response.

The code I posted works the way you want to.. but requires two buttons... is that such a problem ?

dragan77
- 19th May 2010, 00:28
First,THANKS ALL FOR HELP!!!

THIS IS CODE i WILL TRY TO MODIFIED,

ButtonPressCounter var byte

SWITCHLOOP:
IF PORTA.2 = 0 THEN
IF ButtonPressCounter = 3 THEN ButtonPressCounter = 0
ButtonPressCounter = ButtonPressCounter + 1
IF ButtonPressCounter = 1 THEN GOSUB Program1
IF ButtonPressCounter = 2 THEN GOSUB Program2
IF ButtonPressCounter = 3 THEN GOSUB Program3
ENDIF
GOTO SWITCHLOOP:

Program1:
high portb.1
PAUSE 500
LOW PORTB.1
PAUSE 500

RETURN

Program2:
high portb.2
PAUSE 500
LOW PORTB.2
PAUSE 500
RETURN

Program3:
high portb.3
PAUSE 500
LOW PORTB.3
PAUSE 500
RETURN

This code work good,but,I need just when I press my button,then,
still working on some on this may program,

program1,program2,program3!!!

I do not how I make some changes,that will be working!

vaporized
- 19th May 2010, 13:28
Hello.
Can you please give us a bit more detailed description of what are you trying to achieve. In the meantime you could try this:




led_tm var word
led var byte
indx var byte
dbc var byte
led_f var bit

symbol key=porta.2

poke $1F,7 'turn off comparator
poke $9F,0 'turn off voltage reference

porta=0: portb=0
trisa=%00010100
trisb=%00000000
pause 500

led_f=0: led_tm=0: indx=3



MAIN:
pause 1
if key=0 then dbc=dbc+1 'use this if porta.2 is pulled high
'if key=1 then dbc=dbc+1 'use this if porta.2 is pulled low
if dbc=70 then gosub SWITCH_LED
if dbc>72 then dbc=72
if key=1 then dbc=0 'use this if porta.2 is pulled high
'if key=0 then dbc=0 'use this if porta.2 is pulled low

led_tm=led_tm+led_f
if led_tm=500 then
toggle led
led_tm=0
endif
goto MAIN


SWITCH_LED:
indx=indx+1
if indx>2 then indx=0
lookup indx,[1,2,3],led
toggle led
led_f=1
return

dragan77
- 19th May 2010, 15:42
Thanks so much,Grinder,for your help!!!

I try your code,and working good,just what I wont to do in my project,when I press button in PORTA.2, to change program,and still in same program,
and your code do it that!

But,can,you ex plane me,what I must do, which peace,of your code,I must change,
if I like to change, which port I like to be low,of high,I mean because I like to make some ,to combinations of led,to high,or low,to I do it myself!

malc-c
- 19th May 2010, 21:05
To be fair, paste up your complete code as it is and then people can see what you want to do and hopefully post a corrected version for you. To ask for help and only post up cryptic bits of code makes it hard to provide the support you are seeking

dragan77
- 19th May 2010, 22:49
Ok,I try modification this code:


switch var byte

main:
if portb.2 = 1 then
switch = switch +1

If switch = 1 then goto program1
If switch = 2 then goto program2
If switch = 3 then goto program3
endif
goto main

program1:
HIGH PORTB.1
PAUSE 500
LOW PORTB.1
PAUSE 500
GOTO program1

program2:
HIGH PORTB.2
PAUSE 500
LOW PORTB.2
PAUSE 500
GOTO program2

program3:
HIGH PORTB.3
PAUSE 500
LOW PORTB.3
PAUSE 500
GOTO program3

and what I need,
when I press button,JUST ONE TIME,TO, PORTB.2,
TO GO TO PROGRAM 1,
AND STILL WORKING IN THE PROGRAM 1.

when I press button,NEXT TIME,TO, PORTB.2,
TO GO TO PROGRAM 2,
AND STILL WORKING IN THE PROGRAM 2.

when I press button,NEXT TIME,TO, PORTB.2,
TO GO TO PROGRAM 3,
AND STILL WORKING IN THE PROGRAM 3,.......

THAT I NEED!!!

malc-c
- 20th May 2010, 09:09
Long way, but possibly a fix is to incorporate the test for switch in each program



main:
if portb.2 = 1 then
switch = switch +1

If switch = 1 then goto program1
If switch = 2 then goto program2
If switch = 3 then goto program3
endif
goto main

program1:
HIGH PORTB.1
PAUSE 500
LOW PORTB.1
PAUSE 500
if portb.2 = 1 then
switch = switch +1

If switch = 1 then goto program1
If switch = 2 then goto program2
If switch = 3 then goto program3
endif
GOTO program1

program2:
HIGH PORTB.2
PAUSE 500
LOW PORTB.2
PAUSE 500
if portb.2 = 1 then
switch = switch +1

If switch = 1 then goto program1
If switch = 2 then goto program2
If switch = 3 then goto program3
endif
GOTO program2

program3:
HIGH PORTB.3
PAUSE 500
LOW PORTB.3
PAUSE 500
if portb.2 = 1 then
switch = switch +1

If switch = 1 then goto program1
If switch = 2 then goto program2
If switch = 3 then goto program3
endif
GOTO program3


crude code, but may work (I've not tested as I'm at work)

malc-c
- 20th May 2010, 09:10
THAT I NEED!!!

Oh and no need to shout !

flotulopex
- 20th May 2010, 12:25
This is what I understand you may be looking for (not tested yet).
MAIN:
IF PORTA.2 = 0 THEN
PAUSE 300 'debounce
GOTO Program1:
ENDIF
GOTO MAIN:

Program1:
IF PORTA.2 = 0 THEN
PAUSE 300
GOTO Program2:
ENDIF
HIGH PORTB.1
PAUSE 500
LOW PORTB.1
PAUSE 500
GOTO Program1:

Program2:
IF PORTA.2 = 0 THEN
PAUSE 300
GOTO Program3:
ENDIF
HIGH PORTB.2
PAUSE 500
LOW PORTB.2
PAUSE 500
GOTO Program2:

Program3:
IF PORTA.2 = 0 THEN
PAUSE 300
GOTO Program1:
ENDIF
HIGH PORTB.3
PAUSE 500
LOW PORTB.3
PAUSE 500
GOTO Program3:

END


...Can you write finish code for compile, because I am new in programing!

Thanks,for your help,but not working!

But,can,you ex plane me,what I must do, which peace,of your code,I must change...
.....
My question to you dragan77: is this thread really 30 replies worth? What are your personal inputs and efforts?

It looks a bit frustrating to me....

vaporized
- 20th May 2010, 13:31
Hello.
Please forgive me, but I'm still not sure what are you trying to do. What puzzles me most is PAUSE 500 because when a program is executing PAUSE it can't do anything else until the specified period expire (unless abrupted by interrupt). In your case, whenever the program hits PAUSE 500 it is just sitting there for the half of a second.
In my example the program is looping in MAIN waiting a key to be pressed (with some sort of debounce routine) and counting ~500ms ON/OFF time for the appropriate LED (it counts nothing until the key is pressed for the first time). After keypress it jumps to SWITCH_LED subroutine where it adjusts index (indx variable) to grab a value from the LOOKUP table in order to toggle an appropriate LED (that way I'm addresing a port by its number instead by its name), and then returns in main loop.




if I like to change, which port I like to be low,of high,I mean because I like to make some ,to combinations of led,to high,or low,to I do it myself!

To change ports with attached LEDs you need to change values in LOOKUP table. You can use numbers 0-15 instead of port names, where 0 is portb.0, and 15 would be porta.7. However on 16F628 you can go as far as 12 (porta.4) or 13 (porta.5), depending whether you use external or internal oscillator. It's not same for all PICs. For example on 16F877 you can use full range of 0-15 because it spreads over portb and portc.

vaporized
- 20th May 2010, 15:56
Hello.

First, I want to apologize for taking liberty to correct other people's code. In post no. 31 mr. Roger (flotulopex) accidentaly made a mistake:


MAIN:
IF PORTA.2 = 0 THEN
<font color="red">PAUSE 300 'debounce</font>
GOTO Program1<font color="red">:</font>
ENDIF
GOTO MAIN<font color="red">:</font>
...


Those colons marked red are surplus and that PAUSE 300 doesn't do any debounce here. It is simply executed immediately after the porta.2 goes low. The most simple way to verify that is to change pause to some larger value, e.g. 1000 (1 sec.) and apply very short (less than 1 sec.) push on button. What will happen is that LED will toggle its state after the pause no matter how shortly you kept the button pressed.
If it was written like this:


IF PORTA.2 = 0 THEN
PAUSE 300
IF PORTA.2 = 0 THEN Program1
ENDIF

On button-press the program would make a 300ms debounce-pause and then check again if button is still pressed and perceived if it was real button-press or just random noise.

flotulopex
- 20th May 2010, 22:16
Hi grinder,

Thanks for your corrections but there is sometimes an explanation behind "strange looking" code.

If you didn't tested this yet, do so and you will discover that the "debounce" will prevent the code to jump from the MAIN loop directly to the Program2 label; just try...and see by yourself ;)

You're right, the colons are not necessary but this is just because I copy/paste the code instead of retyping it. BTW, this will make absolutely no change to the compiled code.

Dragan77 seems to be looking for a simple program made of simple commands for simple functionality; I'm not sure his application needs "complexity" up to using LOOKUP and so on.

vaporized
- 21st May 2010, 11:14
Hello.

Mr. Roger (flotulopex), I apologize once more.


If you didn't tested this yet, do so and you will discover that the "debounce" will prevent the code to jump from the MAIN loop directly to the Program2 label; just try...and see by yourselfNo need to test it, you're absolutely right about that. I made a mistake taking piece of your code out of the content. My intention was to explain that debouncing should represent a protection against random noise, beside inadvertently key presses. I'm really sorry, I didn't eplained that adequately.


You're right, the colons are not necessary but this is just because I copy/paste the code instead of retyping it...That's why I said that you accidentaly made a mistake.


Dragan77 seems to be looking for a simple program made of simple commands for simple functionality; I'm not sure his application needs "complexity" up to using LOOKUP and so on.I beleive you're right about that as well. I put my example more as a probe to see if that's what mr. Dragan77 wants to achieve.