PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Eigenwilliger Blinker



Greensiver
15.11.2013, 20:16
Hi Leute,

ich habe mir neulich einen Inkrementalgeber zugelegt. Für den Anfang wollte ich ein kleines Programm schreiben, womit ich mit dem Inkrementalgeber die Blinkfrequenz variieren kann. Nunja den Inkrementalgeber kann ich auslesen, aber beim Blinken wird es Interessant! Die LED blinkt zwar, hört aber nach kurzer Zeit damit auf. Ich kann mir nicht ganz erklären warum. Aber vil. ist es ja nur ein ganz einfacher Logikfehler von mir;).

Naja hier der Code: (geht bestimmt noch eleganter zu lösen:rolleyes:)




int LED_1=5;
int tmp=0;
unsigned long timer_1=0;
unsigned long timer_2=0;
unsigned long time_on=50; //Anzeit der LED in Millisekunden
unsigned long time_off=50; //Auszeit der LED in Millisekunden


void setup()
{
__pinMode(LED_1, OUTPUT);
}

void loop()
{


__if(tmp==0) //Wenn Blinkvorgang beendet, von forn bginnen
__{
____digitalWrite(LED_1, HIGH); //LED anschalten
____timer_1=millis(); //erste Zeit nehmen
____tmp=1;//dauerhaftes Zeitnehmen verhindern
__}
__if(millis() == (timer_1+time_on)) //wenn die vorher genommene Zeit PLUS der Anzeit mit der derzeitigen Zeit übereinstimmt...
__{
____digitalWrite(LED_1, LOW); //...schalte LED aus...
____timer_2=millis(); //...und nehme Zeit 2
__}
__if(millis() == (timer_2+time_off)) //Wenn Auszeit abgelaufen ist, beginne von forn
__{
____tmp=0;
__}


}



Habt Ihr einen Lösungsansatz für mich? millis() braucht ja glaube so an die 70Tage bis es auf Null zurückfällt, daran kann es also nicht liegen...


Viele Grüße, Green

Greensiver
17.11.2013, 11:53
Leute......hier geht es um ein einfaches Blinkprogramm für den Arduino.

Hat den keiner der Arduino-Freunde oder anderen Programmieren hier eine Idee?:(

Hubert.G
17.11.2013, 14:58
mill is_rev_on=millis();

Ohne genaue Beschreibung deines Programms, weisst du in Kürze selbst nicht mehr was du gemacht hast.

Greensiver
17.11.2013, 16:59
mill is_rev_on=millis();
JO, da war ein Leerzeichen da, wo es nicht hin sollte.:)


Ohne genaue Beschreibung deines Programms
Ich hab mich jetzt mal bemüht eine gute Beschreibung hinzubekommen...Ich hoffe die is gut so, wenn nicht bitte sagen.:)

Auserdem waren noch 2 Variablen zu viel drin.:Haue

RoboHolIC
17.11.2013, 22:20
Hi Geensiver.

Ist dein gezeigter Code vollständig? Ich bin nicht so firm mit C, aber ich kann nicht erkennen, wo die beiden Funktionen setup() und loop() aufgerufen werden, weil ich kein main() finde.
Ich vermute, du willst eine Weiterschaltung von Phase zu Phase realisieren:
1: Zeitnehmen und einschalten
2: Warten auf Ausschaltbedingung
3: Warten auf Auszeit-Ende

Die Phasen 2 und 3 sollten dann WHILE-Konstrukte sein mit der jeweils negierten Bedingung ("solange Abbruch-Kriterium NICHT erreicht").
Dann fehlt m.E. noch der direkte Sprung nach oben zu Phase 1, oder eben: main() {loop();}

Dass es bisher überhaupt zu einem Blinken kommt, erscheint mir eher zufällig (wenngleich offenbar reproduzierbar).

Was ich noch sagen wollte:
Ich fände es besser, die veröffentlichte ursprüngliche Programmversion nicht nachträglich zu verändern, weil dann die innere Stimmigkeit des Threads verloren geht.
Lieber durch jeweils aktuelle Versionen die sukkzessive Verbesserung des Programms erkennbar machen.

Hubert.G
18.11.2013, 09:43
Arduino Code ist etwas problematisch. Es läuft einiges im Hintergrund ab, ähnlich wie bei BASCOM.
Vom Syntax her ist das geschriebene schon richtig, auch das loop()
Problematisch betrachte ich allerdings dieses unsigned long.
Wenn das hier: if(millis() == (timer_2+time_off)) nicht genau erreicht wird, ist es vorbei und es gibt keinen Sicherheitsausstieg. Das unsigned long ist eine 8Byte Zahl. Wenn es da während der Addition und Vergleich eine Verschiebung gibt, ist es vorbei.
Ich bin mir sicher das hier irgendwo der Wurm steckt, auch wenn ich ihn nicht erkenne.

RoboHolIC
18.11.2013, 10:23
Arduino Code ist etwas problematisch. Es läuft einiges im Hintergrund ab, ähnlich wie bei BASCOM.
Vom Syntax her ist das geschriebene schon richtig, auch das loop()
OK, ist für µC-Anwendungen in gewisser Weise auch sinnvoll.


...gibt keinen Sicherheitsausstieg ... bin mir sicher das hier irgendwo der Wurm steckt
Wie siehst du das mit dem ungebremsten Durchrauschen durch alle drei IF-Blöcke? Das erscheint mit nach-wie-vor plausibel. Hab ich mich da auch geirrt? Dann würde ich mich eben mal leise pfeifend davonstehlen ...

Hubert.G
18.11.2013, 11:35
Wie siehst du das mit dem ungebremsten Durchrauschen durch alle drei IF-Blöcke? Das erscheint mit nach-wie-vor plausibel. Hab ich mich da auch geirrt? Dann würde ich mich eben mal leise pfeifend davonstehlen ...
Das Durchrauschen ist ansich auch OK, nur wenn einmal ein Takt verpasst wird oder sich innerhalb einer Abfrage was ändert, ist Schluss mit Lustig.

RoboHolIC
18.11.2013, 11:51
Das Durchrauschen ist an sich auch OK
Ähm, tja, jetzt seh' ich es auch. Ich fang dann schon mal mit dem Pfeifen an ...

Greensiver
18.11.2013, 14:58
Danke für die Antworten!


Ist dein gezeigter Code vollständig? ... Ja, der komplette Blinkteil des Programmes, mit dem Inkrementalgeber bin ich ja fertig geworden.:)

Die Phasen 2 und 3 sollten dann WHILE-Konstrukte sein mit der jeweils negierten Bedingung ... in dem Falle bleib ich beim If.

Ich fände es besser, die veröffentlichte ursprüngliche Programmversion nicht nachträglich zu verändern, weil dann die innere Stimmigkeit des Threads verloren geht.
Lieber durch jeweils aktuelle Versionen die sukkzessive Verbesserung des Programms erkennbar machen. ... DANKE! Werde Ich mich in Zukunft ganz bestimmt drann halten.

Arduino Code ist etwas problematisch. Es läuft einiges im Hintergrund ab, ähnlich wie bei BASCOM. ... Problematisch betrachte ich allerdings dieses unsigned long.
Wenn das hier: if(millis() == (timer_2+time_off)) nicht genau erreicht wird, ist es vorbei und es gibt keinen Sicherheitsausstieg. Das unsigned long ist eine 8Byte Zahl. Wenn es da während der Addition und Vergleich eine Verschiebung gibt, ist es vorbei.
Ich bin mir sicher das hier irgendwo der Wurm steckt, auch wenn ich ihn nicht erkenne. ... soweit, dass der µC mal was übersringen könnte habe Ich noch gar nicht gedacht, DANKE! Und JA, tatsächlich scheint dort der Wurm drinn gewesen zu sein.


Ich habe dem µC jetzt mehr Zeit zum erkennen gegeben. So ... genug gelabert! Hier mein derzeitiger Code.


int LED_1=5;
int tmp=0;
unsigned long timer=0;

long time_on=100; //Anzeit der LED in Millisekunden
long time_off=5000; //Auszeit der LED in Millisekunden


void setup()
{
__pinMode(LED_1, OUTPUT);
}

void loop()
{


__if(tmp==0) //Wenn Blinkvorgang beendet, von forn bginnen
__{
____digitalWrite(LED_1, HIGH); //LED anschalten
____timer=millis(); //erste Zeit nehmen
____tmp=1;_//dauerhaftes Zeitnehmen verhindern
__}
__if((millis() >= (timer + time_on)) && (millis() < (timer + time_on + time_off))) //wenn die vorher genommene Zeit PLUS der Anzeit mit der derzeitigen Zeit übereinstimmt UND kleiner als die Endzeit ist...
__{
____digitalWrite(LED_1, LOW); //...schalte LED aus
__}
__if(millis() >= (timer + time_on + time_off)) //Wenn Anzeit PLUS Auszeit abgelaufen ist, beginne von forn (jetzt mehr Sicherheit durch ">=")
__{
____tmp=0;
__}


}




Das ganze ist jetzt doch deutlich länger als dieses Beispiel (http://arduino.cc/en/Tutorial/BlinkWithoutDelay) geworden. Hat noch jemand Ideeen zum verkürtzen des Codes? Wenn sonst keiner mehr Anregungen oder Fragen hat, makier Ich den Thread als Erledigt.



Viele Grüße, Green

PlasmaTubeI²C
18.11.2013, 15:07
Hi,

wollte ich gerade vorschlagen, dass eine Abfrage-Bedingung mit ">=" deutlich sicherer ist.
Hab mir in jeder If den Inhalt der einzelnen Timer-Variablen ausgeben lassen, mit dem Ergebnis, dass ungefähr sekündlich ein timeshift von 1ms auftritt,
weswegen die Bedingung "==" irgendwann nicht mehr gültig gewesen ist und die Led sich "aufgehängt" hat.

Aber schön wenns jetzt läuft :)

Greensiver
18.11.2013, 15:26
An PlasmaTubeI²C:

stimmt, hätte ich auch mal machen können:). Ohne Uhrenquarz hat man immer einen gewissen Timeshift, das wirkt sich aber leider negativ auf die Bautrate aus. Ich war einfach zu faul mal einen
UART -> USB Wandler an meinen ATmega328P zu klemmen.

...Sowas fällt einem aber auch immer erst Hinterher ein...:rolleyes:

Trotzdem Danke für die Antwort!