Hallöchen Zusammen,
ich programmieren grade meinen AtTiny85 und stelle mich selber bisschen
auf die Probe. Ich bin Anfänger und versuche durch Praktische Übung zu
lernen. Nun, ich habe eine kleine LED Schaltung aufgebaut die mithilfe
des Tiny beleuchtet werden sollen. Dabei sind alle 5 Ports belegt und
übernehmen eine bestimmte reihe. Einige schöne Sachen konnte ich bisher
damit anstellen, doch bei meiner nächsten Idee hapert es ein bisschen.
Die LED´s sollen nach jeder Runde immer schneller leuchten und wieder
ausgehen. Also: Die LED`s fangen an eine Sekunden lang zu leuchten.
Danach gehen sie aus und sofort danach leuchtet die nächste reihe. Auch
diese leuchtet eine Sekunde lang auf und geht danach wieder aus. Das
geschieht mit allen 5 Reihen. Dann ist eine ganze Periode zu ende. Bei
dem nächsten Start der Periode sollen die LED`s nicht eine Sekunde lang
leuchten sondern z.b nur 800ms. Das ganze geht dann so lange weiter bis
man bei etwas 1ms ist. Mit der Zeit wird es dann so scheinen als würden
die LED´s durchgehend leuchten, obwohl das ja eigentlich nicht der Fall
ist, sie gehen nur so extrem schnell an und aus das wir das nicht
merken. Nun das Problem ist das runterzählen. Das kriege ich noch nicht
gebacken. Meinen Code habe ich mit der for schleife so verfasst dass es
bei einer Sekunde anfängt, und in 100ms schritten immer weiter
runterläuft.
Deine for Loop ist falsch.
Du veraenderst das i nicht.
for (int i=1000; i>=1; i-100)
Du musst den Wert wieder zuweisen, also z.B.
for (int i=1000; i>=1; i=i-100) oder for (int i=1000; i>=1; i-=100)
Hercules H. schrieb:> for (int i=1000; i>=1; i-100)
nicht i-100 sondern i-=100
Hercules H. schrieb:> _delay_ms(i);
das geht nicht. _delay_ms geht nicht mit variablen. Dafür eine Funktion
schreiben und aufrufen.
Als letzten Teil im for-Statement willst du eine Anweisung die nach
jeden Schleifendurchlauf ausgeführt wird. Das ist üblicherweise eine
Zuweisung an die Zählvariable. Also in deinem Fall
i = i - 100
Sonst bleibt i einfach immer gleich.
anstatt "int" würde ich immer explizit die Typen mit der Längenangabe
nutzen wie z.B. "int16_t2, dann weiß man immer gleich was wirklich
gemeint ist.
Michael
schreib dir mal auf (so mit graphit und totem baum) welche werte i
deiner meinung nach so annimmt.
danach schaust du dir die operatoren an, die in der for schleife
verwendet werden und was in deinem code passiert.
tipp: du kannst den schleifenkopf auch in einen c-programm für den pc
verwenden und auf der konsole einfach die werte für i ausgeben lassen
Werner P. schrieb:> das geht nicht. _delay_ms geht nicht mit variablen. Dafür eine Funktion> schreiben und aufrufen.
Das erklaer mal, warum das nicht gehen soll.
devzero schrieb:> Werner P. schrieb:>> das geht nicht. _delay_ms geht nicht mit variablen. Dafür eine Funktion>> schreiben und aufrufen.>> Das erklaer mal, warum das nicht gehen soll.
ok. dachte immer das müsste eine Konstante sein. Kann mich auch irren.
Edit: wird hier z.B. auch so dargelegt.
[[Beitrag "Variable übergeben in #include <avr/delay.h>"]]
devzero schrieb:> Werner P. schrieb:>> das geht nicht. _delay_ms geht nicht mit variablen. Dafür eine Funktion>> schreiben und aufrufen.>> Das erklaer mal, warum das nicht gehen soll.
Es ist ein Makro und wird beim Kompilieren berechnet und nicht zur
Laufzeit. Daher müssen alle Parameter schon beim Compilieren fest
stehen.
devzero schrieb:> Das erklaer mal, warum das nicht gehen soll.
Was hat _delay_ms() nur an sich, dass diese Frage alle paar Tage wieder
im Forum auftaucht... Google halt. Wurde ja oft genug beantwortet hier.
Also ich habe jetzt probiert die Antworten als Lösungsansatz zu
verwenden, allerdings kommt nur eine Fehlermeldung. Arbeite übrigens mit
Atmel Studio7. Von der Fehlermeldung habe ich ein Screenshot gemacht.
Wisst ihr vielleicht was das Problem hierbei ist? Zuvor war die Meldung
nicht da, hat alles funktioniert, bis ich dann... i-100) mit... i=i-100)
ersetzt habe. :/
Hercules H. schrieb:> Wisst ihr vielleicht was das Problem hierbei ist?
Lies doch wenigstens die Antworten, wenn du schon fragst. So viele sinds
nicht.
Ich bin, wie bereits Anfangs erwähnt, Anfänger in diesem Gebiet. Von
einem Anfänger zu erwarte dass er versteht was bei einer Error Ausgabe
gemeint ist, und im besten Fall auch noch weiß was zu tun ist, ist ja
wohl absurd. Einige Antworten zu der Hauptfrage kann ich weder richtig
zuordnen noch verstehen. Entschuldigt mein Interesse und mein Streben
nach einer Lösung...
Hercules H. schrieb:> Von einem Anfänger zu erwarte dass er versteht was bei einer Error> Ausgabe gemeint ist, und im besten Fall auch noch weiß was zu tun ist,> ist ja wohl absurd
Hat auch keiner verlangt. Nur die Antworten in diesem Thread zu lesen.
Hercules H. schrieb:> Ich bin, wie bereits Anfangs erwähnt, Anfänger in diesem Gebiet. Von> einem Anfänger zu erwarte dass er versteht was bei einer Error Ausgabe> gemeint ist, und im besten Fall auch noch weiß was zu tun ist, ist ja> wohl absurd. Einige Antworten zu der Hauptfrage kann ich weder richtig> zuordnen noch verstehen. Entschuldigt mein Interesse und mein Streben> nach einer Lösung...
_delay_ms() ist kein Arduino delay(), und im Unterschied zu Arduino
funktioniert nur mit Zahlen und nicht mit Buchstaben.
lambda schrieb:> Als letzten Teil im for-Statement willst du eine Anweisung die nach> jeden Schleifendurchlauf ausgeführt wird. Das ist üblicherweise eine> Zuweisung an die Zählvariable. Also in deinem Fall> i = i - 100> Sonst bleibt i einfach immer gleich.
Nöö will er nicht, das macht die for-Schleife ganz allein. Was meinst Du
wozu i-=100 (an Stelle des falschen i-100) gut ist? Wenn er das so macht
wie Du schreibst dekrementiert er in jedem Durchlauf um 200.
Zeno schrieb:> lambda schrieb:>> Als letzten Teil im for-Statement willst du eine Anweisung die nach>> jeden Schleifendurchlauf ausgeführt wird. Das ist üblicherweise eine>> Zuweisung an die Zählvariable. Also in deinem Fall>> i = i - 100>> Sonst bleibt i einfach immer gleich.>> Nöö will er nicht, das macht die for-Schleife ganz allein. Was meinst Du> wozu i-=100 (an Stelle des falschen i-100) gut ist? Wenn er das so macht> wie Du schreibst dekrementiert er in jedem Durchlauf um 200.
das mit i = i - 100 ist doch nicht falsch. Zur Sicherheit hab ich das
mal getestet. Warum sollte das auch um 200 dekrementieren?
@zeno: lambda schrieb
"im letzten Teil des for-statement"
nicht
"im letzten Teil der for-Schleife"
allerdings ist die Frage "..von n bis 0 in n*er schritten" wohl unnötig
kompliziert mit "for" gelöst, da kann man auch gut den einen Durchlauf
ohne Schleife als Klammer ausprogrammieren.
Oder wie oft könnt ihr n von n abziehen bis es 0 ergibt?
G. H. schrieb:> @zeno: lambda schrieb> "im letzten Teil des for-statement"> nicht> "im letzten Teil der for-Schleife"
Hast recht, da habe ich aus dem Statement irgendwie eine Schleife
gemacht. Sorry! Hab jetzt gerade nochmal Lambda's Post gelesen, alles
korrekt wie er es geschrieben hat - war mein Fehler. Ist halt immer
wieder das Gleiche, wer lesen kann ... .
G. H. schrieb:> allerdings ist die Frage "..von n bis 0 in n*er schritten" wohl unnötig> kompliziert mit "for" gelöst, da kann man auch gut den einen Durchlauf> ohne Schleife als Klammer ausprogrammieren.
Wie willst Du eine mehrfache Wiederholung ohne Schleife machen?
Man könnte es auch mit while lösen, das ist aber auch eine Schleife.
Es ginge auch mit goto, aber das ist ja böse.
Also ich habe mir den Tipp von Werner P. zu herzen genommen und
folgendes in mein Programm Eingebaut, aber irgendwie klappt es trotzdem
nicht. Davon mal ganz abgesehen das ich gar nicht verstehe was da steht.
und warum ...i=i-100) mein Problem plötzlich löst habe ich auch nicht
ganz gerafft. Hatte vorher ja nur ...i-100).
Hercules H. schrieb:> Davon mal ganz abgesehen das ich gar nicht verstehe was da steht. und> warum ...i=i-100) mein Problem plötzlich löst habe ich auch nicht ganz> gerafft. Hatte vorher ja nur ...i-100).
Du hast eine Schleife gebaut, die läuft, solange i>=1 ist.
Zu Anfang ist i = 1000.
Du änderst i niemals wieder.
Wann denkst du hört die Schleife auf?
Sie hört nie auf, das war mir spätestens dann klar als mein ...i-100)
durch ...i=i-100) verbessert wurde. Ich wusste zuvor nicht das der Wert
bei jeden Neuanfang sich dadurch ändert. Meine Idee am Anfang war es den
aktuellen Wert irgenwie zwischen zu speichern, und beim neu anfangen
dieser Wert mit -100ms anfängt. Was ich nicht so ganz verstehe ich
folgender Punkt: Die schleife fängt bei 1000ms an. Beim nächsten Lauf
zieht die Schleife 100ms ab. Und das bei jedem Lauf bis i>=1 ist. Aber
wie weiß die Schleife denn das nach dem ersten Lauf die Zeit nicht mehr
1000ms sondern 900ms. Schließlich fängt es doch von vorne an, und der
Wert wird nirgends zwischengespeichert. Stutzig macht mich das langsam.
Hercules H. schrieb:> Davon mal ganz abgesehen das ich gar nicht verstehe was da steht. und> warum
Das ist dein Hauptproblem. Du solltest zwingend Mal ein vernünftiges C
Buch durcharbeiten damit du verstehst was hier passiert. Ansonsten
machst du dir nur das Leben schwer. Du musst verstehen was eine Funktion
ist, was man mit einer Schleife machen kann und was eine Konstante ist.
In deinem Eingangspost hat sich i nicht verändert. Der Compiler hat das
erkannt und dafür eine Konstante eingesetzt.
Deshalb gab es keine Fehlermeldung bei _delay_ms(i).
_delay_ms ist wie gesagt ein Makro das eine Konstante erwartet. Dadurch
dass du in deinem berichtigten Code eine Zuweisung machst (i=i-1) wird
aus i eine wirkliche Variable. Deshalb meckert der Compiler. Zu Recht.
Werner P. hat dieses Problem einfach umgangen indem er eine Konstante
für _delay_ms eingesetzt. Nämlich 1. Damit die Zeit einstellbar ist,
macht er noch eine Schleife darum. Die Funktion my_delay_ms wartet also
bei einem Aufruf counter*1ms.
Hercules H. schrieb:> Aber wie weiß die Schleife denn das nach dem ersten Lauf die Zeit nicht> mehr 1000ms sondern 900ms.
Indem sie eine temporäre Variable i hält die sie bei jedem
Schleifendurchlauf um die angegebene Operation verändert (i=i-1).
Hercules H. schrieb:> Schließlich fängt es doch von vorne an,
Nö
Hercules H. schrieb:> und der Wert wird nirgends zwischengespeichert
Doch in i.
Nimm Mal einen Debugger deiner Wahl.
Entweder direkt auf dem uC (du hast aber wahrscheinlich keinen Debugger
dafür) oder in einer C Applikation auf dem PC.
Da kannst du die Einzelschritte einer For Schleife Mal Schritt für
Schritt durchsteppen und sehen wie sie abgearbeitet wird.
Die for-Schleife hat 4 Teile:
for(Initialisierung;Laufbedingung;Änderung) Schleifenkörper
Die Initialisierung wird vor dem Schleifenbeginn einmal aufgerufen
Die Laufbedingung wird vor jedem Durchlauf geprüft.
Die Änderung wird nach dem Durchlauf des Schleifenkörpers aufgerufen.
Der Schleifenkörper enthält die Anweisungen, die wiederholt werden.
Du kannst eine for-Schleife auch als while-Schleife schreiben.
Initialisierung;
while(Laufbedingung) {
Schleifenkörper
Änderung;
}