HI Henrik
I've looked lookup in the manual (I found a copy on the net, then realised there's one in the demo-program...doh).
So are we saying that to make the seven segment display show a '3' our loop count would be:00000011 '3' but that would LOOKUP a stored value of :%01001111 and display that?
So we'd have to 'load in' somewhere a table of values:
%01001111 3 b3
%01011011 2 b2
%00000110 1 b1
%00111111 0 b0
So:
FOR B0 = 0 TO 3 ' Count from 0 to 3
LOOKUP B0,[%00111111],B1 ' Get character number B0 from string to variable B1
SEROUT 0,N2400,[B1] ' Send character in B1 to Pin0 serially
NEXT B0 ' Do next character
*Shouldn't SEROUT be something like PAROUT (parallel out) namely display all seven bits on seven pins at once.*
Dave (struggling but trying).
Last edited by LEDave; - 24th February 2010 at 17:14.
No,*Shouldn't SEROUT be something like PAROUT (parallel out) namely display all seven bits on seven pins at once.*
GPIO = B1
will set the bits to whatever B1 is.
SERIOT is for RS232 type stuff.
Another lesson
Dave
Always wear safety glasses while programming.
Hi mackrackit
"You might get creative and shift the bits 4 four places.
Lower four to one port, upper four to the other???"
How difficult is getting creative for a newbie like me?
My PICkit1 came with a PIC16F684 included.
Dave
The '<<' and '>>' operators shift a value left or right, respectively, 0 to 15 times. The newly shifted-in bits are set to 0.
Code:B0 = B0 << 3 ‘ Shifts B0 left 3 places, (same as multiply by 8) W1 = W0 >> 1 ‘ Shifts W0 right 1 position and places result in W1 (same as divide by 2)
Hi,
SEROUT is for serial RS232 communication. It's just used as an example in the LOOKUP section of the manual.See, when i is 0 the first value in the lookup table (0) will get written to GPIO, all bits will be reset, when i is 6 the seventh value (125) in the lookup table will get written to GPIO. 125 is the same as %01111101 which means all segments except the one driven by Bit1 will be on - the display will show "6".Code:i VAR BYTE Main: For i = 0 to 9 LOOKUP i, [0, 6, 91, 79, 102, 109, 125, 7, 127, 103], GPIO Pause 500 Next Goto Main
Now, this would work on a PIC with seven or more consecutive GPIO pins, which apparently doesn't exist.... Getting a PIC with a "full" PortB and using that instead of GPIO would do it. It's still possible to do on the '684 (which has 6 bits on PortA and 6 bits on PortB, no GPIO) but then maby the Lookup aproach isn't the most suitable.
There are many many ways to skin the cat, sit down and play a bit with what you have, if you already have the BCD-Seven segment decoder go ahead and use that and play around.
/Henrik.
In the Math Operators section of the manual take a look at SHIFT and the Btiwise Operators.
The idea is..
From Henrik
You will have to connect the display so that part is on one port and part on another. half and half...To display a "2" you need to set bits 0, 1, 3, 4 and 6 (%01011011 or 91)
Take the lower 4 bits in the case of #2 (1011) and send them to the display with Port1.
Take the upper 4 bits (0101) and send that to the display with Port2.
Think of Port1 as being 0-3
Port2 as 4-7
Presto... a whole Port...0-7
Dave
Always wear safety glasses while programming.
Well plenty to think about today. Maybe a little consolidation from me, drum those basics into my mind (I still have plenty to learn here).
I see what you're saying regards splitting port1 & port1 to drive the display.
Absolutely fascinating stuff though, I think I'm hooked and I've only managed to flash a few LED's.
Again many thanks to you all.
Dave
Hi everyone. I've been working on a program below which is a modification of Henrik's look up table program. I know if you had a PIC with an eight bit wide output you could store the output words in the lookup table and then drive a seven segment display directly as Henrik explained.
So I thought I'd try and load a lookup table to blink an LED (D0) 3 times using a for-next-loop (I've never used a for-next-loop before). It works except after three cycles it doesn't stop. I read up that after the loop has finished it then moves on down to the next instruction, so I've added STOP / END. IF i = 4 then STOP. None of these work and when any of these lines are added the program only cycles once.
The only thing I can think of is that the 12F683 doesn't support LOOKUP tables.
Any ideas please? Dave
ANSEL = %00000000 'disable analog select so ports work as digital i/o
CMCON0 = %00000111 'Disable analog comparators
TRISIO = %11001111 'Set GPIO.4&5 to input
GPIO = %00000000 ' set all outputs low
i VAR BYTE
START
Main:
pause 500 'pause 500 mili-secs
For i = 1 to 3 ' loop count variable (value i) also number of times to loop.
LOOKUP i, [ 223, 223, 223] ,GPIO '223 = %11011111 D0 switches on (GPIO.4)
Pause 500 'pause 500 mili-secs
LOW GPIO.4 ' DO switches off
Next i ' loop again. ONE is added to count i and prog jumps to FOR
Hi,
I read "somewhere" a program might end by the " END " directive, or loop to a known label in the program...
Alain
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
Dave, use <code> tags and format your code - makes it easier to read.
Code:ANSEL = %00000000 'disable analog select so ports work as digital i/o CMCON0 = %00000111 'Disable analog comparators TRISIO = %11001111 'Set GPIO.4&5 to input GPIO = %00000000 ' set all outputs low i VAR BYTE START Main: pause 500 'pause 500 mili-secs For i = 1 to 3 ' loop count variable (value i) also number of times to loop. LOOKUP i, [ 223, 223, 223] ,GPIO '223 = %11011111 D0 switches on (GPIO.4) Pause 500 'pause 500 mili-secs LOW GPIO.4 ' DO switches off Next i ' loop again. ONE is added to count i and prog jumps to FOR
Hi Dave,
Two things.... First as you figured out and as Alain also pointed out you will need an END after the loop or the PIC will wonder off to never never land eventually starting over (I think). Second, you need another PAUSE in there or you will not see the LED blink. It will get turned on then 500ms later it will get turned off and then on again almost instantly as the loop goes back to the beginning. I guess that's what you were trying with the PAUSE right after Main but remeber that the loop starts over at the FOR statement.Code:Main: pause 500 'pause 500 mili-secs For i = 1 to 3 ' loop count variable (value i) also number of times to loop. LOOKUP i, [ 223, 223, 223] ,GPIO '223 = %11011111 D0 switches on (GPIO.4) Pause 500 'pause 500 mili-secs LOW GPIO.4 ' DO switches off Pause 500 Next i END
Henrik you are a star.....!
So I was pretty close then? I guess we wouldn't want to be flying in an aeroplane with any PIC'S in it I'd programmed just yet though...
Right, I'm off for some for-next-loop practice.
Cheers: Dave
So that's a code tag then, I really didn't know that...doh.Code:Testing 1.2.3.
Evening everyone.
I've been doing a lot of reading of late some beneficial some confusing.
I've decided to try and make a 12F683 turn an LED on when a button is momentarily pressed, then expand this further. I can see lots of possibilities in being able to make outputs do different things on receipt of an input/s.
Is something like this on the right lines?
I've put the driving a seven segment display using a 16F684 and part of two ports to on hold just for the minute.Code:IF GPIO.x = HIGH 'Button is pressed. THEN OUTPUT GPIO.x HIGH 'Turns LED on
David
Almost...
Take a look at this. From the manual...
http://www.melabs.com/resources/pbpmanual/5_32-5_35.htm
Dave
Always wear safety glasses while programming.
Hi David,
I think I smell what you are cooking, you want to send power to a port and then have it stay powered after you release the switch. I Used to install gun lock timers that were wired that way.
Try This UNTESTED CODE
Keep in mind there is no setup code appropriate to your PICCode:GPIO = %00000000 ' set all outputs as low TrisIo = %00000001 'make all outputs except GPIO.0 main: If GPIO.0 then unlock goto main unlock: Trisio.0 = 0 'changes to output GPIO.0 = 1 'sets port latch to high logic pause 30000 ' wait 30seconds GPIO.0 = 0 :TRISIO.0 = 1 ' Turn it off goto main end
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
Hi Joe,everyone. Sorry for the slow reply, it's been one of those days today.
Before I forget I loved the line: "I think I smell what you are cooking" It's had me smiling all day.
Joe, the program you wrote. I was happy with all of it except line four.I see you've made GPIO.0 an input
but the 'THEN' label hasn't been given a HIGH or LOW statement for the pin
To my mind (please be gentle with me I'm really green at this) it should be something like:Code:If GPIO.0 then unlock
Am I on the right lines here?Code:IF GPIO.0 = HIGH THEN UNLOCK ' GPIO.O goes HIGH (button pressed) jump to label UNLOCK. ELSE GOTO MAIN ' button not pressed do the loop again (not sure if I needed the GOTO here). Or maybe: IF GPIO.O = LOW THEN MAIN ' button not pressed, do the loop again
* Silly but important question here*: I'm confusing myself, can an INPUT be either HIGH or LOW?
I know an OUTPUT can be.
So your program is maybe a timed latching relay circuit or locking solenoid?
As for my program, I was thinking more along the lines that if GPIO.X goes high (a button is pressed +5v on that input pin) that would make an output on GPIO.Y go high. In other words the pressing of a button makes the program jump to some specified section of code making an output.
Then moving this idea on, if the button was pressed twice (within a certain time period say) you could 'jump' to another section of code and make a different output..
I hope you're all having a pleasant evening,
David
Last edited by LEDave; - 27th February 2010 at 22:16.
Now you will want to look at the COUNT command. Might be what you need for the button presses.
Dave
Always wear safety glasses while programming.
Cheers mackrackit, will do.
Reading the manual for me isn't such a bad idea after all....lol.
Can you help me with my:
* Silly but important question here*: I'm confusing myself, can an INPUT be either HIGH or LOW? I know an OUTPUT can be.
For the record I think it can be active HIGH or Low (but I'm not 100% sure).
Dave
When a pin is an INPUT it will read the pin's state. Either HIGH or LOW.
Yes, active H/L.
Dave
Always wear safety glasses while programming.
Cheers mackrackit.
Another question (I know but I am trying hard) In my PICkit1 there is a button attached, now I'm thinking that it goes onto pin GPIO.3 is that right.
So I could use that button to try out some programs using IF THEN and COUNT.
David
I do not have the PicKit1's docs with me, but yes. What ever pin it goes to you can use it that way.
Also, check the data sheet to see it the pin has anything "special" about it. MCLR??
Dave
Always wear safety glasses while programming.
I am always gentle
It does seem unintuitive doesn't it?
Got it straight from the manual though. If gpio.0 is set? goto unlock. As I understand it, it is a computed goto.
Where zero and one are representing False and true.
IF GPIO.0 is true, goto Label, without requiring endif or else statements.
Melanie posted some things which will interest you using multiple button presses to do different things:
try looking at these, open the links Melanie posted, especially the Olympic timer PDF:
http://www.picbasic.co.uk/forum/showthread.php?t=3423
http://www.picbasic.co.uk/forum/showthread.php?t=632
Oh yeah, that was for a shotgun lock for a police car, officer would turn a keyswitch, and it would stay energized long enough to access his weapon.
Last edited by Archangel; - 27th February 2010 at 23:23.
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
Cheers Joe, very interesting that regards the GPIO.0 computed GOTO. You can see why a newbie like me got a little confused, very handy piece of code though, thanks for the explanation.
I had a look at Melanie's Olympic timer, very impressive. She's one very clever lady.
I've always been an admirer of clever people.
Right, I'm off to my bed to dream of COUNTER - IF-THEN- ELSE IF commands.
Really enjoying this, I hope I'm not driving you all to mad?
David
Already been there. Had a lot of fun too!!!!I hope I'm not driving you all to mad?
Dave
Always wear safety glasses while programming.
Hi,
Just in case this isn't clear already....This is NOT how you you determine if an input is high or low. HIGH and LOW are commands that both sets the pin in question to "output mode" and then drives it either high or low. To check if a pin (or any bit in any register) is set you do either:Code:IF GPIO.0 = HIGH THEN UNLOCK
OrCode:If GPIO.1 = 1 THEN GOTO Unlock
OrCode:If GPIO.1 THEN GOTO Unlock
Right, back to HIGH and LOW... as have been said already the HIGH and LOW commands first sets the pin to "output mode" and then drives the pin high or low. It's nothing wrong with that except that it sets the pin to "output mode" each and every time either command is used. It doesn't matter if the pin already IS in "output mode" - it still writes to the TRIS register - every time and this wastes both time and codes space. It's much better to set the TRIS register manually and only change it if needed and then simply write to the Port or GPIO register directly.Code:If GPIO.1 = 0 THEN GPIO.2 = 1 Goto DoThis ELSE Goto Unlock ENDIF
/Henrik.
Hi Henrik, thanks for that. Being new to programming it's easy to get confused especially when many of the terms are so similar.
I'm a relatively slow learner too which doesn't help I guess. When I finally get it though, it does stick.
You've got to marvel the complexity contained within an eight pin microchip, staggering.
I can't wait to actually build something either.
Have a nice evening.
David
Hi everyone.
I'm working on my first circuit using the12F683 and I'd like to add a push button as an input. Would I be right in assuming that:
A pull-up resistor say 10k from the +5v line onto the chosen input GPIO.n and a push button connected from GPIO.n to ground should do the job?
This to my mind would leave GPIO.n at +5v until pressed, momentarily dropping to 0v.
David
Yup, that will work.
Dave
Always wear safety glasses while programming.
Cheers mackrackit.
My project, here's the master plan:
I'm going to use the 12F683 to output 4 bit words to drive a BCD to 7-segment decoder driver: Count up from 0-9 in a continual loop IF the push button is pressed THEN GOTO countdown from 9-0 in a continual loop, IF pressed again count down from 5-0 then stop.
This project covers a lot of the ground we've been over in the last week or two and would give me some much needed practical practice.
Another question: Is this program statement viable / do-able to provide input words into the decoder driver?
i VAR WORD
Main:
For i = 0 to 3 etc
LOOKUP i, [0, 1,2,3], GPIO
NEXT i
Sorry but the code tags didn't work tonight.
This would output from the PIC (I hope):
0000 making the driver display '0'
0001 " " '1'
0010 " " '2'
0011 " " '3'
1000 " " '4'
Also from the output side of the PIC ('words') to the input side of the display driver, I'd like to bleed off a little current to the base of four transistors with LED's in the collector leg to visually see the binary count, just for fun.
So what do we think then guys? Have I learned my lessons well, or am I heading for the books...!
David
Hi David,
That will work for exercise purposes but in the above case there's really no need for the LOOKUP table. You can just as well write i directly to GPIO, you'd also want a PAUSE in there or it will count really fast, and don't forget to set the TRIS-register to make the pins in question outputs:Code:i VAR WORD Main: For i = 0 to 3 etc LOOKUP i, [0, 1,2,3], GPIO NEXT iCode:Main: For i = 0 to 3 GPIO = i Pause 500 NEXT iNot quite, it will count (and display) 0, 1, 2 and 3 since 3 is what you have in your FOR statement. Actually i will get incremented one more time, to 4, but when that happens the code will jump to after the NEXT statement so the "4" will never make it to GPIO. (If that last thing didn't make sense never mind, the important thing is that it counts from 0 to 3.)0000 making the driver display '0'
0001 " " '1'
0010 " " '2'
0011 " " '3'
1000 " " '4'
/Henrik.
Hi Henrik
So to get the program to count down from 9-0 would this do it:
FOR i = 9 to 0 STEP -1
GPIO = i
Pause 500
NEXT i
*I don't know why but I my code tags still aren't working tonight, sorry*
If GPIO = 9 then out would go 1001 to the driver etc...
Yes, without the pause it would have counted to 3 lightning fast I guess.
The LOOKUP table is excellent for outputting stored values though, really glad we touched on it.
Last edited by LEDave; - 1st March 2010 at 22:14.
Hi,
Yes, that is correct - all of it. Good job!
All BBTags uses square brackets, ie. [...] and [/...] to turn the option ON and OFF respectively. Seems to work from here. There's a box at the bottom of the page showing if BBCode is ON or OFF, make sure it's ON.
/Henrik.
Henrik thanks for that.
I'm trying to use the COUNT command that mackrackit put me onto to jump from one loop to the next after a button is pressed. There are three loops (count up to nine when button pressed once - Jump to second loop and count down from nine if button pressed a second time and to a final third loop, count down from five after button is pressed a third time).
Is this code anywhere near to where I need to be? If I'm close but not quite there please let me carry on thinking. If I'm miles off course then a pointer would be much appreciated.
My code tags are working today, I didn't touch anything.Code:COUNT PIN.n, 10000, VAR B_P_C WORD 'Set GPIO.n as input, define Button Push Count as VAR WORD B_P_C, with a loop count time of 10 secs. Let i = B_P_C IF B_P_C = i GOTO FIRSTLOOP ' Button pressed once IF B_p_c = i+i GOTO SECONDLOOP ' Button pressed twice IF B_P_C = i+i+i Goto THIRDLOOP ' Button pressed a third time
David
Last edited by LEDave; - 2nd March 2010 at 14:58.
Hi,
Not quite sure I understand. Are you saying that you want it to execute one of the three loops depending on how many times the butten is pressed within a certain amount of time? Or are you saying that you want to execute the three loops, one after the other, but to wait for a button press between the loops?
In any case, I'm afraid what you have there ain't gonna work....
The above will define a 16 bit variable called B_P_C and then immediatley start counting how many times the button connected to GPIO.5 is pushed. It will keep counting for 10 seconds (10000mS) after which it continues in the program.Code:B_P_C VAR WORD COUNT GPIO.5, 10000, P_B_C
What this does is to say that i should be assigned whatever value B_P_C is. So, after this is exectued i has the same value as B_P_C, provided i is declared the same size as B_P_C - a WORD in this case.Code:Let i = B_P_C
Now, since i is the same as B_P_C (it is because you told it to be) the only condition that can ever be true is the first one.Code:IF B_P_C = i GOTO FIRSTLOOP ' Button pressed once IF B_p_c = i+i GOTO SECONDLOOP ' Button pressed twice IF B_P_C = i+i+i Goto THIRDLOOP ' Button pressed a third time
/Henrik.
PS. Pushbuttons are quite "bouncy", the COUNT command may register several counts even though you only push the button once.
Last edited by HenrikOlsson; - 2nd March 2010 at 17:32.
Cheers Henrik. The idea is to run the first loop when the button is pressed, if the button is pressed again the counter would count two button pushes and run / goto loop two, if pressed three times would goto loop three, run that loop then stop.
Somehow I need to get the button pushes to increment a counter: One push = run loop1 two pushes = run loop2 three pushes = run loop3....then Stop until button pressed again.
Is there anyway when a button is pressed to just count how many times that's happened then jump to a given loop without the count timer running?
Thanks for your help.
David
Hi,
You say that if the button is pressed one time it should run the first loop - no problem there. But how fast should you need "double-click" or "tripple-click" it in order to run the second or third loop instead of the first one? Or should it run the first loop as soon as it sees a button press and THEN wait for the button the be pressed again?
With the count command but you need to understand that it counts for a certain amount of time during which nothing else will get executed, once that time has passed (10000ms in your case) the code will continue.
So, your idea was on the right track but the implementation had a couple of problems as explained in my previous message. Here's ONE aproach to the single, double, triple-click solution but remember that it might not work in reallity due to the switch bouncing as described before.
Let's say your button pulls the input low when pushed.Now, wire it up, compile the code, program the chip and GIVE IT A TRY! ;-) If there's still "basic" stuff that you don't understand then you need to back up and get that sorted first or you will just be creating more problems for yourself. Perhaps we jumped to the LOOKUP and COUNT commands etc a little too soon(?).Code:B_P_C VAR BYTE WaitForButton: If GPIO.5 = 1 THEN GOTO WaitForButton 'Button is not pressed, go back and check again PAUSE 10 'Wait a little while for the contact bouncing to die WaitForRelease: If GPIO = 0 THEN GOTO WaitForRelease 'Loop here until button is relased COUNT GPIO.5, 1000, B_P_C 'Count number of presses for during one second IF B_P_C = 0 THEN GOTO FirstLoop 'Remember, we had to press the button once to get here. If B_P_C = 1 THEN GOTO SecondLoop If B_P_C = 2 THEN GOTO ThirdLoop 'First one press, then two more as counted by the COUNT-command. Goto WaitForButton 'Start over if number of presses is more than 3 FirstLoop: 'Your code here Goto WaitForButton SecondLoop 'Your code here Goto WaitForButton ThirdLoop: 'Your code here Goto WaitForButton END
/Henrik.
Henrik first of all a big thank you for giving your time to help me along (and everyone else too of course).
I agree, I do need to back up and go over some of the basics we've covered, like you say running before you can walk with programming will only compound problems later on.If there's still "basic" stuff that you don't understand then you need to back up and get that sorted first or you will just be creating more problems for yourself. Perhaps we jumped to the LOOKUP and COUNT commands etc a little too soon(?).
I think I need to write lots of short programs using the basics and do enough of them to really drive it home.
That said, I do understand the basic principle of the COUNT command and it's timing component also with the LOOKUP command.
When you think that trying to use C and assembler I hadn't even managed to switch an LED on! I've come a long since joining this forum and using PB in the last few weeks thanks to you all, there's absolutely no doubt that this in the language to use!
So no, time to build this circuit (I need to make something work) and I'm sure I'll still have plenty of questions for you about the basics still, so you're not of the hook quite yet....;-)
David
No problems, we're all here to help.So no, time to build this circuit (I need to make something work) and I'm sure I'll still have plenty of questions for you about the basics still, so you're not of the hook quite yet....;-)
Bookmarks