Forum: Mikrocontroller und Digitale Elektronik Atmega 2560 ausgelastet


von Ralf Eden (Gast)


Lesenswert?

Hallo!

ich habe folgendes Problemchen. Ich möchte mit meinem Atmega (in c++) ca 
300 LEDs ansteuern. Das ganze über 30 Pins die mit Vorwiderstand an den 
Anoden von je 10 LEDs hängen und dann eben noch 10 Pins die im Wechsel 
einen FET schalten um einen Abschnitt der LEDs zu aktivieren.

Das ganze klappt auch soweit. Ich erzeuge Effekte in der Main Funktion 
und eine ISR kümmert sich darum dass immer einer meiner FETs angesteuert 
wird.

Nun kommen im Programm so einige rand()%x Aufrufe vor und ich habe 
beobachtet, dass meine Anzeige ab einer kritischen Menge von ca 10 
Zufallsberechnungen im Pfad stehen bleibt. Es sind aber nach dem 
compilieren gerade mal 1% Speicher belegt. Frisst die rand() zur 
Laufzeit derartig viele Ressourcen dass der uC so schnell an seine 
Grenzen kommt? Wie überprüft man sowas am besten?

von Peter Z. (hangloose)


Lesenswert?

Zeile 42?

von Oliver S. (oliverso)


Lesenswert?

Im Simulator mal die Zyklen zählen lassen.

Oliver

von Falk B. (falk)


Lesenswert?

Ralf Eden schrieb:
> Hallo!
>
> ich habe folgendes Problemchen. Ich möchte mit meinem Atmega (in c++) ca
> 300 LEDs ansteuern. Das ganze über 30 Pins die mit Vorwiderstand an den
> Anoden von je 10 LEDs hängen und dann eben noch 10 Pins die im Wechsel
> einen FET schalten um einen Abschnitt der LEDs zu aktivieren.

Das nennt man eine LED-Matrix.

> Das ganze klappt auch soweit. Ich erzeuge Effekte in der Main Funktion
> und eine ISR kümmert sich darum dass immer einer meiner FETs angesteuert
> wird.

Klingt gut.

> Nun kommen im Programm so einige rand()%x Aufrufe vor und ich habe
> beobachtet, dass meine Anzeige ab einer kritischen Menge von ca 10
> Zufallsberechnungen im Pfad stehen bleibt.

Programmierfehler.

> Es sind aber nach dem
> compilieren gerade mal 1% Speicher belegt. Frisst die rand() zur
> Laufzeit derartig viele Ressourcen dass der uC so schnell an seine
> Grenzen kommt?

Nö.

> Wie überprüft man sowas am besten?

Mit einer systematischen Fehlersuche.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ralf Eden schrieb:
> eine ISR kümmert sich darum
Wie sieht denn diese ISR aus? Sind da drin Schleifen? Oder sogar 
irgendwelche Warteschleifen?

> Wie überprüft man sowas am besten?
Such mal nach "float" und/oder nach "double" in deinem Programm. Wenn da 
sowas vorkommt, dann findest du Zeitfresser recht schnell.

Ein recht guter Ansatz ist auch die Suche nach delay() und/oder seine 
Derivate...

> Wie überprüft man sowas am besten?
Man misst/berechnet die Zykluszeit der Hauptschleife. Messen geht z.B. 
über eine LED, die pro Durchlauf getoggelt wird. Mit einem Oszi kann man 
dann recht leicht feststellen, wie lang die dann braucht. Das selbe kann 
man mit einer LED in der ISR machen: am Anfang setzen, am Ende 
zurücksetzen, Oszi dran und ein paar Minuten laufen lassen, um auch 
Ausreißer zu erfassen.

von Peter D. (peda)


Lesenswert?

Per Timerinterrupt 10 mal jeweils 4 Byte auszugeben, sollte keine 
nennenswerte CPU-Last erzeugen. Dein Fehler muß also woanders liegen.
Ohne Code kann man dazu nichts weiter sagen.

von Ralf Eden (Gast)


Lesenswert?

Aber was bringt es mir, die Zykluszeit der Hauptschleife zu messen? Die 
sollte ja unkritisch sein, nachdem die Ansteuerung der LEDs von der ISR 
übernommen wird.

Die ISR ist unterdessen tatsächlich nicht gerade die feine englische 
Art, da in einer Schleife die Bits entsprechend der Pinbelegung 
angeordnet werden müssen. Aber sie läuft immer gleich lang ab und bis 
zum nächsten Interrupt vergehen sicher 50*256 Taktzyklen.

von Ralf Eden (Gast)


Lesenswert?

Ich werde den Code nachher mal hochladen.

von Peter D. (peda)


Lesenswert?

Ralf Eden schrieb:
> Die ISR ist unterdessen tatsächlich nicht gerade die feine englische
> Art, da in einer Schleife die Bits entsprechend der Pinbelegung
> angeordnet werden müssen.

Da die Multiplexrate deutlich höher sein wird, als die Änderungsrate, 
könnte man die Bitreihenfolge besser vor Speicherung in den Bild-RAM 
umändern. Das spart deutlich CPU-Last.
Man könnte natürlich auch gleich die LED-Matrix in der optimalen 
Reihenfolge an den AVR anschließen.

von Ralf Eden (Gast)


Lesenswert?

Peter D. schrieb:
> Ralf Eden schrieb:
> Die ISR ist unterdessen tatsächlich nicht gerade die feine englische
> Art, da in einer Schleife die Bits entsprechend der Pinbelegung
> angeordnet werden müssen.
>
> Da die Multiplexrate deutlich höher sein wird, als die Änderungsrate,
> könnte man die Bitreihenfolge besser vor Speicherung in den Bild-RAM
> umändern. Das spart deutlich CPU-Last.
> Man könnte natürlich auch gleich die LED-Matrix in der optimalen
> Reihenfolge an den AVR anschließen.


Ja stimmt, das steht auch auf der Todo-Liste. Aber die Ursache kann das 
ja eigentlich kaum sein denke ich.

von Falk B. (falk)


Lesenswert?

Ralf Eden schrieb:
> Ja stimmt, das steht auch auf der Todo-Liste. Aber die Ursache kann das
> ja eigentlich kaum sein denke ich.

1. Fehler! Niemals etwas ausschließen, was man nicht wasserdicht geprüft 
hat!

Siehe Fehlersuche.

von Εrnst B. (ernst)


Lesenswert?

Ralf Eden schrieb:
> Die ISR ist unterdessen tatsächlich nicht gerade die feine englische
> Art, da in einer Schleife die Bits entsprechend der Pinbelegung
> angeordnet werden müssen.

jetzt nicht direkt zum Thema:

__builtin_avr_insert_bits ist bekannt?

https://gcc.gnu.org/onlinedocs/gcc/AVR-Built-in-Functions.html

damit gehen so Bit-Umsortierereien recht komfortabel und flott.
Natürlich nur, wenn die Pinbelegung zur Compilezeit schon bekannt ist.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ralf Eden schrieb:
> Aber was bringt es mir, die Zykluszeit der Hauptschleife zu messen? Die
> sollte ja unkritisch sein, nachdem die Ansteuerung der LEDs von der ISR
> übernommen wird.
Wenn die Hauptschleife "normalerweise" 500 mal pro Sekunde durchlaufen 
wurde, nach einer "kleinen" Codeänderung an ganz anderer Stelle, z.B. in 
der Interruptroutine(!) aber auf einmal nur noch 200 mal, dann war die 
Änderung doch nicht so "klein" wie vermutet.

Ralf Eden schrieb:
> beobachtet, dass meine Anzeige ab einer kritischen Menge von ca 10
> Zufallsberechnungen im Pfad stehen bleibt.
Definiere "stehen bleiben", wie stellst du das fest?

von Purzel H. (hacky)


Lesenswert?

Was soll rand() als Random Generator ?
Nimm ein LFSR, siehe XApp210.pdf, XApp211.pdf, XApp217.pdf, XApp220.pdf 
von Xilinx.
Mit der Laenge kannst du dir die Repetierhaeufigkeit einstellen.
Ich denke oberhalb von 20 bit, entsprechend 1:1'000'000 bist du gut 
aufgestellt.
Ich wuerd's mit 32 bit probieren, mit Longint rechnen. Das waere dann 
eine wiederholung alle 4 Milliarden bit.

von Falk B. (falk)


Lesenswert?

Name H. schrieb:
> Was soll rand() als Random Generator ?

Weil das schon funktioniert?

> Nimm ein LFSR, siehe XApp210.pdf, XApp211.pdf, XApp217.pdf, XApp220.pdf
> von Xilinx.

Was glaubst du, was in rand() drin steckt? Eine Blattlaus die würfelt?

von Ralf Eden (Gast)


Angehängte Dateien:

Lesenswert?

So hier ist mal der Code soweit. In der Main ist die Änderung 
auskommentiert, die zum Freeze führt. Wenn ich an anderer Stelle die 
Anzahl an rand()-Aufrufen reduziere, funktioniert die Änderung.

von Ralf Eden (Gast)


Lesenswert?

Lothar M. schrieb:
> Definiere "stehen bleiben", wie stellst du das fest?

Das Hauptprogramm bleibt bei der aktuellen Anzeige Hängen. Die ISRs 
scheinen aber weiterzulaufen.


Meine Testmöglichkeiten sind bzgl Oszi dummer Weise eingeschränkt, denn 
ich habe keins. :(

Beitrag #5794535 wurde von einem Moderator gelöscht.
Beitrag #5794542 wurde von einem Moderator gelöscht.
Beitrag #5794543 wurde von einem Moderator gelöscht.
Beitrag #5794547 wurde von einem Moderator gelöscht.
Beitrag #5794551 wurde von einem Moderator gelöscht.
von Hannes J. (hannes_j)


Lesenswert?

Also bis auf die beiden Punkte die du selbst mit Todo angemerkt hast 
fällt mir auch nichts auf

von Falk B. (falk)


Lesenswert?

Ralf Eden schrieb:
> So hier ist mal der Code soweit. In der Main ist die Änderung
> auskommentiert, die zum Freeze führt. Wenn ich an anderer Stelle die
> Anzahl an rand()-Aufrufen reduziere, funktioniert die Änderung.

Deine Formatierung ist ungünstig.

Auf den ersten Blick sehe ich keinen massiven Fehler. Aber es würde mich 
nicht wundern, wenn dein Funktion zum Erzeugen neuer Anzeigemuster 
spinnt. Das reine Multiplexen sieht erstmal OK aus.

von Peter D. (peda)


Lesenswert?

Ralf Eden schrieb:
> So hier ist mal der Code soweit.

Mit C++ kenne ich mich nicht so aus. Irgendwann habe ich den Faden 
verloren, wer wen aufruft. Vielleicht sollte man die Codehäppchen etwas 
größer machen und nicht alles bis zu Einzeilern zerteilen.

Es sieht so aus, daß fast alles im Interrupt läuft, also ne richtig 
große Menge Holz. Daneben soll aber der Interrupt noch die Helligkeit 
ändern, d.h. ne PWM machen (je LED?).
Wenn der Interrupt dicht ist, dann läuft Main auf Sparflamme, d.h. 
zwischen den Interrupts wird nur noch ein Befehl des Main ausgeführt. 
Das kann so wirken, als ob das Main steht.
Ein Aufräumen wäre also dringeng angeraten.
Man sollte auch vermeiden, für jedes Bit ein Byte zu verbraten. 
Bitmasken (ein Byte je 8 Bit) machen das ganze nochmal schneller.

von Ralf Eden (Gast)


Lesenswert?

Falk B. schrieb:
>
> Deine Formatierung ist ungünstig.
>
> Auf den ersten Blick sehe ich keinen massiven Fehler. Aber es würde mich
> nicht wundern, wenn dein Funktion zum Erzeugen neuer Anzeigemuster
> spinnt. Das reine Multiplexen sieht erstmal OK aus.

Kannst du das präzisieren? Was würdest du genau anders machen?

 Das seltsame ist ja, dass die Probleme erst auftreten, sobald ich zu 
viele Parameter per Zufall erzeuge. Solange ich in diesem Fall die 
beiden Directions fest übergebe klappt alles. Ich kann auch die 
Directions per Zufall bestimmen und dafür die Axen fest übergeben. Dann 
läuft es auch. Mein Eindruck ist, dass einzig und allein die Anzahl der 
rand() Aufrufe den Unterschied macht.

von Ralf Eden (Gast)


Lesenswert?

Peter D. schrieb:
> Ralf Eden schrieb:
> So hier ist mal der Code soweit.
>
> Mit C++ kenne ich mich nicht so aus. Irgendwann habe ich den Faden
> verloren, wer wen aufruft. Vielleicht sollte man die Codehäppchen etwas
> größer machen und nicht alles bis zu Einzeilern zerteilen.
>
> Es sieht so aus, daß fast alles im Interrupt läuft, also ne richtig
> große Menge Holz. Daneben soll aber der Interrupt noch die Helligkeit
> ändern, d.h. ne PWM machen (je LED?).
> Wenn der Interrupt dicht ist, dann läuft Main auf..

Nein im Interrupt wird nur umsortiert u die Portzuweisung gemacht. 
Wobei die sortierung wirklich noch raus kann aber das kann es kaum sein. 
Da sind noch ca 50*256 Taktzyklen Zeit. Helligkeit wird nicht im 
Interrupt behandelt.

von Peter D. (peda)


Lesenswert?

Ich werfe mal die Stichworte "atomic" und "volatile" in den Ring.
Beim Datenaustausch Main<->Interrupt können die Wunder bewirken.

von Ralf Eden (Gast)


Lesenswert?

Oder anders herum gefragt. Wann kann ein überladener Interrupt denn für 
ein Freeze sorgen? Das passiert doch eigentlich nur wenn er so groß wird 
dass das Programm kaum noch außerhalb der ISR läuft. Oder übersehe ich 
hier was?

von Ralf Eden (Gast)


Lesenswert?

Peter D. schrieb:
> Ich werfe mal die Stichworte "atomic" und "volatile" in den Ring.
> Beim Datenaustausch Main<->Interrupt können die Wunder bewirken.

Die habe ich doppelt und dreifach überprüft. Hast du eine bestimmte 
Stelle im Auge?

von Peter D. (peda)


Lesenswert?

Ralf Eden schrieb:
> Die habe ich doppelt und dreifach überprüft. Hast du eine bestimmte
> Stelle im Auge?

Volatile habe ich grad gefunden. Ist eben schwer, sich in einem fremden 
Code zurecht zu finden.
Atomic braucht man, wenn mehrere Datenbytes konsistent sein müssen. Wo 
das in Deinem Code nötig wäre, kann ich noch nicht sagen.

von Falk B. (falk)


Lesenswert?

Ralf Eden schrieb:

>> Auf den ersten Blick sehe ich keinen massiven Fehler. Aber es würde mich
>> nicht wundern, wenn dein Funktion zum Erzeugen neuer Anzeigemuster
>> spinnt. Das reine Multiplexen sieht erstmal OK aus.
>
> Kannst du das präzisieren? Was würdest du genau anders machen?

Einfach mal eine EINFACHE Funktion schreiben, die einfach ein paar 
Zahlen hochzählt und anzeigt.

>  Das seltsame ist ja, dass die Probleme erst auftreten, sobald ich zu
> viele Parameter per Zufall erzeuge.

Wo denn?

In deiner Hauptschleife wählst du zufällig eine von 5 Funktionen aus. In 
den einzelnen Funktion stecken auch wieder lange delays. Aber das ist 
nebensächlich. Denn das Multiplexing ist davon unberührt. Bestenfall 
wenn die CPU-Last im Multiplexing zu hoch wird (sehr nahe 100%), kommt 
das Hauptprogramm gar nicht mehr merklich vorwärts. Das kann man aber 
messen, auch ohne Oszi.

Schalte in JEDEM Interrut zu Beginn ein IO-Pin auf HIGH und am Ende 
wieder auf LOW. Damit kann man die CPU-Last der ISRs messen. Mit dem 
Oszi ist es komfortabel, es reicht aber auch ein Multimeter! Denn das 
mißt den Mittelwert des Signals. Wenn du dort >90% von VCC mißt, hast du 
ein Problem.

> Solange ich in diesem Fall die
> beiden Directions fest übergebe klappt alles.

Wo denn? Mit welcher Funktion?

 Ich kann auch die
> Directions per Zufall bestimmen und dafür die Axen fest übergeben. Dann
> läuft es auch. Mein Eindruck ist, dass einzig und allein die Anzahl der
> rand() Aufrufe den Unterschied macht.

Sicher nicht, denn die sind relativ kurz, ein paar Dutzend Takte.

Man kann den Spies auch mal rumdrehen. Lass die ISRs AUS! Kein sei() vor 
der Hauptschleife! Und dann lass deine Datengenerierungsfunktionen mal 
laufen und schalte vor jedem Aufruf/Durchlauf eine Status-LED an und 
nach dem Aufruf aus. Dann siehst du, ob da was langsamer wird oder 
stehen bleibt, wenn du deine Aufrufparameter veränderst.

von Ralf Eden (Gast)


Lesenswert?

Falk B. schrieb:
> Wo denn?
>

Siehst du in der Main. Dort sind zwei Funktionsaufrufe auskommentiert. 
So wie der Code JETZT ist, funktioniert er tadellos. Erst wenn durch 
diese beiden veränderten Funktionsaufrufe weitere rand Aufrufe statt 
finden fangen die Probleme an. Ich kann aber dann an anderer Stelle im 
Pfad rand Aufrufe weg nehmen und es klappt wieder.

von Peter D. (peda)


Lesenswert?

Falk B. schrieb:
> In
> den einzelnen Funktion stecken auch wieder lange delays.

Das kann die Ursache sein. _delay_ms(1); geht davon aus, daß es 16000 
Zyklen verbraten soll. Wenn es aber nur jede 1ms (1/960Hz) für einen 
Zyklus dran kommt, ist es 16000-fach langsamer (16s statt 1ms).

von Ralf Eden (Gast)


Lesenswert?

Peter D. schrieb:
> Falk B. schrieb:
> In
> den einzelnen Funktion stecken auch wieder lange delays.
>
> Das kann die Ursache sein. _delay_ms(1); geht davon aus, daß es 16000
> Zyklen verbraten soll. Wenn es aber nur jede 1ms (1/960Hz) für einen
> Zyklus dran kommt, ist es 16000-fach langsamer (16s statt 1ms).

Guter Punkt, aber nochmal. So wie das Programm jetzt ist läuft es wie 
gewünscht. Dann würde es ja gar nicht laufen.

Beitrag #5794641 wurde vom Autor gelöscht.
von Peter D. (peda)


Lesenswert?

Ralf Eden schrieb:
> Erst wenn durch
> diese beiden veränderten Funktionsaufrufe weitere rand Aufrufe statt
> finden fangen die Probleme an.

Dann füg doch einfach mal in die Mainloop eine Schleife mit 
rand-Aufrufen ein, z.B. 10, 100 oder 1000.
Ich denke mal, nicht die rands sind das Problem, sondern was mit deren 
Werten gemacht wird.

von Falk B. (falk)


Lesenswert?

Ralf Eden schrieb:
> Falk B. schrieb:
>> Wo denn?
>>
>
> Siehst du in der Main. Dort sind zwei Funktionsaufrufe auskommentiert.
> So wie der Code JETZT ist, funktioniert er tadellos. Erst wenn durch
> diese beiden veränderten Funktionsaufrufe weitere rand Aufrufe statt
> finden fangen die Probleme an. Ich kann aber dann an anderer Stelle im
> Pfad rand Aufrufe weg nehmen und es klappt wieder.

OK. Hmmm, merkwürdig. Denn das sind einfache, aufeinanderfolgende 
Funktionsaufrufe.

Deine Funktion

void var_delay_ms(double ms)
{
  while(0 < ms)
  {
    _delay_ms(1);
    --ms;
  }
}

funktioniert zwar, der Parameter MS ist aber mit double nonsense. Die 
Funktion kann nur ganzzahlige Millisekunden warten, also reicht ein 
Paramter vom Typ integer oder Long. aber das ist nicht das Problem.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Der Quelltext ist wiedermal das allerbeste Beispiel warum C++ und andere 
Objektorientierte Sprachen auf kleineren Mikrocontrollern 
kontraproduktiv sind, du verlierst einfach absolut die Übersicht.

Oder anders gefragt, wieviele Takte brauchen deine ISR?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ralf Eden schrieb:
> Erst wenn durch diese beiden veränderten Funktionsaufrufe weitere rand
> Aufrufe statt finden
Was passiert denn, wenn du die Funktion mal so oder mal so aufrufst:
1
        // mal so
2
        CFbelt(randAxis(), ((rand()%20)+25), DIR_ASC);  
3
        // un beim zweiten Test so
4
        CFbelt(randAxis(), ((rand()%20)+25), DIR_DESC);

Denn das hier scheint mir sehr eigenartig: 2 Möglichkeiten, aber modulo 
3...
1
Direction randDirection(void)
2
{
3
  switch(rand()%3)  // stimmt das wirklich?
4
  {
5
    case 0:
6
    default:
7
      return DIR_ASC;
8
    break;
9
    case 1:
10
      return DIR_DESC;
11
    break;
12
  }
13
}
Ich hätte das so gemacht:
1
Direction randDirection(void)
2
{
3
  if(rand()&1) return DIR_ASC;
4
5
  return DIR_DESC;
6
}

: Bearbeitet durch Moderator
von Andreas M. (andiator)


Lesenswert?

ist so was nicht eine Endlosschleife?
1
for(uint8_t i=6; i>=0; i--)

von Ralf Eden (Gast)


Lesenswert?

Falk B. schrieb:
> OK. Hmmm, merkwürdig. Denn das sind einfache, aufeinanderfolgende
> Funktionsaufrufe.
>
> Deine Funktion
>
> void var_delay_ms(double ms)
> {
>   while(0 < ms)
>   {
>     _delay_ms(1);
>     --ms;
>   }
> }
>
> funktioniert zwar, der Parameter MS ist aber mit double nonsense. Die
> Funktion kann nur ganzzahlige Millisekunden warten, also reicht ein
> Paramter vom Typ integer oder Long. aber das ist nicht das Problem.

Ich habe Double genommen, weil _delay_ms auch einen Double Wert 
erwartet, wenn ich nicht irre. Aber stimmt ein uint16 sollte ausreichen.

Gut also werde ich mir wenn ich Zuhause bin die ISR nochmal genauer 
anschauen. Wenn die Last hier tatsächlich das Problem sein sollte, 
müsste es ja mit einem größeren Prescaler laufen. Trotzdem seltsam aber 
schauen wir mal.

von Ralf Eden (Gast)


Lesenswert?

Andreas M. schrieb:
> ist so was nicht eine Endlosschleife?for(uint8_t i=6; i>=0; i--)

Ääh! Naja genau genommen sollte es überlaufen und dann trzd stoppen. 
Aber gut gesehen dass ist natürlich falsch!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Andreas M. schrieb:
> ist so was nicht eine Endlosschleife?
> for(uint8_t i=6; i>=0; i--)
Mich würde auch die Meinung des Compilers dazu interessieren...

von Andreas M. (andiator)


Lesenswert?

Ralf Eden schrieb:
> Ääh! Naja genau genommen sollte es überlaufen und dann trzd stoppen.

Es kann nicht stoppen, denn wegen unsigned ist die Bedingung immer true 
;)

von m.n. (Gast)


Lesenswert?

Den Code habe ich mir nicht angesehen.
Typisch für ein Hängenbleiben eines Programmes ist, wenn der Stack 
überläuft.

Hast Du genug Platz für den Stack vorgesehen oder kann C++ an anderen 
Stellen zu einem Überlauf führen?

von Vlad T. (vlad_tepesch)


Lesenswert?

var_delay_ms sieht für mich äußerst verdächtig aus.

stell das mal um, dass es ein Int als Argument nimmt und mit ints 
rechnet.

von Falk B. (falk)


Lesenswert?

Kleiner Tipp. Die Verdrehung der IO-Bits kann man einfach und DEUTLICH 
schneller mit einer Tabelle machen. Dann sieht das so aus.
1
uint8_t bit_mix[256] = {.....};
2
3
*_ptrList[colInd] =  bit_mix[localDataByte];

Da deine Pinzuordnung konstant ist, kann man die Tabelle auch als 
Konstante in den Flash legen, das spart 256 Bytes RAM. Dann muss man sie 
aber vorher per Script, Excel oder zu Fuß erstellen 8-0. Im RAM kann man 
sie per Funktion erstellen.

von Ralf Eden (Gast)


Lesenswert?

Lothar M. schrieb:
>         CFbelt(randAxis(), ((rand()%20)+25), DIR_ASC);
>         // un beim zweiten Test so
>         CFbelt(randAxis(), ((rand()%20)+25), DIR_DESC);
> ...
>   switch(rand()%3)  // stimmt das wirklich?

Oh je. Also rand()%3 spuckt mir Zahlen von 0 bis 2 aus. Das ist eins 
Zuviel, stimmt. Sollte der Default: zwar auffangen, aber falsch ist es 
allemal. Wird geändert. Und ich Idiot habe DIR_DESC gar nicht einzeln 
getestet. Und da kommen wir zu

Andreas M. schrieb:
> ist so was nicht eine Endlosschleife?
> for(uint8_t i=6; i>=0; i--)

Andreas M. schrieb:
> Es kann nicht stoppen, denn wegen unsigned ist die Bedingung immer true
> ;)

Das sieht doch stark nach dem Übeltäter aus.

von Ralf Eden (Gast)


Lesenswert?

Vlad T. schrieb:
> var_delay_ms sieht für mich äußerst verdächtig aus.
>
> stell das mal um, dass es ein Int als Argument nimmt und mit ints
> rechnet.

Jupp wird gemacht. Danke!



Falk B. schrieb:
> Kleiner Tipp. Die Verdrehung der IO-Bits kann man einfach und
> DEUTLICH
> schneller mit einer Tabelle machen. Dann sieht das so aus.
> uint8_t bit_mix[256] = {.....};
>
> *_ptrList[colInd] =  bit_mix[localDataByte];
>
> Da deine Pinzuordnung konstant ist, kann man die Tabelle auch als
> Konstante in den Flash legen, das spart 256 Bytes RAM. Dann muss man sie
> aber vorher per Script, Excel oder zu Fuß erstellen 8-0. Im RAM kann man
> sie per Funktion erstellen.

Ja stimmt wohl. Danke für den Hinweis!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ralf Eden schrieb:
> Das sieht doch stark nach dem Übeltäter aus.
Mich würde nach wie vor interessieren, was der Compiler dazu meint. 
Lässt der das tatsächlich unkommentiert durch?

von Hannes J. (hannes_j)


Lesenswert?

Lothar M. schrieb:
> Andreas M. schrieb:
>> ist so was nicht eine Endlosschleife?
>> for(uint8_t i=6; i>=0; i--)
> Mich würde auch die Meinung des Compilers dazu interessieren...

Keine Warnung, kein Fehler.. Ich benutze den AVR/GNU C++ in den 
Standardeinstellungen des Atmel Studio. Außer Unterschiede und Einflüsse 
unterschiedlicher Optimierungsflags hab ich mich damit auch noch nicht 
wirklich beschäftigt.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Ralf Eden schrieb:
>> Das sieht doch stark nach dem Übeltäter aus.
> Mich würde nach wie vor interessieren, was der Compiler dazu meint.
> Lässt der das tatsächlich unkommentiert durch?

Ja, keine Warnung, keinen Fehler, produziert nur ne 1A Endlosschleife.

: Bearbeitet durch User
von Hannes J. (hannes_j)


Lesenswert?

Irgendeine Möglichkeit ihn dazu zu bringen, sowas anzuzeigen?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hannes J. schrieb:
> Keine Warnung, kein Fehler..
Ok, die Warnung gibts erst ab -Wtype-limits, und das wäre dann drin z.B. 
in -Wextra (zusammen mit anderen zusätzlichen Warnings für C++):
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Warning-Options.html

Deshalb schlägt dieses Problem hier immer wieder auf...   ;-)

: Bearbeitet durch Moderator
Beitrag #5794740 wurde vom Autor gelöscht.
von Ralf Eden (Gast)


Lesenswert?

Lothar M. schrieb:
> Hannes J. schrieb:
>> Keine Warnung, kein Fehler..
> Ok, die Warnung gibts erst ab -Wtype-limits, und das wäre dann drin z.B.
> in -Wextra (zusammen mit anderen zusätzlichen Warnings für C++):
> https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Warning-Options.html
>
> Deshalb schlägt dieses Problem hier immer wieder auf...   ;-)

Dazu kommt, dass AVR Studio die Option nur im C Compiler anbietet, nicht 
im C++. Habe sie jetzt manuell eingefügt und jetzt meckert er auch.

von Veit D. (devil-elec)


Lesenswert?

Falk B. schrieb:

> Was glaubst du, was in rand() drin steckt? Eine Blattlaus die würfelt?

Hallo Falk,

ist zu lustig, ich hätte auf "Kleine Hufeisennase" getippt. :-)

von Veit D. (devil-elec)


Lesenswert?

Hallo,

die delays in den Funktionen und in der Hauptschleife stören nicht?

Ohne Oszi kannste dennoch eine LED in Hauptschleife blinken lassen.
Musste aber ohne delay machen. Überhaupt würde ich delay rauswerfen.
Wenn sich die Frequenz optisch verändert sieht man das.

von Wolfgang (Gast)


Lesenswert?

Ralf Eden schrieb:
> Meine Testmöglichkeiten sind bzgl Oszi dummer Weise eingeschränkt, denn
> ich habe keins. :(

Dafür brauchst du kein Oszi. Es reicht ein minimalistischer 
Logikanalysator im Gegenwert eines Kantinenmittagessens.

von Hannes J. (hannes_j)


Lesenswert?

Hab da noch zwei Fehler entdeckt. Du rufst CFfullPulsation() und 
TPflash() mit Parametern auf die größer als 8Bit sein können. Die 
Funktionen erwarten da aber uint8 ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.