Guten Abend an alle,
es geht darum, einen Reely S0008 servo über einen Atmega 328PB zu
steuern.
Der Servo wird über eine PWM, welche mittels TIMER1 CTC mode erfolgt,
angesteuert.
Steuerung klappt wunderbar. Das habe ich mit einem Oszilloskop getestet.
Allerdings habe ich folgendes Problem:
Ich möchte mit einem Taster (an PD3) bei Tastendruck den Servo um ca. 5°
weiterdrehen, ausgehend von einer beliebigen Ausgangsstellung. Für jeden
Tastendruck soll der Servo also quasi um 5° weiterfahren bis er eine
Endstellung x erreicht hat.
Das Problem ist, dass bei Tastendruck teilweise zufällig Schritte
übersprungen werden. Statt einmal zu incrementieren, incrementiert er
teilweise 2 oder dreimal. Manchmal klappt es aber auch. Leider habe ich
nicht direkt rausgefunden an was dies liegt. Ich arbeite hier mit einem
externen Interrupt. Auch eine delay im interrupt bringt keine Abhilfe.
Vielleicht hat jemand von euch hier einen Tipp, was das Problem ist. Am
Oszilloskop sieht man sehr schön, wie er teilweise einfach doppelt
incrementiert. Anbei noch der Code.
Ich danke euch schon mal im Voraus.
1 | #define F_CPU 16000000UL //define CPU frequency 16Mhz
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <util/delay.h>
|
5 |
|
6 |
|
7 | int main(void)
|
8 | {
|
9 | DDRD |= (1<<PORTD5); //set PD5 to output
|
10 | DDRD &=~(1>>PORTD3); //set PD3 to input to increment OCR1A value for servo movement
|
11 | PORTD |= (1<<PORTD3); //activate internal pull-up resistance
|
12 | TCCR1A = 0; //no OCnx value is used
|
13 | TCCR1B |= (1<< WGM12) | (1<<CS11); //set CTC mode and prescaler to 8;
|
14 | TIMSK1 |= (1<< OCIE1A); //enable compare match at OCR1A
|
15 | EIMSK |= (1<<INT1); //activate external interrupt INT1 at PD3
|
16 | EICRA |= (1<<ISC11); //activate external interrupt in case of falling edge
|
17 | OCR1A = 2000; //set OCR1A to get the selected positive pulse width
|
18 | sei();
|
19 |
|
20 | while (1)
|
21 | {
|
22 |
|
23 |
|
24 | }
|
25 | }
|
26 | ISR(INT1_vect)
|
27 | {
|
28 | OCR1A += 111; //increase OCR1A to get a movement of about 5°
|
29 |
|
30 | }
|
31 | ISR(TIMER1_COMPA_vect)
|
32 | {
|
33 | PORTD ^= (1<< PORTD5); //toggle PD5 to create CTC PWM at PD5
|
34 | }
|