Skip to content

Instantly share code, notes, and snippets.

@lopesivan
Forked from tokolist/gist:8319281
Created October 16, 2017 13:22
Show Gist options
  • Save lopesivan/6b26412f0c674ca029cf469aff577a75 to your computer and use it in GitHub Desktop.
Save lopesivan/6b26412f0c674ca029cf469aff577a75 to your computer and use it in GitHub Desktop.
Use an AVR Microcontroller and Potentiometer to Control a Servo (ADC and PWM) http://youtu.be/vNwx_W2daJs
#define F_CPU 16000000 //16MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
//#include <stdio.h>
//#include "uart/uart.h"
#define PWM_PRESCALLER 64
#define ICR_MAX (long double)F_CPU/PWM_PRESCALLER/50
#define OCR_MIN ICR_MAX/20
#define OCR_MAX ICR_MAX/10
//char uart_s[150];
volatile unsigned long adc_val=0;
volatile unsigned long counter=0;
unsigned long curr_adc=0;
ISR (ADC_vect)
{
adc_val += ADC;
counter++;
}
int main(void)
{
//uart_init(uart_calc_ubrr(F_CPU));
DDRB |= (1<<DDB1);
ICR1 = ICR_MAX;
OCR1A = OCR_MIN;
TCCR1A = (1 << COM1A1) | (1<<WGM11);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11) | (1<<CS10);
ADMUX = (1 << REFS0);
ADCSRA = (1 << ADEN)|(1 << ADFR)|(1 << ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
sei();
ADCSRA |= (1<<ADSC);
while(1)
{
if(counter >= 500)
{
cli();
unsigned long round_val = round(adc_val / counter);
adc_val=0;
counter=0;
if(abs(round_val - curr_adc) > 1)
{
curr_adc = round_val;
}
long double ocr = OCR_MIN + ((long double)curr_adc * (OCR_MAX - OCR_MIN)/1024);
/*sprintf(uart_s, "ADC = %8lu, OCR = %f, rounded = %d\r\n", curr_adc, ocr, (int)round(ocr));
uart_send_string((unsigned char*) uart_s);*/
OCR1A = (int)round(ocr);
//_delay_ms(100);
sei();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment