PDA

View Full Version : A/D, Pot, Input, A,B So lost now....



Helmutt
- 9th March 2008, 08:54
1st off I would like to say thank you to all for these forums, It has helped me solve many many issues so far.

I am new to the PIC world but have made leaps and bounds so far.

Ok. What I am trying to do is control the limits of a servo based on the position of two pots. To give a whole over view of the application I am trying to make a replacement power valve controller for a 2 stroke motorcycle. This being my 1st real Pic project, Im having more than my fare share of issues, but working through them, so any help is greatly appreciated.

Im trying to use 16f690 chip because I think I need the AD converter to handle the pot command.

But so the simplified version of the code I am going with is. I am still struggling with the RPM pick up, but one problem at a time. I am replacing the RPM input with a simple low high switch to help simplify testing. I know this isn't the fastest code method due to the pulse pause, but... It should be well quick enough.

Servo VAR Portc.5 'The servo being used is a Futaba Digital RC Servo.
Scale VAR Byte
Pulse VAR Byte
RinTot VAR Porta.2
Potin VAR Porta.4
potvar VAR Byte
RPMin VAR portc.4
RPM VAR Word


POT RinTOT, 255, Scale 'According to docs. By setting the scale to 255, then useing the max resistance of the pot it will give a correct scale? Store this on start up to use later.


Loop:
POT Potin, Scale, potvar
IF RPMin=1 THEN
PULSOUT Servo, potvar 'I should only get a useable value between 100-200, so effectively limiting my pot, through, I droped the scaling until I could get this fixed.
PAUSE 18 'The pause for the servo input.
ELSE
PULSOUT Servo, 100 'Go back to the lowest pulse position.
PAUSE 18
ENDIF
GOTO Loop
END

Ok so I get servo active and locked, if I change it to go to a fixed pulse time on RPM press it works. But once the pot is added in I get nothing. I am probably making a really dumb mistake. So if you do help, Thank you.

I have read so many different ways of doing this I am very very lost now. I tried some functions with the A/D converters but didn't get very far. Then I read many different approaches to converting the Pot to something useable. Tried some plug and drop in methods, with other code.. So maybe its my way of wiring. Both of my reference books I use have two totally different ways of doing it. So I'm very very confused now. SO again Thank you.

I drew how I was wiring the pot in if I am screwing that up as well :(, But I am horrible at drawing on a computer so its pretty rough, but gives the idea.

Thank you all so very much for even taking the time to look at this.

skimask
- 9th March 2008, 09:00
Ok. What I am trying to do is control the limits of a servo based on the position of two pots.
Sounds exactly like this other thread out there recently...


Im trying to use 16f690 chip because I think I need the AD converter to handle the pot command.
PBP manual says it gets the POT value by charging up an external, then measuring the time it takes to discharge to a low logic level...on a digital input pin.
I think you'd be better off using an analog input and some ADC type commands and registers.
Besides, if you're using POT, you'll be at the mercy of your capacitor...which are notorious for having very wide tolerances.
If you set your potentiometer up as a simple voltage divider, you'll get much more accurate results, and repeatable.
The POT command is a holdover from way back when, and not a very good command in my opinion.

Code from another thread using a 12F675...
Uses a couple of switches and pot to set some endpoints...
Change the registers over to '690 equals and make something out of it...


@ DEVICE pic12F629, INTRC_OSC_NOCLKOUT ; Using Internal Clock, no clock out
@ DEVICE pic12F629, WDT_ON ; Enable Watch dog timer
@ DEVICE pic12F629, PWRT_ON ; Enable Power-up timer
@ DEVICE pic12F629, MCLR_OFF ; Disable MCLR pin
@ DEVICE pic12F629, BOD_ON ; Enable Brown-out detect
@ DEVICE pic12F629, CPD_OFF ; EEPROM Protect
@ DEVICE pic12F629, PROTECT_OFF ; Code Protect off
TRISIO = %11111110
INTCON.6=0 ' Disable all unmasked Interrupts
INTCON.7=0 ' Disable Global Interrupts
CMCON = 7 ' Disable analog comparator
ServoOut var GPIO.0
SetLimitSw var GPIO.1
PotIn var GPIO.2
MinSw var GPIO.4
MaxSw var GPIO.5
wPosit var word
Posit var byte
MinPosit var byte
MaxPosit var byte
'load starting min and max positions
data @ 0, 100
data @ 1, 250
'************************************************* ***************
low Servoout
'read in stored min and max limits
read 0, MinPosit
read 1, MaxPosit
'for power-on reset of positions:
if minsw = 1 then
minposit = 100
write 0, minposit
endif
if maxsw = 1 then
maxposit = 250
write 1, maxposit
endif
pause 1000
Start:
gosub GetServoPosition
pulsout servoout, posit
pause 20
if setlimitsw = 1 then 'check min max buttons
if minsw = 1 then
MinPosit = Posit
write 0, MinPosit
pause 250
endif
if maxsw = 1 then
MaxPosit = Posit
write 1, MaxPosit
pause 250
endif
endif
goto start
'************************************************* ***************
GetServoPosition:
high potin
pause 1
rctime potin, 1, wPosit 'at 4 mhz, returns 0 - 120
'adjust posit to get values between 75 and 250
'use word-sized variable because calculation might exceed 255
wposit = wposit + 75 + (wposit / 2)
'now limit posit to 100 - 250 (1 ms - 2.5 ms)
'and put into byte-sized variable
if wposit > 250 then
posit = 250
else
posit = wposit
endif
if posit < 100 then posit = 100
if setlimitsw = 0 then 'apply limits
if Posit < MinPosit then Posit = MinPosit
if Posit > MaxPosit then Posit = MaxPosit
endif
return
'************************************************* ***************

Kamikaze47
- 9th March 2008, 09:10
Wow, skimask, you must _live_ on this forum :)

skimask
- 9th March 2008, 09:11
Wow, skimask, you must _live_ on this forum :)

Nope, just passing by every few minutes in-between work benches and/or projects... Keyboard is at waist level. Easy to type...

Helmutt
- 9th March 2008, 18:54
wow, thanks for the reply.

But damn now Im lost.

Can I just read the AD converter value to a byte? Then use that as my pulse out. I think thats what that code above is doing, but also applying some limits and boot up procedures.

I guess where Im getting most lost is how do I define what I am using on that pin? Or Will it just read what ever it wants to? Do I have to write it to a data spot or can I just use it as a variable?

Servo VAR Portc.5
Potin VAR AD.4 ' Can I do that? Or Do I call it something else to call the AD converter inside the pin.
PULSE VAR BYTE


Loop:
READ AD.4, Pulse
PULSOUT Servo, Pulse
Pause 18
Goto Loop

Thanks again, Sorry I am new at this. Im trying.

EDIT: Ok so super noob question, Is there a difference between calling a PIN by GPIO.? versus Porta.? or Pin 5. I get the port/pin references but I can seem to figure out where the GPIO comes from.

Archangel
- 9th March 2008, 19:06
EDIT: Ok so super noob question, Is there a difference between calling a PIN by GPIO.? versus Porta.? or Pin 5. I get the port/pin references but I can seem to figure out where the GPIO comes from.
Hello Helmutt,
Yes, GPIO is for the PICs that have GPIO like the 12fseries as they only have 1 port. PortA, B, C are assigned to the ports you actually have. I E. a 16F628a has 2 ports, A & B, whereas another PIC might have several more A B C D . . .

Helmutt
- 9th March 2008, 19:14
Ah cool, Finally stopped skipping over the 12 pin section and found that out. Thank you.

skimask
- 9th March 2008, 22:23
Can I just read the AD converter value to a byte? Then use that as my pulse out. I think thats what that code above is doing, but also applying some limits and boot up procedures.
Easy way...if you left justify the results, you can use the high byte of the result and use the upper 8 bits (low 2 bits ignored), if you right justify, you read both high and low byte of ADRES into a word

As far as how to use the A/D converter, read the manual. There's an example in there, and while it doesn't fit all scenarios, it fits many of them.