Вот что нашёл касательно ручного управления сервомотором с помощью потенциометра (см. пост выше). Как мне кажется, очень близко к тому, что нужно (PIC16F877A):
Название: Running small motors with PIC microcontrollers Автор: Harprit Singh Sandhu Год: 2009 Страниц: 352 Формат: pdf Размер: 2,72 MB Описание: Программирование микроконтроллеров PIC для з
// pic.rkniga.ru
TURNING POTENTIOMETER TO CONTROL MOTOR
Program 15.3 also demonstrates one of the ways in which a potentiometer (in this case acting as an error signal) can control the position of an encoded motor. In our case the potentiometer provides a count of up to 255 so we can move the motor about three turns (as set up with the 42-slot encoder, each slot in the encoder gives us two counts because the PIC 18F4331 has been set to read both the rising and falling edge of the signal).
If we want the motor to move more than three turns, we can use a multiplier to
change the value read from the potentiometer, but we are still limited to the 255 dif-ferent positions that the potentiometer provides. (We can also read the potentiometer as a 10-bit variable, which will give a reading of from 0 to 1023.)
As we add or subtract the potentiometer reading from the register that contains the
encoder counts to bring the motor to its set position, we have a rudimentary motor
control algorithm. Of course there are many improvements to be made, but basically
that is what we are trying to do with all programs that control encoder coupled
motors.
Program 15.3 provides the rudimentary control needed to hold a motor on an encoder position as just described. Later programs modify this code to add the features and refinements we have been discussing. As you turn the potentiometer further and
further, the motor moves further and further—that is, it follows the potentiometer. The motor moves because the potentiometer position is being added to the target register (not the position register) each time through the loop. It is not cumulative. The LCD display shows the contents of the four low bits of PORTC and the 16-bit position register and the gain so we can see what is going on.
What we have is a simple motor position controller operated from a potentiometer.
This would be an easy way to move a controlled device in a laboratory set up. With a few wire extensions you could also do the following:
- Move a control lever remotely
- Open and close a motorized gate
- Remove yourself from a dangerous environment
- Turn a knob or a steering wheel on a car with a large servo
- Control one axis of the orientation of a remote camera
- Use the remote motor as a general purpose positioning servo
The controlling input does not have to be the potentiometer; any of the methods that we have at our disposal to read resistances, capacitances, frequencies, and so on with the 16F877A can be used as the input signal. We can use a hobby R/C signal to create a remotely operated radio controlled system.
Let us modify the control algorithm to add one to the gain during each pass through
the zeroing loop (integrating the gain) if the motor is not at its home position. This will make the motor move to its target position more and more strongly each time through the loop if is not at the target position. If unrestrained, the gain will again cause the motor to over control and go into oscillations. You can watch the position and the gain on the LCD as you move the motor shaft back and forth. Note that, as always, the gain has to be limited to 255 to keep the gain byte from overflowing. It may also have to be limited to a less aggressive value to prevent over control.
Program 15.3 Hold position, proportional gain with integration added.
Sophisticated “holding a motor on position” program. Potentiometer value is added
to the motor target position.
code text
CLEAR ; clear memory
DEFINE OSC 20 ; 20 MHz clock (40 better)
DEFINE LCD_DREG PORTD ; define LCD connections
DEFINE LCD_DBIT 4 ; 4 data bits
DEFINE LCD_BITS 4 ; data starts on bit 4
DEFINE LCD_RSREG PORTE ; select register
DEFINE LCD_RSBIT 0 ; select bit
DEFINE LCD_EREG PORTE ; enable register
DEFINE LCD_EBIT 1 ; select bit
LOW PORTE.2 ; set bit low for writing to the LCD
DEFINE LCD_LINES 2 ; lines in display
DEFINE LCD_COMMANDUS 2000 ; delay in μs
DEFINE LCD_DATAUS 50 ; delay in μs
DEFINE ADC_BITS 8 ; set number of bits in result
DEFINE ADC_CLOCK 3 ; set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ; set sampling time in μs
DEFINE CCP2_REG PORTC ; hpwm 2 pin port
DEFINE CCP2_BIT 1 ; hpwm 2 pin bit 1
CCP1CON=%00111111 ; set status register
TRISA =%00011111 ; set status register
LATA =%00000000 ; set status register
TRISB =%00000000 ; set status register
LATB =%00000000 ; set status register
TRISC =%00000000 ; set status register
TRISD =%00000000 ; set status register
ANSEL0=%00000001 ; page 251 of data sheet, status
; register
ANSEL1=%00000000 ; page 250 of data sheet, status
; register
QEICON=%10001000 ; page 173 counter set up, status
; register
INTCON=%00000000 ; set status register
INTCON2.7=0 ; set status register
;
POSITION VAR WORD ; set variables
TARGET VAR WORD ; set variables
MOTPWR VAR WORD ; set variables
POTVALUE VAR BYTE ; set variables
INTPWR VAR BYTE ; set variables
PORTC.0=0 ; break off, motor control
PORTC.1=0 ; PWM bit for Channel 2 of HPWM
PORTC.2=0 ; PWM bit for Channel 1 of HPWM
PORTC.3=1 ; dir bit for motor control
PAUSE 500 ; LCD start up pause
LCDOUT $FE, $01, "START/CLEAR" ; clear message
PAUSE 100 ; pause to see message
POSCNTH=125 ; set counter for encoder, H bit,
; 32000
POSCNTL=0 ; set counter for encoder, L bit
;
LOOP: ; main loop
ADCIN 0, POTVALUE ;
POSITION=256*POSCNTH + POSCNTL ; read position registers
TARGET =32000 +POTVALUE ; add pot value to position
SELECT CASE TARGET ;
CASE IS= POSITION ; at 32000
MOTPWR=0 ; turn off motor
INTPWR=0 ; zero integral gain
HPWM 2, 0, 20000 ; C.1 PWM signal, stop motor
CASE IS< POSITION ; under count
PORTC.3=0 ; set direction fwd
MOTPWR=POSITION- TARGET +10 ; set motor gain
CASE IS> POSITION ; over count
PORTC.3=1 ; set direction reverse
MOTPWR= TARGET –POSITION +10 ; set motor gain
CASE ELSE ; empty
END SELECT ; end decision
IF POSITION<>TARGET THEN INTPWR=INTPWR +1 ; add 1 to
; integral gain
IF INTPWR>90 THEN INTPWR=90 ; limit integral fn to 90
MOTPWR=MOTPWR +INTPWR ; add integral to motor gain
IF MOTPWR>255 THEN MOTPWR=255 ; allow half of full power
HPWM 2, MOTPWR, 20000 ; C.1 PWM signal
LCDOUT $FE, $80, "PRTC=",BIN4 PORTC," GAIN=",DEC3 MOTPWR
; display
LCDOUT $FE, $C0, "POS =",DEC5 POSITION+POTVALUE ; display
GOTO LOOP ; go back to loop
END ; all programs must end with END