ATmega delay Fehlfunktion

OP #1707734
Lesenswert?

Hallo Leute,

Habe dieses programm auf ein ATmega8 am laufen und folgendes problem 
dabei.
Dies ist bei der ansteuerung eines Servo Motors angewendet.
Beim ausführen bearbeit der uC die erste FOR schleife und auch das Delay 
danach, jetzt auch noch die zweite FOR schleife, doch das Delay lässt er 
dabei komplett weg und springt wieder direkt zu ersten FOR schleife.

Anstatt das der Servo so auch in der zweiten position 2 sekunden lang 
bleibt, fährt er dort hin und dann aber wieder sofort zurück, und hält 
nur pause wieder nach der ersten schleife.??

Habe da lange hin und her gemacht, auch die delays anders angeordnet 
usw.
Ich benutze AVR Studio/ Winavr / GCC.

Habe auch die schleifen in zwei unterprogramme gepackt, doch bleibt es 
alles beim selben.

Kann mir jemand da helfen?? Habe ich da was nicht beachtet??

Vielen Dank!


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <stdlib.h>


#define F_CPU 1000000UL
#include <util/delay.h>

//int ciclo = 1;
int a;
int i;
int adch1;


int main(void)
{
DDRD |= ( 1 << DDD0);        // SETAR PD5 como SAIDA
//PORTB |= (1<<PB3);  //LED4 Aktiv = 1
int c;


  while(1)
  {
  sei();
  //adch1 = ReadChannel(1);
  //b = 2*adch1;
  //a=0;
  //cli();
    for(a=0;a<=200;a++)
    {
      PORTD |= (1<<PD0);  //LED4 Off = 0
      _delay_us(1000);
      PORTD &= ~(1<<PD0);  //LED4 Aktiv = 1
      _delay_us(20000);
    }

    _delay_ms(2000);

    for(i=0;i<=200;i++)
    {
      PORTD |= (1<<PD0);  //LED4 Off = 0
      _delay_us(2100);
      PORTD &= ~(1<<PD0);  //LED4 Aktiv = 1
      _delay_us(20000);
    }

    _delay_ms(2000);

  }
}
#1707801
Lesenswert?

Matt Bico schrieb:

> Anstatt das der Servo so auch in der zweiten position 2 sekunden lang
> bleibt,

Das passiert sowieso nicht.
Du steuerst dein Servo ca. 4 Sekunden lang auf eine bestimmte Position 
hin. Danach überlässt du das Servo 2 Sekunden lang sich selbst.

Ein Servo muss ständig angesteuert werden. Einfach einen delay_ms(2000) 
ist zuwenig um ein Servo an einer bestimmten Position zu halten.
#1707827
Lesenswert?

Matt Bico schrieb:
> Der Servo fährt ja auch die 2 position an, und zwar ganz genau da wo ich
> den haben möchte. Kein grund dazu zu sagen das das sowieso nicht
> passiert.


ok falsch ausgedrückt

deine zeitangaben sind ein wenig zweifelhaft.
das servo sollte alle 6 sekunden die position wechseln.

Was ist jetzt mit dem Optimizer? Ist der auf -Os?
(Ansonsten stimmen die Delay Zeiten nicht)
#1707841
Lesenswert?

Hmm.
Die Simlation zeigt:
Nach jeweils 6 Sekunden wird die jeweils andere for-Schleife erreicht. 
So wie es sein soll und sich aus dem Code ergibt.

Kanstt du noch zwei LED irgendwo anhängen und die vor den for Schleifen 
wechselseitig anschalten? Die müssten sich im 6 Sekunden Takt 
abwechseln.
OP #1708016
Lesenswert?

Hatte bereits eine LED mit im Takt zweig eingebunden, so das nach jeder 
schleife einmal die LED an, und nach 1 sekunde delay wieder aus geht, 
und dann erst in die 2 schleife geht, so das ich auch eine kontrolle 
darüber hätte wo das programm sich z.Zt. befindet.
Auch nach der 2 schleife hatte ich solch ein "großes" delay auf der 
selben leitung programmiert.

Also so würde es aussehen für jede schleife:

for(i=0;i<=200;i++)
    {
      PORTD |= (1<<PD0);  //LED4 Off = 0
      _delay_us(2100);
      PORTD &= ~(1<<PD0);  //LED4 Aktiv = 1
      _delay_us(20000);
    }

PORTD |= (1<<PD0);  //LED4 Off = 0
_delay_ms(1000);
PORTD &= ~(1<<PD0);  //LED4 Aktiv = 1
_delay_ms(1000);

Doch auch hier kann ich nur zusehen das die LED einmal ganz schwach 
blinkt(impulse/pausen verhältnis sehr klein), und darach eine sekunde an 
ist, dann wieder blinkt, doch ist der servo dann ja auch bereits auf dem 
weg in die 1 position.

Das programm ist eigentlich noch größer, doch wenn gar nicht einmal 
dieses teil funktioniert, dann brauch ich den rest gar nicht mal 
mitlaufen lassen, obwohl der rest des programms aller bestens 
funktioniert. Nur dieses teil halt nicht.

Was meinen Sie mit ein SOFT-Reset?
Gast #1708026
Lesenswert?

Lass das "SOFT" weg, dann weist Du was er meint.
Testen kannst Du das, indem Du ganz am Anfang in main (noch vor dem 
while(1)) mal eine LED ein- und wieder ausschaltest.
Ein Grund dafür könnte z.B. der Watchdog sein (das wäre dann ein 
HARD-Reset :)
OP #1708059
Lesenswert?

Nein,nein auch das ganze ohne sei(); und pipapo alles bleibt so wie es 
ist.
Habe eine woche lang daran gemacht, und deshalb habe ich mich mal hier 
im Forum erkündigen wollen.

Mir ist im sinne gekommen das auch eine störung ein reset auslösen 
könnte, über den Motor nach + oder masse, doch dann würde ja auch mal 
die erste schleife rausfallen, wenn man es so betrachtet.
#1708089
Lesenswert?

Matt Bico schrieb:

> Das programm ist eigentlich noch größer, doch wenn gar nicht einmal
> dieses teil funktioniert, dann brauch ich den rest gar nicht mal
> mitlaufen lassen, obwohl der rest des programms aller bestens
> funktioniert. Nur dieses teil halt nicht.

Dann solltest du erst mal nur diesen Teil für sich alleine, ohne alles 
andere testen.

WEnn du noch 2 LED irgendwo anhängen kannst, dann lass folgendes 
Programm laufen. Die einzige ANpassung ist die Einstellung des Ports an 
dem die Led hängen bzw. der Pins an denen die LED hängen. Den Rest lässt 
du so wie er ist (ausser natürlich ich habe hier beim tippen Tippfehler 
gemacht)
1
#define F_CPU 1000000UL
2

3
#include <stdlib.h>
4
#include <avr/io.h>
5
#include <util/delay.h>
6

7
#define LED_PORT    PORTB
8
#define LED_1       PB2
9
#define LED_2       PB3
10

11
int main(void)
12
{
13
  unsigned char i;
14

15
  LED_PORT |= (1<<LED_1) | ( 1<<LED_2);
16
  _delay_ms( 500 );
17
  LED_PORT &= ~( (1<<LED_1) | ( 1<<LED_2) );
18
  _delay_ms( 500 );
19

20
  while(1)
21
  {
22
    LED_PORT |= ( 1 << LED_1 );
23
    LED_PORT &= ~( 1 << LED_2 );
24

25
    for( i = 0; i < 200; i++ )
26
    {
27
      PORTD |= (1<<PD0);  //LED4 Off = 0
28
      _delay_us(1000);
29
      PORTD &= ~(1<<PD0);  //LED4 Aktiv = 1
30
      _delay_us(20000);
31
    }
32

33
    _delay_ms(2000);
34

35
    LED_PORT |= ( 1 << LED_2 );
36
    LED_PORT &= ~( 1 << LED_1 );
37

38
    for( i = 0; i < 200; i++ )
39
    {
40
      PORTD |= (1<<PD0);  //LED4 Off = 0
41
      _delay_us(2100);
42
      PORTD &= ~(1<<PD0);  //LED4 Aktiv = 1
43
      _delay_us(20000);
44
    }
45

46
    _delay_ms(2000);
47
  }
48
}


Beim Programmstart leuchten beide LED gemeinsam auf, danach immer 
wechselseitig, alle 6 Sekunden wird gewechselt und gleichzeitig fährt 
das Servo in die andere Position.
Wenn irgendwann beide LED wieder gemeinsam aufleuchten, dann ist der µC 
abgeschmiert und das Programm beginnt von vorne.

Das Verhalten der beiden LED erzählt daher was unter Umständen passiert 
sein könnte. Mit Raten kommen wir nicht weiter. Fakten müssen her.
OP #1708151
Lesenswert?

Ich Habs!!! Danke Leute für das mit in gänge bringen. Obwohl es nichts 
mit dem programm zu tun hat, doch die gedanken schiene hat geholfen!!! 
RESET !!

Habe die Schaltung über 12 Volt Versorgt mit ein 7805 in seiner 
"normalen" konfiguration" mit nur ein 100nF ein- und ausgangsmäßig 
beschaltet.

Es muß dann passieren das der 7805 in die Knie geht und das ganze nicht 
laufen lässt, obwohl der Servo ja nur um die 300mA zieht!!

Habe jetzt ein 100uF mit an Ausgang vom 7805 und es läuft wie 
geschrieben!!

Endlich kann ich das Abschliessen!

Vielen dank!

Schön das es solche Forums gibt!! Muß daher das auch mal gerne 
unterstützen!!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren