Der AVR-/ARDUINO-Faden

Der chaotische Hauptfaden

Moderatoren: Sven, Heaterman, TDI, Finger

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » Di 20. Okt 2015, 16:09

xanakind hat geschrieben:Kurze Info:Ich hab mich diesen Abend nun mal in ruhe an mein Kotzlampenprogramm gesetzt und es funktioniert nun alles so wie ich es will!
Und? Wie oft mußtest Du schon kotzen (also jetzt nicht wegen technischen Problemen sondern wegen der Blinkerei - taugt das?)? :P

Ich hab' auch mal ne Frage, und zwar: Gibt es eine unglaublich clevere Lösung, um aus einer Zahl die Hunderter, Zehner und Einer zu trennen? Z.Zt. mache ich
Code: Alles auswählen
void Display_Dec_3(const uint8_t segment,uint8_t value)
{
   uint8_t temp=value/100;
   ASMData[segment]=Numberz[temp];
   value-=temp*100;
   temp=value/10;
   ASMData[segment+1]=Numberz[temp];
   value-=temp*10;
   ASMData[segment+2]=Numberz[value];
}

Der Compiler kriegt das auch recht klein, aber evtl. gibt's da ja was ganz Schlaues? Printf kann ich nicht nehmen, weil das anschließend (über das Array "Numberz") in ein 7Segment-Zeichen gewandelt wird, da kann ich nicht mit ASCII kommen.

Weiters: kann ich dem avr-objdump beim Disassemblieren irgendwie sagen, das es den ganzen Krempel vor dem eigentlichen Disassembly weglassen soll?

BTW, ist das eigentlich eine Art Entwicklerhumor, daß der AVR-GCC lieber "eor r1,r1" macht als "clr r1", oder hat das tieferen Sinn? Zykle- und Wortnzahl sind gleich, die effektiven Statusbits auch... einfach, "weil's geht"?
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon Bauteiltöter » Di 20. Okt 2015, 18:30

Name vergessen hat geschrieben:
Code: Alles auswählen
void Display_Dec_3(const uint8_t segment,uint8_t value)
{
   uint8_t temp=value/100;
   ASMData[segment]=Numberz[temp];
   value-=temp*100;
   temp=value/10;
   ASMData[segment+1]=Numberz[temp];
   value-=temp*10;
   ASMData[segment+2]=Numberz[value];
}


Ich schreib das mal etwas um
Code: Alles auswählen
void Display_Dec_3(const uint8_t segment,uint8_t value)
{
   uint8_t einer, zehner, hunderter;

   //Hunderter berechnen
   hunderter=value/100;
   
   //Zehner berechnen
   value-=hunderter*100;
   zehner=value/10;
   
   //Einer berechnen
   einer-=zehner*10;

}


Das ganze braucht also zwei Divisionen, zwei Multiplikationen und zwei Subtraktionen.

Das ganze könnte man auch mit Divisionen und Modulo-Operationen berechnen:
Code: Alles auswählen
void Display_Dec_3(const uint8_t segment,uint8_t value)
{
   uint8_t einer, zehner, hunderter;

   hunderter = value / 100;
   
   zehner = (value % 100) / 10;
   
   einer =  value % 10;
}


das ganze braucht offensichtlich zwei Divisionen und zwei Modulo-Operationen die im Grunde auch nur Divisionen sind. Divisionen dürften langsamer sein als Multiplikationen, der Teil ist also sehr wahrscheinlich nicht mal gleichwertig zu deinem Code oben -> Schlecht.

Aber was noch auffällt ist, dass wir erst value durch 100 teilen und dann den Rest dieser Operation haben wollen. Der Rest bleibt ja bei der Division eh stehen -> wir müssen nur da ran kommen und können uns so zwei Divisionen sparen.

Die avr-libc bietet dafür die Funktion div(). Das reference manual hat dazu nur ein bisschen zu sagen:

Code: Alles auswählen
div_t div(
   int __num,
   int __denom)

The div() function computes the value num/denom and returns the quotient and remainder in a structure named div_t that contains two int members named quot and rem.


Daraus wird also:

Code: Alles auswählen
void Display_Dec_3(const uint8_t segment,uint8_t value)
{
   uint8_t einer, zehner, hunderter;
   div_t temp;
   
   temp = div(value,100);
   hunderter = temp.quot;
   temp = div(temp.rem, 10);
   zehner = temp.quot;
   einer =  temp.rem;
}


Der Code enthält jetzt nurnoch zwei Divisionen, dafür werden beide jedoch int anstatt uint8_t durchgeführt, also 16 Bit statt 8 Bit. Außerdem kommen die Zugriffe und die Übergabe der Strukturen dazu, da bin ich mir gerade unsicher was der Optimierer da heraus holt.
Was jetzt wirklich schneller ist muss man mal ausprobieren indem man es durch den Compiler jagt, ich habe leider gerade keinen vernünftigen avr-gcc mit Konsole zur Verfügung.

Gernerell gilt jedoch
premature optimization is the root of all evil.

Ist es wirklich nötig dass das optimiert wird? In 99.9% wird sowas für eine Anzeige benutzt, die wird sowieso nicht mit 100Hz geupdatet, wer soll denn das noch lesen? Somit ist es nicht zeitkritisch und sollte lesbar gehalten werden. Die 3. Variante ist definitiv die unleserlichste, ich würde die 2. Wählen. Erst wenn es klemmt würde ich irgendetwas optimieren.


Name vergessen hat geschrieben:BTW, ist das eigentlich eine Art Entwicklerhumor, daß der AVR-GCC lieber "eor r1,r1" macht als "clr r1", oder hat das tieferen Sinn? Zykle- und Wortnzahl sind gleich, die effektiven Statusbits auch... einfach, "weil's geht"?


Eine finale Antwort darauf kann ich nicht geben, aber wenn das Entwicklerhumor ist, dann haben die GCC-Entwickler diesen Humor von Atmel übernommen. Z.B. im instruction set manual findet man die "eor"-Kombination auch überall anstelle des "clr". Als Grund kann ich mir eigentlich nur vorstellen das früher einige ältere Chips "clr" nicht können. Intern passiert bei "clr" und "eor" eh genau das gleiche, laut manual führt auch "clr" eine xor-Operation mit sich selber durch.
Benutzeravatar
Bauteiltöter
 
Beiträge: 249
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitragvon ferdimh » Di 20. Okt 2015, 19:06

Auf fast allen Architekturen, die Register-Register-Operationen beherrschen, ist der CLR Register als XOR Register,Register implementiert. Hierzu wird einfach dem Assembler ein weiterer Opcode beigebracht, der (Im Binary) exakt das gleiche Bitmuster wie XOR R,R hat. Deswegen kann der Disassembler die beiden Opcodes nicht unterscheiden. Ein Extra CLR-Opcode wäre zusätzliche Logik in der CPU ohne jeden Zusatznutzen.
Manche Architekturen, bei denen die Trivialimplementierung nicht machbar ist (weil keine Register-Register-OP möglich), wie z.B. 6502, haben oft nicht mal ein CLR, sondern nötigen dem Programmierer (oder Compiler) ein LDX #0 (oder äquivalent) auf. Auf entsprechenden Architekturen haben rückwärtslaufende Schleifen eine hohe Popularität erlangt, da hier das Laden nicht aufwändiger wrid und das Prüfen auf Null einfacher ist.
Davon abgesehen sind rückwärtszählende Schleifen generell eine gute Idee, wenn es wirklich schnell gehen muss.
Letzten Endes ist Null auch nur eine Zahl.

Zur ursprünglichen Frage: Ich würde mir eine GetDigit-Funktion in der AVR-Libc wünschen. Sensationell schöner wirds nicht, aber die Aufgabestellung wird oft benötigt. Und das "Teilen und Modulodividieren" Konstrukt ist irgendwie immer etwas bäh. Aber es geht wirklich nicht besser (zumindest nicht in schön und universell).
Benutzeravatar
ferdimh
 
Beiträge: 5914
Registriert: Fr 16. Aug 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitragvon Bauteiltöter » Di 20. Okt 2015, 19:48

ferdimh hat geschrieben:Auf fast allen Architekturen, die Register-Register-Operationen beherrschen, ist der CLR Register als XOR Register,Register implementiert. Hierzu wird einfach dem Assembler ein weiterer Opcode beigebracht, der (Im Binary) exakt das gleiche Bitmuster wie XOR R,R hat. Deswegen kann der Disassembler die beiden Opcodes nicht unterscheiden. Ein Extra CLR-Opcode wäre zusätzliche Logik in der CPU ohne jeden Zusatznutzen.


Tatsächlich, ich habe gerade mal nachgeschaut: Beide Operationen werden mit "0010 01xx xxxx xxxxx" als Bitmuster codiert. -> Es gibt für alles eine logische Erklärung...
Benutzeravatar
Bauteiltöter
 
Beiträge: 249
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » Mi 21. Okt 2015, 17:18

Heh, danke für die spontanen Antworten! Wegen der Optimierung: ist in der Tat nicht zeitkritisch, es läuft im Mainloop und das Wichtige passiert in einer ISR. Ich hatte halt so dieses beschriebene "igitt"-Gefühl bei der Sache, daher hatte ich gedacht, irgend eine clevere Konstruktion übersehen zu haben. :)

Aber der Vollständigkeit halber hier die Ergebnisse vom Compiler (ich mußte am Ende die Zuweisungen einfügen, da sonst lediglich "ret" aus den Funktionen wurde. :) Das sind dann die drei sts am Ende. Zumindest der Anzahl der Befehle nach ist die Variante mit div_t die kürzeste (12 Befehle incl. ret), danach die Modulo-Variante mit 13 Befehlen, gefolgt von der explizit-Variante mit 17 Befehlen und dem Original mit ebenfalls 17 Befehlen.
Code: Alles auswählen
Aus
void Display_Dec_3_div_t(const uint8_t segment,uint8_t value)
{
   uint8_t einer, zehner, hunderter;
   div_t temp;
   
   temp = div(value,100);
   hunderter = temp.quot;
   temp = div(temp.rem, 10);
   zehner = temp.quot;
   einer =  temp.rem;
ASMData[0]=hunderter;
ASMData[1]=zehner;
ASMData[2]=einer;
}
wurde:

000000ee <Display_Dec_3_div_t> push   r28
000000f0 <Display_Dec_3_div_t+0x2> mov   r24, r22
000000f2 <Display_Dec_3_div_t+0x4> ldi   r22, 0x64   ; 100
000000f4 <Display_Dec_3_div_t+0x6> ldi   r23, 0x00   ; 0
000000f6 <Display_Dec_3_div_t+0x8> ldi   r25, 0x00   ; 0
000000f8 <Display_Dec_3_div_t+0xa> rcall   .-3012      ; 0xfffff536 <__eeprom_end+0xff7ef536>
000000fa <Display_Dec_3_div_t+0xc> mov   r28, r22
000000fc <Display_Dec_3_div_t+0xe> ldi   r22, 0x0A   ; 10
000000fe <Display_Dec_3_div_t+0x10> ldi   r23, 0x00   ; 0
00000100 <Display_Dec_3_div_t+0x12> rcall   .-3020      ; 0xfffff536 <__eeprom_end+0xff7ef536>
00000102 <Display_Dec_3_div_t+0x14> sts   0x0095, r28
00000106 <Display_Dec_3_div_t+0x18> sts   0x0096, r22
0000010a <Display_Dec_3_div_t+0x1c> sts   0x0097, r24
0000010e <Display_Dec_3_div_t+0x20> pop   r28
00000110 <Display_Dec_3_div_t+0x22> ret

Code: Alles auswählen
Aus
void Display_Dec_3_modulo(const uint8_t segment,uint8_t value)
{
   uint8_t einer, zehner, hunderter;

   hunderter = value / 100;
   
   zehner = (value % 100) / 10;
   
   einer =  value % 10;
ASMData[0]=hunderter;
ASMData[1]=zehner;
ASMData[2]=einer;
}

wurde:

00000112 <Display_Dec_3_modulo> mov   r19, r22
00000114 <Display_Dec_3_modulo+0x2> mov   r24, r22
00000116 <Display_Dec_3_modulo+0x4> ldi   r22, 0x64   ; 100
00000118 <Display_Dec_3_modulo+0x6> rcall   .-3068      ; 0xfffff51e <__eeprom_end+0xff7ef51e>
0000011a <Display_Dec_3_modulo+0x8> mov   r21, r24
0000011c <Display_Dec_3_modulo+0xa> mov   r24, r25
0000011e <Display_Dec_3_modulo+0xc> ldi   r18, 0x0A   ; 10
00000120 <Display_Dec_3_modulo+0xe> mov   r22, r18
00000122 <Display_Dec_3_modulo+0x10> rcall   .-3078      ; 0xfffff51e <__eeprom_end+0xff7ef51e>
00000124 <Display_Dec_3_modulo+0x12> mov   r20, r24
00000126 <Display_Dec_3_modulo+0x14> mov   r24, r19
00000128 <Display_Dec_3_modulo+0x16> rcall   .-3084      ; 0xfffff51e <__eeprom_end+0xff7ef51e>
0000012a <Display_Dec_3_modulo+0x18> sts   0x0095, r21
0000012e <Display_Dec_3_modulo+0x1c> sts   0x0096, r20
00000132 <Display_Dec_3_modulo+0x20> sts   0x0097, r25
00000136 <Display_Dec_3_modulo+0x24> ret

Code: Alles auswählen
Aus
void Display_Dec_3_explizit(const uint8_t segment,uint8_t value)
{
   uint8_t einer, zehner, hunderter;

   //Hunderter berechnen
   hunderter=value/100;
   
   //Zehner berechnen
   value-=hunderter*100;
   zehner=value/10;
   
   //Einer berechnen
   einer-=zehner*10;
ASMData[0]=hunderter;
ASMData[1]=zehner;
ASMData[2]=einer;
}

wurde:

00000138 <Display_Dec_3_explizit> mov   r19, r22
0000013a <Display_Dec_3_explizit+0x2> mov   r24, r22
0000013c <Display_Dec_3_explizit+0x4> ldi   r22, 0x64   ; 100
0000013e <Display_Dec_3_explizit+0x6> rcall   .-3106      ; 0xfffff51e <__eeprom_end+0xff7ef51e>
00000140 <Display_Dec_3_explizit+0x8> mov   r18, r24
00000142 <Display_Dec_3_explizit+0xa> mov   r24, r19
00000144 <Display_Dec_3_explizit+0xc> ldi   r25, 0x64   ; 100
00000146 <Display_Dec_3_explizit+0xe> mul   r18, r25
00000148 <Display_Dec_3_explizit+0x10> sub   r24, r0
0000014a <Display_Dec_3_explizit+0x12> eor   r1, r1
0000014c <Display_Dec_3_explizit+0x14> ldi   r22, 0x0A   ; 10
0000014e <Display_Dec_3_explizit+0x16> rcall   .-3122      ; 0xfffff51e <__eeprom_end+0xff7ef51e>
00000150 <Display_Dec_3_explizit+0x18> ldi   r25, 0xF6   ; 246
00000152 <Display_Dec_3_explizit+0x1a> mul   r24, r25
00000154 <Display_Dec_3_explizit+0x1c> mov   r25, r0
00000156 <Display_Dec_3_explizit+0x1e> eor   r1, r1
00000158 <Display_Dec_3_explizit+0x20> sts   0x0095, r18
0000015c <Display_Dec_3_explizit+0x24> sts   0x0096, r24
00000160 <Display_Dec_3_explizit+0x28> sts   0x0097, r25
00000164 <Display_Dec_3_explizit+0x2c> ret

Code: Alles auswählen
Und aus dem Original (nur minimal umgeschrieben)
void Display_Dec_3_orig(const uint8_t segment,uint8_t value)
{
   uint8_t temp=value/100,hunderter,zehner,einer;
   hunderter=temp;
   value-=temp*100;
   temp=value/10;
   zehner=temp;
   value-=temp*10;
   einer=value;
ASMData[0]=hunderter;
ASMData[1]=zehner;
ASMData[2]=einer;
}

wurde:

00000166 <Display_Dec_3_orig> mov   r19, r22
00000168 <Display_Dec_3_orig+0x2> mov   r24, r22
0000016a <Display_Dec_3_orig+0x4> ldi   r22, 0x64   ; 100
0000016c <Display_Dec_3_orig+0x6> rcall   .-3152      ; 0xfffff51e <__eeprom_end+0xff7ef51e>
0000016e <Display_Dec_3_orig+0x8> mov   r18, r24
00000170 <Display_Dec_3_orig+0xa> ldi   r24, 0x64   ; 100
00000172 <Display_Dec_3_orig+0xc> mul   r18, r24
00000174 <Display_Dec_3_orig+0xe> sub   r19, r0
00000176 <Display_Dec_3_orig+0x10> eor   r1, r1
00000178 <Display_Dec_3_orig+0x12> mov   r24, r19
0000017a <Display_Dec_3_orig+0x14> ldi   r22, 0x0A   ; 10
0000017c <Display_Dec_3_orig+0x16> rcall   .-3168      ; 0xfffff51e <__eeprom_end+0xff7ef51e>
0000017e <Display_Dec_3_orig+0x18> ldi   r25, 0x0A   ; 10
00000180 <Display_Dec_3_orig+0x1a> mul   r24, r25
00000182 <Display_Dec_3_orig+0x1c> sub   r19, r0
00000184 <Display_Dec_3_orig+0x1e> eor   r1, r1
00000186 <Display_Dec_3_orig+0x20> sts   0x0095, r18
0000018a <Display_Dec_3_orig+0x24> sts   0x0096, r24
0000018e <Display_Dec_3_orig+0x28> sts   0x0097, r19
00000192 <Display_Dec_3_orig+0x2c> ret


Das mit dem Opcode ist tatsächlich wahr, ich habe eben geguckt und gesehen, daß der Disassembler aus meinen clr's im Assembler-Teil auch eor's gemacht hat. :)
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon xoexlepox » Mi 21. Okt 2015, 21:58

ist in der Tat nicht zeitkritisch, es läuft im Mainloop und das Wichtige passiert in einer ISR. Ich hatte halt so dieses beschriebene "igitt"-Gefühl bei der Sache,...

Das "igitt"-Gefühl habe ich u.a., wenn ich Programme sehe, bei denen im in der Interrupt Service Routine "Rechnerei" ausgeführt wird ;) Wenn es nicht wirklich zeitkritisch ist (die "Rechnerei" braucht meist -je nach Daten- unterschiedliche Zeiten), mache ich solche Aktionen über ein Flagbit in einer globalen (volatile!) Variablen, welches die Anforderung anzeigt, die in der Mainloop abgehandelt wird, und die dann durch Löschen des Flags das "done" anzeigt.
Benutzeravatar
xoexlepox
 
Beiträge: 4270
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitragvon Bauteiltöter » Mi 21. Okt 2015, 22:57

Also dann haben wir jetzt vier Versionen:

  1. mit div
  2. Mit Modulo
  3. Umgestellt ohne Zwischenvariable
  4. Umgestellt mit Zwischenvariable

Hier mal die Ergebnisse des Simulators:
Code: Alles auswählen
  | Cycles
a |   17
b |   36
c |   30
d |   30


Damit ist die Variante mit der div()-Routine wohl vorzuziehen.

Dazu muss ich jedoch sagen, dass mein GCC aus dem gleichen C-Code deutlich andere Dinge macht als deiner. Für Code b) mit den ganzen Modulo-Operationen ruft er kein einziges mal die Divisionsroutine auf sondern erledigt das mit Bitpopel-Magie (mul+swap+andi).
Welche GCC-Version verwendest du?


Beim Füttern des Simulators wurde ich echt malwieder vom GCC überrascht.
Die Funktionen b) und d) werden beim Aufruf mit festen Parametern vom Compiler komplett ausgemerzt.
Code: Alles auswählen
void f_b(const uint8_t segment,uint8_t value)
{
   uint8_t einer, zehner, hunderter;

   hunderter = value / 100;
   
   zehner = (value % 100) / 10;
   
   einer =  value % 10;
   ASMData[0]=hunderter;
   ASMData[1]=zehner;
   ASMData[2]=einer;
}

int main(void)
{
   const uint8_t unused = 0;
   
   f_b(unused,112);
      
    while(1){}
}


Davon bleibt nichts stehen außer:
Code: Alles auswählen
0000002B  LDI R24,0x01      Load immediate
0000002C  STS 0x0100,R24      Store direct to data space
0000002E  STS 0x0101,R24      Store direct to data space
00000030  LDI R24,0x02      Load immediate
00000031  STS 0x0102,R24      Store direct to data space
00000033  RJMP PC-0x0000      Relative jump

Also das laden von '1', '1' und '2' in die Speicherstellen für hunderter/zehner/einer.
Benutzeravatar
Bauteiltöter
 
Beiträge: 249
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » Do 22. Okt 2015, 17:55

Erstaunlich, daß aus der zweitkürzesten Variante dann doch die meisten Zyklen werden. Leider habe ich keinen Simulator, daher kann ich meinen code da nicht drin testen. Immerhin, a) gewinnt bisher in allen betrachteten Bereichen. Das macht ja auch Sinn, denn ansonsten hätten die AVR-Libc-Leute wohl auch eine andere Implementierung benutzt oder das struct gleich wieder verworfen.
Als AVR-gcc habe ich
$avr-gcc -v
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/4.7.2/lto-wrapper
Target: avr
Configured with: ../src/configure -v --enable-languages=c,c++ --prefix=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-libssp --build=i486-linux-gnu --host=i486-linux-gnu --target=avr
Thread model: single
gcc version 4.7.2 (GCC)

Jetzt könnte der Unterschied natürlich auch noch an Optimierungseinstellungen liegen. Ich verwende:
avr-gcc -g -Os -mmcu=atmega8 -c main.c
avr-gcc -g -mmcu=atmega8 -o main.o

avr-objcopy -j .text -j .data -O ihex out.elf out.hex

Und über den verwendeten Prozessor haben wir uns auch nicht ausgelassen, zumindest gibt es ja Zyklen-Unterschiede zwischen den Atmega- und Xmega Cores. Ich habe, wie im Skript zu sehen, z.Zt. einen ATMega8 (ATMega8-16PU) zwischen.
Bauteiltöter hat geschrieben:Beim Füttern des Simulators wurde ich echt malwieder vom GCC überrascht.
Die Funktionen b) und d) werden beim Aufruf mit festen Parametern vom Compiler komplett ausgemerzt.
Schlaues Teil. :) Na, meiner hat ja auch, s.O., gemerkt, daß die Funktion ohne die Zuweisungen am Ende auch ohne Sinn ist und sie durch ret ersetzt. Weshalb allerdings das ret übrig blieb, ist mir nicht klar, immerhin hätte er das auch vollständig entfernen können, da es nicht einmal einen Aufruf im Main dazu gab. Evtl. fürs Debuggen, damit überhaupt was zu finden ist, und man nicht glaubt, der würde das einfach ignorieren?

xoxlepox hat geschrieben:Das "igitt"-Gefühl habe ich u.a., wenn ich Programme sehe, bei denen im in der Interrupt Service Routine "Rechnerei" ausgeführt wird ;) Wenn es nicht wirklich zeitkritisch ist (die "Rechnerei" braucht meist -je nach Daten- unterschiedliche Zeiten), mache ich solche Aktionen über ein Flagbit in einer globalen (volatile!) Variablen, welches die Anforderung anzeigt, die in der Mainloop abgehandelt wird, und die dann durch Löschen des Flags das "done" anzeigt.
Tjoar, so mache ich das "im Prinzip" auch, allerdings hat sich in der ISR jetzt noch ein Zähler für Debouncing-Flag und die Berechnung zweier Blink-Bits eingeschlichen. Ist aber sowieso ein Monster an ISR, weil das Display ziemlich verquer angesteuert werden will (enthält außer den Treibern noch eine Art Portexpander sowie Ansteuerung einer 8x8 Tastenmatrix). Das ganze ist ziemlich verquer zu bedienen, da Teile der Expanderlogik noch durch ein D-FF geprügelt werden müssen, dessen 6 höherwertige Bits allerdings noch LEDs treiben. Na, die Untiefen gefundener Hardware halt. XD
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon Bauteiltöter » Do 22. Okt 2015, 19:35

Name vergessen hat geschrieben:Schlaues Teil. :) Na, meiner hat ja auch, s.O., gemerkt, daß die Funktion ohne die Zuweisungen am Ende auch ohne Sinn ist und sie durch ret ersetzt. Weshalb allerdings das ret übrig blieb, ist mir nicht klar, immerhin hätte er das auch vollständig entfernen können, da es nicht einmal einen Aufruf im Main dazu gab. Evtl. fürs Debuggen, damit überhaupt was zu finden ist, und man nicht glaubt, der würde das einfach ignorieren?


Nein, der Compiler muss das "ret" stehen lassen, die Funktion könnte ja von einem anderen Modul aus aufgerufen werden. Er darf also aus der Funktion selber alles Rauswerfen weil es offensichtlich sinnlos ist, er darf die Funktion aber nicht komplett raus schmeißen. Das dürfte nur der Linker, der macht das aber nur mit aktiviertem LTO (link time optimization). Aktiviert wird das mit -flto, muss vermutlich compiler UND linker als Parameter mitgegeben werden. Ob da noch was zu beachten ist weiß ich jedoch nicht.

Ich habe den GCC 4.8.1, also etwas neuer als deiner. Optimierung war -O1, also optimize for speed, nicht for size. Könnte erklären warum er bei dir springt und es bei mir alles Inline erledigt hat. Warum ist das eigentlich nicht standardmäßig auf -Os? *umstell*
Target war der ATmega88.

Sonstige Optionen:
Code: Alles auswählen
'-funsigned-char' '-funsigned-bitfields' '-D' 'DEBUG' '-O1' '-ffunction-sections' '-fdata-sections' '-fpack-struct' '-fshort-enums' '-g2' '-Wall' '-mmcu=atmega88' '-c' '-std=gnu99' '-v' '-MD' '-MP' '-MF' 'speedtest.d'


Ich habe mal mit allen Optimierungsstufen Compiliert und dabei gemerkt, das ich gestern TOTALEN BULLSHIT ermittelt habe. Sorry. Hier unten sind die neuen, richtigen Werte:
Code: Alles auswählen
  |  -O1   |  -Os | -O2         | -O3
  |  514B  | 470B | 438B | 504B | 429B | 429B
a |  444   |  444 | ?    | 444  | ?    | 443
b |   40   |  252 | ?    | 39   | ?    | 39
c |   36   |  184 | ?    | 35   | ?    | 35
d |   33   |  180 | ?    | 31   | ?    | 31


Die Werte für -O2 und -O3 habe ich zum Ausmessen der einzelnen Funktionen jeweils ein "__attribute__ ((noinline))" verpasst, sonst macht er alles inline.
Gut zu sehen: Meine Lösung mit dem div() schneidet überall beschissen ab. Das liegt daran, dass er dabei immer gewungen wird die Divisionsroutine aufzurufen. Schreibt man es getrennt mit "/" und "%" holt der GCC seinen Voodoo-Bitpopeleitrickkiste raus und steckt die Divisionsroutine müheos in die Tasche. Auch die Lösung b) ist durchgehend langsamer als deine, ich würde dennoch dieese Version bevorzugen - ich finde, man kann es einfach besser lesen. Du scheinst jedoch bereits das Optimum gefunden zu haben.

Irgendeinen vorteil der div()-Funktion muss es jedoch geben...


Auch gut zu sehen: -Os bringt hier einen erheblichen Geschwindigkeitsnachteil, das muss aber nicht immer so sein. Es gibt viele Situationen, wo -Os schneller und kleiner wird als -O1... -O3.

Fazit:
Wenn man mit dem Simulator rummacht, nicht um 22:00 Abends...
Benutzeravatar
Bauteiltöter
 
Beiträge: 249
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » So 25. Okt 2015, 01:58

Bauteiltöter hat geschrieben:Nein, der Compiler muss das "ret" stehen lassen, die Funktion könnte ja von einem anderen Modul aus aufgerufen werden. Er darf also aus der Funktion selber alles Rauswerfen weil es offensichtlich sinnlos ist, er darf die Funktion aber nicht komplett raus schmeißen. Das dürfte nur der Linker, der macht das aber nur mit aktiviertem LTO (link time optimization). Aktiviert wird das mit -flto, muss vermutlich compiler UND linker als Parameter mitgegeben werden. Ob da noch was zu beachten ist weiß ich jedoch nicht.
Ah, OK, das macht Sinn. Ich schätze, das -flto werde ich erstmal nicht benutzen, denn auf diese Weise sehe ich, wenn ich groben Unfug gemacht habe. :)

Bauteiltöter hat geschrieben:Ich habe den GCC 4.8.1, also etwas neuer als deiner.
Heh, hatte ich fast erwartet, Debian sta(b)le eben. :)
Bauteiltöter hat geschrieben:Optimierung war -O1, also optimize for speed, nicht for size. Könnte erklären warum er bei dir springt und es bei mir alles Inline erledigt hat.
Ja, das würde Sinn machen, so ein Sprung kostet ja "unnötig" Zeit. Da hab ich gleich noch eine Frage: was machen dieses ominösen Sprünge, die überall auftauchen ("rcall .-3288 ; 0xfffff51e <__eeprom_end+0xff7ef51e>)? Panic Mode? Die Adresse 0xfffff51e taucht jedenfalls im Hexfile gar nicht auf, muß also irgendwas Festes sein.

Die sonstigen Optionen bin ich mal durchgegangen. Evtl. kommt durch "-ffunction-sections" und "-fdata-sections" zusätzlicher Overhead dazu, in der Manpage wird zumindest gewarnt:
avr-gcc manpage hat geschrieben:Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker will create larger object and executable files and will also be slower. You will not be able to use "gprof" on all systems if you specify this option and you may have problems with debugging if you specify both this option and -g.


Bei -fpack-structs ist unklar, ob ich das nutzen kann, da ich (war aber nicht explizit Teil der Frage und auch im Prinzip irrelevant, fiel mir halt nur auf :) ) C und Assembler mische (ISR wie üblich in asm). Wird zwar im selben Schritt und mit ggfs. denselben Optionen ()außer -Mx assembliert, aber hmmja. Ansonsten macht das trotz der Warnung Sinn, die mickrigen 512 Bytes RAM möchte man ja ganz gern nicht mit Alignment verplempern. :) -fshort-enums stört hingegen nicht, da der Assembler mit Enums eh nichts anfangen kann und ich sie deshalb nicht nutze, bzw. nur für C-Code nutzen würde.

Code: Alles auswählen
'-funsigned-char' '-funsigned-bitfields' '-D' 'DEBUG' '-O1' '-ffunction-sections' '-fdata-sections' '-fpack-struct' '-fshort-enums' '-g2' '-Wall' '-mmcu=atmega88' '-c' '-std=gnu99' '-v' '-MD' '-MP' '-MF' 'speedtest.d'


Bauteiltöter hat geschrieben:Irgendeinen vorteil der div()-Funktion muss es jedoch geben... <snip>
Auch gut zu sehen: -Os bringt hier einen erheblichen Geschwindigkeitsnachteil, das muss aber nicht immer so sein. Es gibt viele Situationen, wo -Os schneller und kleiner wird als -O1... -O3.
Komisch, ich sehe es auch so, daß da irgendein Vorteil liegen sollte... evtl. wollte irgendwer ja auch nur einen bequemeren Zugriff auf die Ergebnisse, aber... liegt vielleicht noch an den Optionen, auch, daß je nach Optimierungsstufe ggfs- was anderes rauskommt als erwartet.

Naja, ich danke Dir jedenfalls für Deine Einsichten und Tests! :) Welchen Simulator benutzt Du eigentlich?
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon Fritzler » So 25. Okt 2015, 09:49

div() rechnet es eben stur aus, als wäre es Variable/Variable.
Wenn der Compiler seine Variable/Konstante Magic anwenden darf wird das eben schneller.
Benutzeravatar
Fritzler
 
Beiträge: 5310
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Friedrichshagen/Am Wasserwerk

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » Mo 26. Okt 2015, 00:27

Da haben wir es wieder: irgendwem fällt der Denkfehler auf. :) Wir haben bisher übersehen, daß div() eine vermutlich handoptimierte Assemblergeschichte ist, die (natürlich) allgemein gehalten sein muß und, ebenfalls natürlich, nicht optimiert werden kann, da der Compiler ja kein asm optimieren kann und also einfach nur hinzugelinkt wird. Na dann, danke allerseits!
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon Bauteiltöter » Mo 26. Okt 2015, 10:12

Ah, OK, das macht Sinn. Ich schätze, das -flto werde ich erstmal nicht benutzen, denn auf diese Weise sehe ich, wenn ich groben Unfug gemacht habe. :)


Eigentlich sollte dir der GCC bei so grobem Unfug auch eine Warnung bringen. "Variable set but not used" oder vielleicht sogar "statement without effect". Hast du -Wall -Wextra gesetzt?

-ffunction-sections und -fdata-sections haben sowieso nur Auswirkungen wenn dein Projekt aus verschiedenen Quelldateien besteht.

-fpack-structs ist auf einem 8Bit System eh fast irrelevant, es gibt schließlich keine Alignment-Beschränkungen also wird der Compiler eh kein padding verwenden. Ausnahme sind ggf bitfields.

Ich benutze das Atmel Studio 6, die Optionen sind die Standardeinstellungen.

Wo die rjumps hin gehen kann ich dir gerade auch nicht verraten,muss ich zu Hause noch mal schauen.

Name vergessen hat geschrieben:Da haben wir es wieder: irgendwem fällt der Denkfehler auf. :) Wir haben bisher übersehen, daß div() eine vermutlich handoptimierte Assemblergeschichte ist, die (natürlich) allgemein gehalten sein muß und, ebenfalls natürlich, nicht optimiert werden kann, da der Compiler ja kein asm optimieren kann und also einfach nur hinzugelinkt wird. Na dann, danke allerseits!


Naja, eigentlich habe ich das nicht übersehen. Aber einige dieser Funktionen kann der Compiler schon optimieren, das Stichwort dazu lautet build-in functions. Für einige Funktionen wie z.B. strlen weiß der Compiler was die Funktion macht, daher setzt er z.B. für strlen("Hallo") eine 5 ins Binary. Das er auch div() kennt und bei einem konstanten Nenner seine magie einsetzt wäre also durchaus möglich, wurde aber nicht implementiert.
Mit -ffreerunning macht man dieses Verhalten übrigens kaputt.
Benutzeravatar
Bauteiltöter
 
Beiträge: 249
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » Di 27. Okt 2015, 17:16

Bauteiltöter hat geschrieben:Eigentlich sollte dir der GCC bei so grobem Unfug auch eine Warnung bringen. "Variable set but not used" oder vielleicht sogar "statement without effect". Hast du -Wall -Wextra gesetzt?
Normal schon, bei dem Test allerdings nicht. Hab's mal probiert und er hat auch brav gemeckert. Ihm ist dabei dann auch gleich auch aufgefallen, daß in der "Explizit"-Version die Einer gar nicht initialisiert werden. :) Man sieht, daß man auch bei Tests nicht an den Warnings sparen sollte. :oops:

Bauteiltöter hat geschrieben:-ffunction-sections und -fdata-sections haben sowieso nur Auswirkungen wenn dein Projekt aus verschiedenen Quelldateien besteht.
OK, tut meins allerdings. Einmal das main, dann das ASM, dazu was zum Tasten-Entprellen und demnächst kommt noch LUFA hinzu.

Bauteiltöter hat geschrieben:-fpack-structs ist auf einem 8Bit System eh fast irrelevant, es gibt schließlich keine Alignment-Beschränkungen also wird der Compiler eh kein padding verwenden. Ausnahme sind ggf bitfields.
Hab ich gehofft, aber war mir halt nicht sicher.[/quote]

Bauteiltöter hat geschrieben:Naja, eigentlich habe ich das nicht übersehen. Aber einige dieser Funktionen kann der Compiler schon optimieren, das Stichwort dazu lautet build-in functions. Für einige Funktionen wie z.B. strlen weiß der Compiler was die Funktion macht, daher setzt er z.B. für strlen("Hallo") eine 5 ins Binary. Das er auch div() kennt und bei einem konstanten Nenner seine magie einsetzt wäre also durchaus möglich, wurde aber nicht implementiert.

Hm, kommt vielleicht noch. Vielleicht ist diese div()-Funktion einfach nicht so bekannt und gebräuchlich, daß sich da jemand zu vollständigen Analysen hinreißen lassen hat.
Bauteiltöter hat geschrieben:Mit -ffreerunning macht man dieses Verhalten übrigens kaputt.
Die Option finde ich nicht, Du meinst bestimmt "-ffreestanding" (dessen tieferer Sinn sich mir allerdings nicht erschließt: gerade, wenn man keine stdlib hat, wären die Builtins doch sehr praktisch... und eventuelle "korrektere" Funktionen wie kmalloc() kann man ja trotzdem benutzen... Vorsichtsmaßnahme?).
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon Durango » Sa 7. Nov 2015, 00:02

Mein STK500 wird nicht mehr erkannt. [ http://www.atmel.com/webdoc/stk500/images/STK500.pdf ]

Am MAX202 messe ich falsche Spannungen. ( Seite 7 vom PDF ).
Hat jemand schon diesen Fehler bewusst erlebt ? Elkos oder 202 ist hier die Frage.

Nächste Frage: läuft AVR-Studio 7 unter XP ? Bevor ich 700 MB runterlade, wäre ich gern positiv stimuliert.

73 Manfred
Durango
 
Beiträge: 391
Registriert: Mi 14. Aug 2013, 00:42

Re: Der AVR-/ARDUINO-Faden

Beitragvon Profipruckel » Fr 13. Nov 2015, 22:20

Ich bin gerade heftig irritiert, was die analoge Referenzspanung angeht: Beim SMD-Uno ist der Pin 20 "ARef" vom Mega328P-AU auf die Stiftleiste herausgeführt, ich kann dort entweder Vcc oder die interne 1,07 Volt messen.

Jetzt habe ich einen Aufbau mit einem Nano, auch dort ist der Pin 20 herausgeführt und sogar mit 100nF nach Masse versehen. Es ist der gleiche Mega328P-AU drauf, aber ich messe am ARef keine Spannung - und das an vorerst zwei verschiedenen Nanos.

Die Meßwerte sind einigermaßen schlüssig, auch, wenn ich zwischen
analogReference(INTERNAL); // min 1.0 / typ 1.1 / max. 1.2 Volt
und
analogReference(DEFAULT); // Betriebsspannung
umschalte. Allerdings habe ich Streuungen der Meßwerte, die auf Rauschen hindeuten, ein Kondensator an 0 Volt macht ja auch wenig Sinn.
Profipruckel
 
Beiträge: 1363
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » Sa 14. Nov 2015, 03:20

Ist das P-AU nicht unabhängig vom Gehäuse? Die Pinouts der verschiedenen Gehäusevarianten unterscheiden sich u.A. darin, wo AREF liegt.
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon ando » So 6. Dez 2015, 21:24

Hi,

ich wünsch mir ja schon seit langem ne TvB Gone.
Erst wollte ich eine kaufen, aber dann kam ich auf den Trichter, das müsste ja auch mit dem Arduino realisierbar sein.

Joah, geht. http://fritzing.org/projects/tv-b-gone-with-arduino/
Da wird alles dazu geleifert.
Fix noch bei nem Kumpel ne IR Led organisisert: CQY 99

Also meinen Fernseher bekomme ich damit an und aus, wenn ich davor stehe.
Der im Dönerladen wollte nich.
Ich habe leider nciht so den durchblick , was das Programm angeht.
Sonst hätte ich gerne ein paar Änderungen:
Zb ne Betriebsanzeige, solange die IR Led sendet ( Ok, da kann man theoretisch ne normale paralell hängen)
Ländercode.. wäre schön, wenn die einstelleung auch signalisiert würde.
(seh ich das richtig, da der pull down von pin 0 die umschaltung triggert? Einmal pulldown --> eu nochmal pull down --> NA)

Und dann natürlich noch: Mehhhr Power!!!

Wie macht man das??
Mehr LED's parallel hängen?
Oder mehr Strom?? Die Led hängt direkt an 5 V , bzw an PWM...
Und da hört es bei mir auf...

Transistor dazwischen und die LED damit ansteuern und Variablen Vorwiderstand zum einstellen des Stromes? ( Die LED kann 100mA dauernd)

Fragen über fragen...

Oder hat jemand von euch vllt da schonmal was eigenes auf Arduino Basis entwicklet und stellt es mir zur Verfügung?

lg

Ando
ando
 
Beiträge: 812
Registriert: Sa 31. Aug 2013, 23:30

Re: Der AVR-/ARDUINO-Faden

Beitragvon xanakind » So 6. Dez 2015, 22:13

Also ein Arduino ist dafür völlig überdimensioniert
Ich habe mir die vor vielen Jahren mit einem nackten Atmel gebaut.
https://learn.adafruit.com/assets/6198
hat den vorteil, dass man den kleinen Tiny halt auch mal irgendwo einbauen kann.
z.B. in eine Kopflampe:
Clipboard01.jpg

zusammen mit der aktuellen Firmware und einer Hochleistungs IR-LED macht diese besonders Spass :)

Oder im Handy:
TVausHandy3.jpg

oder im Mp3 Player:
mp.jpg

:D
Edit:
die Aktuelle Firmware hat viele weitere nützliche Funktionen:
Betriebsanzeige LED beim senden Ein / abschaltbar
Loop Modus aktivierbar! das Ding sendet dann permanent :D
zwischen verschiedenen Regionen umschaltbar.

ich glaube die Firmware sollte auf der Seite zu finden sein, ansonsten sag bescheid und ich schicke sie dir
Benutzeravatar
xanakind
 
Beiträge: 3413
Registriert: So 11. Aug 2013, 21:55
Wohnort: in der nähe von Frankfurt/Main

Re: Der AVR-/ARDUINO-Faden

Beitragvon ando » Mo 7. Dez 2015, 19:05

Hi,

ja das sind gute Argumente dafür, das kleiner aufzubauen.

Ich gebs ungern zu, aber ich habs nich so mit rumlöten und was µC angeht, bin ich auch noch nicht so fit.
ICh war ja gestern shcon heilfroh, das ich das Prog auf dem Arduino zum laufen gebracht hab.

Jetzt noch Atmel ( der ja auch programmiert werden will, vmtl mit nem Programmer)

Ich weiß ich nöl jez hier etwas rum... aber ich würds zunächst gern mal mit dem Arduino machen, der leigt hier.

Die Frage is nun, wie kann icha us der PWM mehr Power rausholen?
ICh hab da ne Zeile im Programm gefunden

Code: Alles auswählen
/* This function is the 'workhorse' of transmitting IR codes.
 Given the on and off times, it turns on the PWM output on and off
 to generate one 'pair' from a long code. Each code has ~50 pairs! */
void xmitCodeElement(uint16_t ontime, uint16_t offtime, uint8_t PWM_code )
{
  TCNT2 = 0;
  if(PWM_code) {
    pinMode(IRLED, OUTPUT);
    // Fast PWM, setting top limit, divide by 8
    // Output to pin 3
    TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
    TCCR2B = _BV(WGM22) | _BV(CS21);
  }
  else {
    // However some codes dont use PWM in which case we just turn the IR
    // LED on for the period of time.
    digitalWrite(IRLED, HIGH);
  }


Meine LED kann 100mA ...

ANdo
ando
 
Beiträge: 812
Registriert: Sa 31. Aug 2013, 23:30

Re: Der AVR-/ARDUINO-Faden

Beitragvon Name vergessen » Mo 7. Dez 2015, 19:11

ando hat geschrieben:Die Frage is nun, wie kann icha us der PWM mehr Power rausholen?
Meine LED kann 100mA ...

Es mag ja oldschool sein, aber ich würde das mit einem Treibertransistor machen. Ein BC547 kommt mit 100mA locker klar, wenn's erheblich mehr sein soll ein BD135. Natürlich muß dann die LED einen passenden Widerstand bekommen. Da die Codes ggfs. auch "Dauer-1" senden, sollte der auch nicht für mehr als den Nennstrom der LED ausgelegt sein (manche würden das bestimmt trotzdem mit 300mA laufen lassen, weil das ja dennoch meistens aus ist...)). Der Vorwiderstand kann natürlich variabel sein, dann mußt Du aber trotzdem einen Festwiderstand davor setzen, damit das Poti nicht auf 0 Ohm steht und alles grillt.

LEDs parallel schalten funktioniert... in China. Vernünftig und zuverlässig macht man das mit eigenen Vorwiderständen je LED. Wenn Du 5V hast, und die IR-LED 1,6V Spannungsabfall haben, kannst Du 2 (theoretisch auch 3, aber dann hast Du nur noch 0,2V Reserve, was bei Batteriebetrieb "etwas knapp" ist) davon seriell nehmen, mit entsprechend kleinerem Vorwiderstand. Für 100mA wären das noch 18 Ohm. Da kannst Du 15 Ohm nehmen, wegen PWM und so, oder 22 Ohm, um sicherzugehen.

BTW, ob Arduino oder AVR ist völlig wurst. Ein Arduino ist im Prinzip ein besseres Breakout-Board für einen AVR (OK, mit USB-Konverter, falls der AVR kein USB intern hat). Der AVR im Arduino hat halt noch einen Bootloader, damit das Proggen ohne Programmer geht, das war's aber meistens auch schon. Du kannst in einen normalen AVR den kompilierten Arduino-Sketch flashen, oder in den Arduino ein in C oder ASM oder Bascom oder binär geschriebenes Programm. Letztlich sprechen beide denselben Maschinchenencode.
Benutzeravatar
Name vergessen
 
Beiträge: 2019
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitragvon BernhardS » Mo 7. Dez 2015, 19:43

Ich hab mir den Adventskalender "Internet of Things" vom großen C gegönnt. Gelegentlich hat mein Jüngster schon einen Elektronik-Adventskalender bekommen - ist eine schöne Geschichte für Einsteiger. So dachte ich, da könnte ich meine Mikrokontrollerkenntnisse mit täglichen kleinen Überraschungen mal wieder auf Stand bringen.

Hinter dem ersten Türchen ist ein Arduino Nano - muss ja den Bogen zum Thema Arduino hinbekommen. Man kann dann ein kleines Programm runterladen, das auf dem Arduino eine serielle Schnittstelle laufen lässt und den WLAN-Chip auf der Platine ansprechen.
Nach einigen Schwierigkeiten tatsächlich hinbekommen - das Ding erkennt das häusliche WLAN und gibt den Namen aus. Nur bin ich schon mehrere Tage im Rückstand. Weihnachten fällt adventskalendertechnisch vermutlich auf DreiKönig.
BernhardS
 
Beiträge: 442
Registriert: Fr 23. Okt 2015, 19:58

Re: Der AVR-/ARDUINO-Faden

Beitragvon Profipruckel » Mo 7. Dez 2015, 23:48

ando hat geschrieben:Die Frage is nun, wie kann icha us der PWM mehr Power rausholen?...
Wenn ich das richtig einschätze, ist Deine CQY99 30 Jahre alt - ein aktuellerer Typ mit besserem Wirkungsgrad wäre meine erste Idee.

Name vergessen hat geschrieben:Es mag ja oldschool sein, aber ich würde das mit einem Treibertransistor machen. Ein BC547 ...
Bei zwei in Reihe wird die Luft dünn, wenn wir etwas weniger old agieren, darf es auch ein N-Kanal-MOSFet werden, ein fast beliebiger Logic-Level Typ.

LEDs parallel schalten funktioniert... in China. Vernünftig und zuverlässig macht man das mit eigenen Vorwiderständen je LED.
Das klingt wirklich "old", lernt man das heutzutage noch? Ich weiß nicht, wievielen Kollegen ich schon versucht habe, die Stromverteilung zu erklären, warum man Widerstände braucht.

BTW, ob Arduino oder AVR ist völlig wurst.
Volle Zustimmung, zumal die Chinuinos kaum teurer sind als ein einzelnes IC plus drumherum-Teile. Was ich nicht verstehe, ist der Uno - riesengroß und mit einem dämlichen Rasterversatz. Ich setze den Nano ein, mit seinen 30 Beinchen, kaum größer als ein großes DIL-IC, passt er ins 2,54 mm Raster und kann alles, was der Uno auch kann.

Wenn jemand den Arduino-Bootlader nicht will, der Programmieranschluss ICSP ist ja auch drauf.

Natürlich muss man akzeptieren, siehe xanakind im Handy, dass u.U. die mechanische Größe für den Einsatz des puren AVR spricht.
Profipruckel
 
Beiträge: 1363
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitragvon Durango » Sa 12. Dez 2015, 01:21

AVR STK500 funzt wieder ! Nach dreimaligen Tauschen des MAX202 und den Kondensatoren auf dem Board wurde die gesamte Geschichte durch einen separaten MAX232 und einem DC/DC Wandler 5V auf +/- 12V ersetzt. Für den Operationsverstärker wird in der Originalschaltung die Versorgung des OP dem MAX202 entnommen.

Messtechnisch gab es vorher keine Auffälligkeiten, aber es ging nicht. Manchmal muß man zu groben Mitteln greifen, die Axt im Haus ersetzt den Zimmermann. :-)

73 Manfred
Durango
 
Beiträge: 391
Registriert: Mi 14. Aug 2013, 00:42

Re: Der AVR-/ARDUINO-Faden

Beitragvon Bastelbruder » Sa 12. Dez 2015, 08:54

Ich bin jetzt nicht so der Programmierer, aber der PWM-Schnipsel erzeugt die TRÄGERFREQUENZ welche mit dem eigentlichen Telegramm moduliert wird. Die unten erwähnte Direktmethode dürfte Manchester absondern. --- Da gibt es nichts zu verbessern ---

Die CQY99 ist zwar eine 34 Jahre alte schwäbische Konstruktion, aber die hat immerhin einen Strahlungswirkungsgrad von typisch 11%. Neuzeitliche LEDs sind zwischen 29% (SFH4231) und 49% (Osram Oslon). Die Angaben beziehen sich auf die Wellenlängen um 945nm.
Viel wirksamer als Leistung und Wirkungsgrad ist der Öffnungswinkel der (wild um sich schlagenden) Strahlungskeule, von der man seit dem Baseballschläger weiß daß kleinere Winkel höhere Reichweite erzielen. Bei LEDs wird dann mit besonders großen Zahlen und dem unscheinbaren Zusatz (sr) geworben.
Der in 30 Jahren erzielte Leistungszuwachs um Faktor 4 ist auf Grund der zweidimensionalen Ausbreitung der Strahlung gerade mal geeignet, die doppelte Entfernung zu überbrücken. IR-LEDs haben nicht so viel dazugewonnen wie man von den sichtbaren gewohnt ist, die bunten hat man in der gleichen Zeit drei Zehnerpotenzen hochgeprügelt (war auch notwendig).
Bastelbruder
 
Beiträge: 4535
Registriert: Mi 14. Aug 2013, 18:28
Wohnort: drunt' am Neckar - km142,7

VorherigeNächste

Zurück zu Allgemeine Diskussion

Wer ist online?

Mitglieder in diesem Forum: johannes und 1 Gast

span