While the stepper motor could be completely computer-controlled, I'd like to be able to change the speed of the motor by turning a dial. for this i'm using a linear potentiometer from radioshack (10kohm, RadioShack #271-1715.) I'll read the voltage off of the middle pin -- turning the potentiometer will cause this middle-pin voltage to swing from ground to +Vcc (5v in my case). I will read this voltage in via the PIC's analog-to-digital converter and control the motor's speed accordingly.
mounting of potentiometer
the potentiometer has a nice 5/16" threaded shaft. I drilled a 5/16" hole on my project board and mounted the pot directly to the board. the outside pins are connected to +Vcc and Gnd respectively. The middle pin is connected to the AN0 pin on the PIC.
PIC Code
I use the CCS PCH compiler (for PIC18F series chips). Here is the code I used to test the analog-to-digital converter for the speed dial control.
CODE:
// Author: Andrew Wilson
// Date: 6/28/2006
// Description: This program will control a stepper motor driver circuit.
// it will monitor two inputs: analog potentiometer, and digital rpm sensor
// the program will ramp the speed output of the motor depending on the
// position of the potentiomenter. the rpm sensor will be used to ensure the
// correct speed is maintained.
#include <18F2520.h>
#include "stepper_driver.h"
#fuses INTRC, NOWDT, NOLVP
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PC)
int main()
{
int16 v_reading; //the pic18f2550 has a 10-bit A-to-D converter
//this gives 1024 possible steps
printf("Stepper Motor Interface v1, brought to you by:\n\r");
printf("Andrew Wilson\n\r");
printf("reconnsworld.com\n\r");
//this sets up PIN A0 as an analog-in pin.
//it is OR'd with VSS_VDD which forces the pic to use
// ground and VDD as reference voltages
setup_adc_ports(AN0_TO_AN1 || VSS_VDD);
//this (i think) sets the ADC to clock via the internal
//instruction clock
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(1); //we will only be using this channel
//no need to set it again.
while(1)
{
v_reading = read_adc();
printf("Reading is: %4lu; for an approximate voltage of: %5f\n\r", v_reading,
(5.0*(((float)v_reading)/((float)MAX_READING))));
delay_ms(100);
output_toggle(PIN_A0);
}
return 1;
}
now, for some reason I could not get the 18F2550.h file to work, so I temporarily used the 18F2520.h file. This lets me set the INTRC fuse, but I think it's messing with my analog to digital conversion, as I can only get 8 bits of data back from the converter.
here is the sample output (I verified the output on an oscilloscope, btw):
Reading is: 98; for an approximate voltage of: 1.921568
Reading is: 99; for an approximate voltage of: 1.941176
Reading is: 98; for an approximate voltage of: 1.921568
Reading is: 99; for an approximate voltage of: 1.941176
Reading is: 98; for an approximate voltage of: 1.921568
Reading is: 99; for an approximate voltage of: 1.941176
Reading is: 255; for an approximate voltage of: 5.000000
Reading is: 255; for an approximate voltage of: 5.000000
Reading is: 255; for an approximate voltage of: 5.000000
Reading is: 255; for an approximate voltage of: 5.000000
Reading is: 255; for an approximate voltage of: 5.000000
Reading is: 255; for an approximate voltage of: 5.000000
Reading is: 0; for an approximate voltage of: .000000
Reading is: 0; for an approximate voltage of: .000000
Reading is: 0; for an approximate voltage of: .000000
Reading is: 0; for an approximate voltage of: .000000
Reading is: 0; for an approximate voltage of: .000000
Download
Click here for the main.c
Click here for the header file
Click here for the hex file