Skip to content
Snippets Groups Projects
Commit 227b79be authored by Martin Vítek's avatar Martin Vítek
Browse files

Add servo & potenciometr class

parent 0fcc8dd9
No related branches found
No related tags found
No related merge requests found
......@@ -29,6 +29,12 @@ add_definitions("-std=c++14")
set(SOURCE_FILES
main.cpp
irq.cpp
irq.h
Potenciometr.cpp
Potenciometr.h
servo.cpp
servo.h
)
include_directories(libs/src)
......
#include "Potenciometr.h"
Potenciometr potenciometr;
#pragma once
#include <stdint.h>
#include <avr/io.h>
class Potenciometr
{
private:
enum
{
ADC_BUFFER_SIZE = 10
};
volatile uint8_t attempt;
public:
volatile uint16_t buffer[ADC_BUFFER_SIZE];
volatile uint16_t adc_value;
public:
Potenciometr()
{
adc_ini();
};
void adc_ini()
{
//55kHz, 2.56V reference
ADMUX = (1<<REFS1) | (1<<REFS1);
ADCSRA = (1<<ADEN) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1);
//cca 13Hz
TCCR0 = (1<<CS01) | (1<<CS00);
TIMSK |= (1<<TOIE0);
};
void irq_handler()
{
buffer[attempt++] = ADC;
if(attempt >= ADC_BUFFER_SIZE)
{
uint16_t adc_sum = 0;
for (uint8_t i = 0; i < ADC_BUFFER_SIZE; i++)
{
adc_sum += buffer[i];
}
adc_value = adc_sum / ADC_BUFFER_SIZE;
attempt = 0;
}
};
void start_conversion()
{
ADCSRA |= (1<<ADSC);
};
};
extern Potenciometr potenciometr;
#include "irq.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "Potenciometr.h"
ISR(ADC_vect)
{
potenciometr.irq_handler();
}
ISR(TIMER0_OVF_vect)
{
potenciometr.start_conversion();
}
ISR(USART_RXC_vect)
{
}
#pragma once
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(ADC_vect);
ISR(TIMER0_OVF_vect);
ISR(USART_RXC_vect);
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"
#include "Potenciometr.h"
#include "servo.h"
static usart_regs registers
{
&UCSRA,
......@@ -13,8 +19,33 @@ static usart_regs registers
usart uart(registers);
static servo_data blue_servo_data
{
220, //0°
2200, //180°
10000, //ICR_value
20000 //Pulse_duration
};
servo_class servoL(&DDRB, PB1, &OCR1A, blue_servo_data);
servo_class servoR(&DDRB, PB2, &OCR1B, blue_servo_data);
void servo_ini()
{
TCCR1A |= (1<<COM1A1) | (1<<COM1B1) | (1<<WGM11); //Fast PWM non-inverted
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS11); //Prescaler 8 -> 7.03Hz
ICR1 = 10000; //Top value -> 46.04Hz
servoL.set_angle(120);
servoR.set_angle(30);
}
int main(void)
{
sei();
uart.set_operating_mode(uart.ASYNCHRONOUS_NORMAL);
uart.set_baudrate(115200);
uart.set_data_bits(8);
......@@ -24,8 +55,23 @@ int main(void)
uart.transmit_string("\nServo headlight control\n");
servo_ini();
char angle;
for(;;)
{
angle = potenciometr.adc_value/5;
uart.transmit_dec32(potenciometr.adc_value);
uart.transmit_char('\t');
uart.transmit_dec32(angle);
uart.transmit_char(248);
uart.transmit_new_line();
servoL.set_angle(angle);
servoR.set_angle(angle);
_delay_ms(50);
}
}
\ No newline at end of file
/*
* sevoclass.cpp
*
* Created on: 27. 6. 2014
* Author: martin.vitek
*/
#include "servo.h"
#include <avr/io.h>
#include <stdint.h>
servo_class::servo_class(volatile uint8_t *ddr,
uint8_t bit,
volatile uint16_t *ocr,
servo_data &data):data(data)
{
this->ddr = ddr;
this->bit = bit;
this->ocr = ocr;
*ddr |= (1<<bit);
this->data = data;
one_step = data.pulse_duration / data.ICR_value;
one_degree_pulse = (data.max_duration - data.min_duration) / 180;
//set_angle(90);
}
servo_class::~servo_class()
{
*ddr &= ~(1<<bit);
}
void servo_class::set_angle(uint8_t angle)
{
if (angle < 0) current_angle = 0;
else if (angle > 180) current_angle = 180;
else current_angle = angle;
*ocr = (data.min_duration + (one_degree_pulse * current_angle) ) / one_step;
}
/*
* sevoclass.h
*
* Created on: 27. 6. 2014
* Author: martin.vitek
*/
#pragma once
#include <avr/io.h>
#include <math.h>
#include <stdint.h>
struct servo_data
{
//Min a max doba kontroln�ho pulzu v us
uint16_t min_duration;
uint16_t max_duration;
//Parametry PWM
uint16_t ICR_value;
uint16_t pulse_duration;
};
class servo_class
{
//Prom�nn�
private:
volatile uint8_t *ddr;
uint8_t bit;
volatile uint16_t *ocr;
uint8_t current_angle;
servo_data &data;
uint8_t one_step;
uint8_t one_degree_pulse;
//Metody
public:
//Konstruktor
servo_class(volatile uint8_t *ddr, uint8_t bit, volatile uint16_t *ocr, servo_data &data);
//Destruktor
~servo_class();
//Metody
void set_angle(uint8_t angle);
uint8_t get_angle() { return current_angle; };
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment