Roman B. schrieb:> Weiß keiner Rat?
Bevor Du wartest, dass sich jemand durch Deinen unkommentierten Code
wühlt, wärst Du mit einer Simulation schon längst fertig, eine SM wie
diese lässt sich gut simulieren.
Ansonsten, es gibt die Regel dass im Main und ISR gemeinsam verwendete
Variablen volatile zu deklarieren sind, die Verwendung eines Struct
ändert daran nichts.
Roman B. schrieb:> Weiß keiner Rat?
Dir ist hoffentlich klar, dass das ein amoklaufender Pointer ist:
Roman B. schrieb:> PORTB |=servos.pins[++servos.servo_id];
Denn wenn zuvor servo_id == 1 ist, dann wird es hier erst mal auf 2
erhöht (PreIncrement!) und danach auf ein Element zugegriffen, das nicht
mehr Inhalt von servos.pins ist. Es wird nämlich auf servos.pins[2]
zugegriffen. Das ist aber das selbe wie servos.values[0]. Und der "Pin",
der dort deklariert ist, wird dann gesetzt... :-o
Noch eine kleine Unstimmigkeit: ein int ist 16 Bit breit. Ein Port hat
nur 8 Bit...
> Es bewegt sich jedoch immer nur der Servo an PB1.
Was passiert, wenn du die Ports einfach mal tauschst?
> Wo liegt mein Fehler?
Du analysierst das Problem nicht. Oder du teilst uns nicht mit, was du
schon herausgefunden hast...
Hast du ein Oszilloskop?
Lothar Miller schrieb:> Noch eine kleine Unstimmigkeit: ein int ist 16 Bit breit. Ein Port hat> nur 8 Bit...
Und der Timer (OCR0A) auch.
Nimm daher uint8_t.
Ansonsten muß man bei int die Mainzugriffe atomar kapseln.
Danke für diese Hinweise!!
Habe das jetzt ausgebessert, irgendwo hängts aber immer noch...
MWS schrieb:> Bevor Du wartest, dass sich jemand durch Deinen unkommentierten Code> wühlt, wärst Du mit einer Simulation schon längst fertig, eine SM wie> diese lässt sich gut simulieren.
Wie mache ich das?
(Verwende avr dragon)
Roman B. schrieb:> while( 1 ) {> servos.values[0]=rand()%270;> servos.values[1]=rand()%270;> }
Diesen Testfall finde ich eher ungeschickt. Der dürfte zu wildem Gezucke
der Servos führen. Genau das gleiche, was auch passiert, wenn die
Timings nicht richtig funnktioniern.
Auch ist mir aufgefallen, daß im deiner Statemachine in der ISR in zwei
verschiedenen States (und damit in zwei getrennten ISR-Aufrufen) auf die
Servo-Werte zugegriffen wird. Dein Hauptprogramm ändert zwischendrin
aber diese Werte.
MWS schrieb:> eine SM wie diese lässt sich gut simulieren
Suchmaschine? Seemeile? Sailor Moon? Was könnte eine "SM" sein?
Roman B. schrieb:> Wie mache ich das?> (Verwende avr dragon)
Mit dem Dragon dürftest Du In-Circuit debuggen können, mir hat immer die
Simulation im AVR-Studio gereicht.
Wenn Du per AVR-Studio simulieren möchtest, dann compilierst Du mit -O0,
startest den Simulator (Debug -> Start Debugging), legst einen
Haltepunkt mit F9 auf die ISR, lässt mit F5 laufen und steppst per F11
durch den Code. Dabei schaust Du Dir die Variablen an, das geht per
Watch (Rechtsklick -> Add Watch), in der IO-View beobachtest Du, wie
sich der Port ändert.
Studio simuliert auch die Timer und ruft die ISR passend auf, bei großen
Prescalern kann's sinnvoll sein, diese nur für die Simulation auf 1 zu
verkleinern. Damit führt das Studio den Interrupt schneller aus.
In der Simulation vergleichst Du, was Deiner Meinung nach passieren soll
und was tatsächlich passiert.
Rolf Magnus schrieb:> MWS schrieb:>> eine SM wie diese lässt sich gut simulieren>> Suchmaschine? Seemeile? Sailor Moon? Was könnte eine "SM" sein?
OMG (oh my god, Oh.., mein Gott)
Ok, versuchen wir mal:
> Eine Suchmaschine wie diese lässt sich gut simulieren
Hm.
> eine Seemeile wie diese lässt sich gut simulieren
Hmm.
> eine Sailor Moon wie diese lässt sich gut simulieren
Hmmm.
> eine Sado Maso wie diese lässt sich gut simulieren
Hmmmm.
> eine State Machine wie diese lässt sich gut simulieren
Bingo.
Und was ist das, was der TS in seinem Code zeigt? Eine State Machine,
oder nicht-Angelsächsisch auch Zustandsautomat genannt. Aber Du machst
doch den Job lang genug, um das zu wissen, warum hast Du gefragt?
Wolltest Du Klarstellung für die Leserschaft?
Aber selbst dann - jemand, der den Code nicht lesen kann, der nicht
erkennt dass es sich dabei um eine State Machine handelt und der auch
den Ausdruck "State Machine" nie gehört hat, wird zum Thema nicht viel
beitragen können, dann ist's mir auch egal, ob er SM versteht.
Wer dagegen den Ausdruck State Machine kennt, der wird's problemlos in
Kontext bringen.
MWS schrieb:> Und was ist das, was der TS in seinem Code zeigt? Eine State Machine,> oder nicht-Angelsächsisch auch Zustandsautomat genannt. Aber Du machst> doch den Job lang genug, um das zu wissen, warum hast Du gefragt?
Dass in seinem Code eine Statemachine steckt, weiß ich. Hab ich ja
selbst geschrieben.
> Wolltest Du Klarstellung für die Leserschaft?
Nein, ich hab wirklich die Verbindung nicht gesehen. Ich hatte bei "SM"
eher gedacht, daß damit das Programm als ganzes gemeint ist und eben
nach alternativen Begriffen für "Code", "Compilat" oder "Programm"
gesucht und keinen gefunden, der mit "SM" abgekürzt werden könnte. Bei
Arduino gibt es "Sketch", aber was das "M" bedeuten könnte, wäre dann
auch unklar. Ich hatte sogar an sowas wie "Servo-Manager" gedacht, aber
konnte mir nicht so recht vorstellen, daß das wirklich gemeint sein
könnte, abgesehen davon, daß es mit dem Genus nicht gepasst hätte.
> Wer dagegen den Ausdruck State Machine kennt, der wird's problemlos in> Kontext bringen.
Oder auch nicht. ;-)
Mir ist das viel zu viel Holz im Interrupt.
Insbesondere * und / kosten einiges auf CPUs ohne MUL/DIV-Befehl.
Ich würde den Interrupt soweit wie möglich entschlacken, z.B.:
Peter Dannegger schrieb:> Ich würde den Interrupt soweit wie möglich entschlacken, z.B.:
Damit hast Du bewiesen, dass Du programmieren kannst, was man vorher
auch wusste. Ein Erfolgserlebnis für den TE, "seinen" Fehler zu finden,
bescherst Du damit nicht.
MWS schrieb:> Ein Erfolgserlebnis für den TE, "seinen" Fehler zu finden,> bescherst Du damit nicht.
Das wird eher daran liegen, daß niemand da durchsieht, ich jedenfalls
nicht.
Das Fehlen von Kommentaren ist hier besonders störend.
Auchmagichesnicht,wennmandenCodeohneLeerzeichenaneinanderklatscht.
Leerzeichen können die Lesbarkeit deutlich erhöhen, wie bei jedem
anderen Text auch.
If-else-Monster finde ich auch schlecht lesbar. Wann immer möglich,
nehme ich switch-case. Da hat man eine klare Struktur, so daß es auch
ohne Kommentare leicht verstehbar ist.
Peter Dannegger schrieb:> Das wird eher daran liegen, daß niemand da durchsieht, ich jedenfalls> nicht.
Auch ich fand's schwer, daher mein Rat, es zu simulieren.
Peter Dannegger schrieb:> Das wird eher daran liegen, daß niemand da durchsieht, ich jedenfalls> nicht.
Danke für die Hilfe trotz dieses Umstandes!!
Peter Dannegger schrieb:> Mir ist das viel zu viel Holz im Interrupt.
Natürlich lässt es sich entschlacken. Ich wäre nie auf diese
Möglichkeiten gekommen! Danke dafür.
Eine Frage zu dem verbesserten Programm hätte ich noch:
Warum wird Timer-Mode 0 verwendet und nicht CTC bzw. warum ruckeln die
Servos bei Verwendung von CTC?
Roman B. schrieb:> Warum wird Timer-Mode 0 verwendet und nicht CTC bzw. warum ruckeln die> Servos bei Verwendung von CTC?
Das war nur mal schnell dahingeschrieben.
CTC sollte auch gehen. Bin mir aber nicht sicher, ob dabei OCR1A
gepuffert wird, dann muß es einen Interrupt früher gesetzt werden oder
die Pins einen Interrupt später.
Peter Dannegger schrieb:> CTC sollte auch gehen. Bin mir aber nicht sicher, ob dabei OCR1A> gepuffert wird, dann muß es einen Interrupt früher gesetzt werden oder> die Pins einen Interrupt später.
OCR0A
Der Double Buffer ist bei den 8Bit AVRs nur in den PWM-Modes an.