Controlling a servo with a potentiometer
subratasarkar20
c_cpp
a year ago
2.0 kB
9
Indexable
/*
* ADC_Servo.cpp
* Author: subrs
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
void ADC_Init()
{
ADMUX = (1 << REFS0); // AVCC as reference, ADC0 selected
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // Enable ADC, set prescaler to 64 (for 1MHz clock)
}
uint16_t ADC_Read(uint8_t channel)
{
ADMUX = (ADMUX & 0xF8) | (channel & 0x07); // Select the ADC channel (in this case, channel 0 for the potentiometer)
ADCSRA |= (1 << ADSC); // Start conversion
while (ADCSRA & (1 << ADSC)); // Wait for conversion to complete
return ADC; // Return the ADC result (10-bit value)
}
void setupPWM()
{
// Set Fast PWM mode with ICR1 as TOP (Mode 14: WGM13:WGM10 = 14)
TCCR1A = (1 << WGM11);
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11) | (1 << CS10); // Prescaler = 64
// Set non-inverting mode on OC1A (Clear OC1A on compare match, set at BOTTOM)
TCCR1A |= (1 << COM1A1);
// Set TOP value for 50Hz (ICR1 = 311)
ICR1 = 311;
// Set PD5 (OC1A) as output for PWM signal
DDRD |= (1 << PD5);
}
void setServoPosition(int pulseWidth)
{
// Set the OCR1A register for the specified pulse width
OCR1A = pulseWidth;
}
int main(void)
{
// Initialize ADC and PWM for controlling the servo
ADC_Init();
setupPWM();
uint16_t adc_value;
int pulseWidth;
while (1)
{
// Read the ADC value from the potentiometer (channel 0)
adc_value = ADC_Read(0);
// Map the ADC value (0 - 1023) to pulse width for the servo (1ms to 2ms)
pulseWidth = (adc_value / 57) + 16; // (1024 / 180) + 16 => Pulse width between 16 and 31
setServoPosition(pulseWidth); // Set the servo position
_delay_ms(50); // Small delay for stability
}
}
Editor is loading...
Leave a Comment