Der AVR-/ARDUINO-Faden

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

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
Bauteiltöter
Beiträge: 254
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitrag von Bauteiltöter »

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
ferdimh
Beiträge: 9381
Registriert: Fr 16. Aug 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von ferdimh »

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
Bauteiltöter
Beiträge: 254
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitrag von Bauteiltöter »

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...
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

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
xoexlepox
Beiträge: 4814
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

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
Bauteiltöter
Beiträge: 254
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitrag von Bauteiltöter »

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.
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

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
Bauteiltöter
Beiträge: 254
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitrag von Bauteiltöter »

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...
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

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
Fritzler
Beiträge: 12579
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

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.
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

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
Bauteiltöter
Beiträge: 254
Registriert: So 11. Aug 2013, 17:37

Re: Der AVR-/ARDUINO-Faden

Beitrag von Bauteiltöter »

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.
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

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
Durango
Beiträge: 635
Registriert: Mi 14. Aug 2013, 00:42

Re: Der AVR-/ARDUINO-Faden

Beitrag von Durango »

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
Profipruckel
Beiträge: 1506
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitrag von Profipruckel »

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.
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

Ist das P-AU nicht unabhängig vom Gehäuse? Die Pinouts der verschiedenen Gehäusevarianten unterscheiden sich u.A. darin, wo AREF liegt.
ando
Beiträge: 2623
Registriert: Sa 31. Aug 2013, 23:30

Re: Der AVR-/ARDUINO-Faden

Beitrag von ando »

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
xanakind
Beiträge: 12538
Registriert: So 11. Aug 2013, 21:55

Re: Der AVR-/ARDUINO-Faden

Beitrag von xanakind »

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
ando
Beiträge: 2623
Registriert: Sa 31. Aug 2013, 23:30

Re: Der AVR-/ARDUINO-Faden

Beitrag von ando »

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
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

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
BernhardS
Beiträge: 1751
Registriert: Fr 23. Okt 2015, 19:58

Re: Der AVR-/ARDUINO-Faden

Beitrag von BernhardS »

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.
Profipruckel
Beiträge: 1506
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitrag von Profipruckel »

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.
Benutzeravatar
Durango
Beiträge: 635
Registriert: Mi 14. Aug 2013, 00:42

Re: Der AVR-/ARDUINO-Faden

Beitrag von Durango »

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
Benutzeravatar
Bastelbruder
Beiträge: 11482
Registriert: Mi 14. Aug 2013, 18:28

Re: Der AVR-/ARDUINO-Faden

Beitrag von Bastelbruder »

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).
Lars_Original
Beiträge: 506
Registriert: Mo 12. Aug 2013, 08:21
Wohnort: Burghaun (im Zentrum des Wahnsinns)

Re: Der AVR-/ARDUINO-Faden

Beitrag von Lars_Original »

Wenn da noch ein Transistor eingebaut wird, kann man den auch als Stromquelle für die LED benutzen.
Den Widerstand (oder einen Teil davon) könnte man nun mit einem kleinen Kondensator brücken um den Strom im Pulsbetrieb zu erhöhen, bei Dauerstrich aber im zulässigen Rahmen zu halten.


Lars
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

Kann mir kurz jemand sagen, ob der PT6311 tatsächlich SPI spricht (Seite 14ff), wie es im Netz bei vergleichbaren Chips angedeutet, aber nicht explizit gesagt wird? Habe zugegebenermaßen von dem SPI keine Ahnung, daher weiß ich nicht, ob das mit den >1µs twait vor der Antwort normal ist und die Hardware-SPI vom AVR das auch so macht.
Benutzeravatar
Fritzler
Beiträge: 12579
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

Das is sowas von SPI ;)
Musst eben nurnoch den SPI Modus rausfinden.

twait ist kein problem, der AVR SPI ist Byte orientiert.
Also Data Read Befehl senden, warten und dann NUllbytes senden mit der SPI Takte erzeugt und dann Byteweise einlesen.
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

Fritzler hat geschrieben:Das is sowas von SPI ;)
Sehr schön, das hatte ich gehofft, danke für die klare Aussage!
Fritzler hat geschrieben:Musst eben nurnoch den SPI Modus rausfinden.
Öhm, Mode? Da gibt's Modes? Oder ist damit Master vs. Slave gemeint?
Fritzler hat geschrieben:twait ist kein problem, der AVR SPI ist Byte orientiert.
Also Data Read Befehl senden, warten und dann NUllbytes senden mit der SPI Takte erzeugt und dann Byteweise einlesen.
OK, das muß ich mir dann also noch ansehen. Macht ja irgendwie auch Sinn, daß das SPI-Modul nicht wissen kann, ob das Byte nun ein Read-Befehl ist oder sonstwas. :)
Ich muß also wirklich Nullen senden, bevor ich lesen kann, trotz HW-SPI? Gut zu wissen, das hätte mich bestimmt schön gebissen.
Benutzeravatar
Fritzler
Beiträge: 12579
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

Zu den SPI Modes guckst du ins AVR Datenblatt, das ist da sehr gut beschrieben.
Damit der Slave was sendet brauchter nen Takt, der Takt kommt immer vom SPI Master.
Wie bekommt man den SPI Master dazu nen Takt rauszuwerfen?
Jo, er sendet irgendein Müll, der Slave "weis" ja, dass er jetzt senden soll weil vorher ein read Befehl kam.
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

OK, dann ist das geklärt, danke! Daß die Clock nicht einfach durchläuft, hat vermutlich den Grund, daß man dadurch dann die Start Condition anzeigt, anstatt irgendwelche sonstige Synchronisation machen zu müssen?
Benutzeravatar
Münsterländer
Beiträge: 329
Registriert: Fr 11. Okt 2013, 14:55
Wohnort: Borken (bei Holland)

Re: Der AVR-/ARDUINO-Faden

Beitrag von Münsterländer »

So, der Anfang ist gemacht, siehe http://www.fingers-welt.de/phpBB/viewto ... 49#p121249 Erfreunis der Woche.
Mein TV-B-Gone läuft. Schaltung funzt so:
tvbgone.JPG
Software kommt (wie auch die Schaltung) von hier:
http://www.righto.com/2010/11/improved- ... -gone.html

Ich freu mich gerade ziemlich, aber immer son Arduino mit gesteckten Pins ist irgendwie nervig, fehleranfällig und auffällig.
Meine Frage:
Kann ich das Programm auch leicht auf andere Attinys bringen? Es gibt viele TV-B-Gone Nutzer, die den Attiny 85 dafür benutzen. Der ist klein und billig. Wenn ich den auf Lochraster bringe und die Software weiter verwenden kann, würde ich das vielleicht noch schaffen. Ich bin halt Einsteiger und eher Grobmotoriker.
Glück Auf,
Thomas
Edith will wissen, ob der Taster ohne widerstand so in Ordnung geht. (Die Notwendigkeit der Widerstände ist mir noch unklar.)
Benutzeravatar
Nicki
Beiträge: 3127
Registriert: So 11. Aug 2013, 20:16
Wohnort: wo Mosel und Rhein sich treffen

Re: Der AVR-/ARDUINO-Faden

Beitrag von Nicki »

Münsterländer hat geschrieben: Edith will wissen, ob der Taster ohne widerstand so in Ordnung geht.
Falls das Programm mit einem internen Pullupwiderstand arbeitet passt das.
Die Baustelle "LED" erscheint mir wesentlich wichtiger
(Die Notwendigkeit der Widerstände ist mir noch unklar.)
Guck dir mal das I/U-Diagramm einer Diode an, dann sollte dir ein Licht aufgehen ;)
Benutzeravatar
xoexlepox
Beiträge: 4814
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

Münsterländer hat geschrieben:Wenn ich den auf Lochraster bringe und die Software weiter verwenden kann, würde ich das vielleicht noch schaffen.
Das "Problem" wird wohl eher sein, das Programm in den Chip zu bekommen -> Die "Annehmlichkeiten" des Entwickungsboards mit USB (und vmtl. RS232-Chip) hat ein "nackter" Chip nicht mehr, und du benötigst ggf. einen Programmer. Mglw. kannst du dazu auch das Entwicklungsboard verwenden ;)
der Taster ohne widerstand so in Ordnung geht.
Ich vermute, daß der Taster an einem Eingang mit "internen Pullup" (ist ähnlich einem Widerstand) betrieben wird. Da sehe ich den Anschluß der LED ohne Vorwiderstand eher als "kritisch" an...
Die Notwendigkeit der Widerstände ist mir noch unklar.
Die dienen dazu, den Strom zu begrenzen -> Beliebig viel Strom "kann" solch ein Chip auch nicht ab...

Ok, Nicki war schneller...
Anse
Beiträge: 2278
Registriert: Mo 12. Aug 2013, 21:30
Wohnort: Bühl (Baden)

Re: Der AVR-/ARDUINO-Faden

Beitrag von Anse »

Wie das Mit Widerständen, LEDs und Arduino so ist erklärt der Herr hier ganz gut:https://youtu.be/bdWINZIgdms?t=797. :twisted:
Natürlich so nicht machen. :roll:
Benutzeravatar
Münsterländer
Beiträge: 329
Registriert: Fr 11. Okt 2013, 14:55
Wohnort: Borken (bei Holland)

Re: Der AVR-/ARDUINO-Faden

Beitrag von Münsterländer »

Danke für die schnellen Antworten!
@Nicki
Nicki hat geschrieben: Die Baustelle "LED" erscheint mir wesentlich wichtiger
Widerstand an der LED habe ich erstmal weg gelassen, weil ich auf mehr Reichweite hoffe. Brennt die LED durch, nehme ich eine neue, dann aber mit Widerstand. Oder meintest du, dass keine IR LED im Plan steht. Die habe ich im Teileverzeichnisvon Fritzing.org auf die Schnelle nicht gefunden.
Benutzeravatar
Nicki
Beiträge: 3127
Registriert: So 11. Aug 2013, 20:16
Wohnort: wo Mosel und Rhein sich treffen

Re: Der AVR-/ARDUINO-Faden

Beitrag von Nicki »

Münsterländer hat geschrieben: Brennt die LED durch, nehme ich eine neue, dann aber mit Widerstand.
Ich mache mir jetzt eher Sorgen um den AVR, so eine IRED kann relativ hohe Ströme ab.
Aus Faulheit mache ich sowas lieber direkt ordentlich, ist mir sonst viel zu wahrscheinlich dass ich da noch mal beigehen muss.
Benutzeravatar
Münsterländer
Beiträge: 329
Registriert: Fr 11. Okt 2013, 14:55
Wohnort: Borken (bei Holland)

Re: Der AVR-/ARDUINO-Faden

Beitrag von Münsterländer »

Oh, ich habe mit 10 Cent Verlust für die LED gerechnet. Bevor ich nen neuen Uno brauche löte ich lieber nen Widerstand dran.
Danke für die Info.
Name vergessen
Beiträge: 3261
Registriert: Mo 12. Aug 2013, 19:47

Re: Der AVR-/ARDUINO-Faden

Beitrag von Name vergessen »

Den Programmer kannst Du Dir sparen, indem Du den fertig programmierten Chip aus dem Arduino nimmst und auf das Board setzt. Mußt nur darauf achten, daß Du dieselben Pins kontaktierst (und auf den internen RC-Oszillator fusest). Wenn Du ihn sockelst, kannst Du den zum Neuprogrammieren zur Not wieder in den Arduino stecken. Allerdings müßtest Du dann, wenn Du den Arduino weiterbenutzen willst, einen neuen Chip einsetzen, der einen Arduino-Bootloader gebrannt hat, was ohne einen Programmer (mit dem Du auch ohne Arduino den Tiny beschreiben könntest) nicht geht.
Benutzeravatar
Heaterman
Beiträge: 3990
Registriert: Fr 28. Jun 2013, 10:11
Wohnort: Am Rand der Scheibe, 6 m unter NN

Re: Der AVR-/ARDUINO-Faden

Beitrag von Heaterman »

Um das weiter zu spinnen: wenn man gar keinen Programmer einsetzen will, kann man auch fertig mit Bootloader programmierte Chips kaufen:

http://www.amazon.de/s/?ie=UTF8&keyword ... gm29nnwo_b

So einen Chip in den UNO stecken, per USB mit dem Programm bespielen, dann raus und in der Minimal-Standardbeschaltung auf die eigene Applikation. Neuen Chip in den UNO usw.
Ist eine bequeme und stressfreie Einsteigerlösung.

Für etwas mehr Gehirnschmalz-Einsatz gibts tausend Lösungen im Netz unter "Bootloader Arduino". Ich nehm dazu einen USBasp und die myAVR-Prog-Software. Einfacher gehts kaum für Einsteiger.


Unterm Strich sind dann aber heute zehn Arduino Nanos vom Ali billiger... Muss man nur Zeit haben.
Benutzeravatar
Münsterländer
Beiträge: 329
Registriert: Fr 11. Okt 2013, 14:55
Wohnort: Borken (bei Holland)

Re: Der AVR-/ARDUINO-Faden

Beitrag von Münsterländer »

Das sind die Infos die ich brauchte. Da ich leider die Billigvariante vom Uno habe kann ich den Controler nicht rausnehmen. Aber wenn das ansonsten geht muss ein Originalteil her. Ne Programmierschnittstelle sollte aus meinem Einführungskurs sogar noch da sein. Das war aber eher hakelig . Über den Arduino läuft es einfach sehr benutzerfreundlich ab.
Wobei das Argument mit den Chinateilen die im Nano verbaut billiger sind als einzelne µc schon zieht. Die Geduld fehlt allerdings. Ich habe einiges in China bestellt, das wird aber erst Mitte Februar kommen (hoffe ich). Das ist in Zeiten von Amazon Prime etc. schon ne Nummer.
margau
Beiträge: 78
Registriert: Sa 7. Nov 2015, 23:15
Wohnort: Rhein-Main

Re: Der AVR-/ARDUINO-Faden

Beitrag von margau »

Hallo zusammen!
Man kann auch den Arduino als ISP-Adapter für spätere Breadboard und Lochraster-Varianten nehmen. Funktionierte bei mir so naja.

Mein Plan sieht jetzt so aus, das ich überall einen 6-pol wannenstecker drauflöte, und das ganze mit nem <10€ USBasp und der Arduino-IDE programmiere ("Uploaden mit Programme").

Dann hat man halt auf dem Breadboard keine Serielle Schnittstelle zum debuggen, aber selbst da könnte man eine Buchsenleiste für ein FT232-Breakout vorsehen.

Viele Grüße!
margau
Sir_Death
Beiträge: 3446
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sir_Death »

In Zeiten in denen 5 China-Nano-Clones inkl. Versand um 12,99 zu haben sind, bestelle ich die nur noch im 10er-Pack (und wenn nur noch 2-3 Stück da sind, wird nachbestellt)
http://www.ebay.at/itm/121507227435?_tr ... EBIDX%3AIT

Da ist die serielle (über USB) dabei, ein Spannungswandler (Eingang 7-12V --> Ausgang 5V) und nachdem die Steckleisten nicht eingelötet sind, kann man auch Drähte direkt anlöten...

Für alle größeren Projekte (Nano-Pins zu wenig) gibt's den MEGA...

P.S.: Da fällt mir ein, ich muss mal wieder ordern :lol: :lol: :lol:
Benutzeravatar
Trax
Beiträge: 1677
Registriert: Mi 30. Okt 2013, 23:21

Re: Der AVR-/ARDUINO-Faden

Beitrag von Trax »

Sir_Death hat geschrieben: Für alle größeren Projekte (Nano-Pins zu wenig) gibt's den MEGA...:
gibts die noch biliger als das: http://www.ebay.at/itm/NEW-ATmega2560-1 ... SwPe1T6WAd
Sir_Death
Beiträge: 3446
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sir_Death »

wow - ich hatte bisher als kleinsten Preis 8,49 - geht ja noch besser... :-)

Wenn es schnell gehen muss, nehme ich beim Mega meist den hier: http://www.ebay.at/itm/Neu-SunFounder-L ... xylpNTSOvL
Profipruckel
Beiträge: 1506
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitrag von Profipruckel »

Sir_Death hat geschrieben:wow - ich hatte bisher als kleinsten Preis 8,49 - geht ja noch besser...
Na, wenn schon "Artikelstandort China", dann doch gleich direkt:

http://www.aliexpress.com/item/Mega-256 ... 18bc0c7bad

Aktuell $5,90 ... ab 5,98 USD jede Menge Angebote.
Sir_Death
Beiträge: 3446
Registriert: Mo 11. Mai 2015, 22:36
Wohnort: südlich von Wien

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sir_Death »

Trax hat geschrieben:gibts die noch biliger als das: http://www.ebay.at/itm/NEW-ATmega2560-1 ... SwPe1T6WAd
VORSICHT!!!
Aus dem Angebot:
USB Driver Chip: CH340G replace the Atmega 8U2/16U2
caution: No availabe for WIN8: aution: No availabe for WIN8

da frag ich mich was der bei WIN10 macht? - da bleib ich lieber bei http://www.ebay.de/itm/261724251567?_tr ... EBIDX%3AIT

Der hat den Originalen 16U2
margau
Beiträge: 78
Registriert: Sa 7. Nov 2015, 23:15
Wohnort: Rhein-Main

Re: Der AVR-/ARDUINO-Faden

Beitrag von margau »

Also der CH340 der auf den meisten Nanos drauf ist funktioniert unter Windows 10. Einzige Komplikation war glaube ich was von wegen unsignierte Treiber oder so.

Viele Grüße!
margau
Profipruckel
Beiträge: 1506
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: Der AVR-/ARDUINO-Faden

Beitrag von Profipruckel »

Sir_Death hat geschrieben:VORSICHT!!!
USB Driver Chip: CH340G replace the Atmega 8U2/16U2
caution: No availabe for WIN8: aution: No availabe for WIN8
Damit das bloß nicht zu einfach wird, heisst der Treiber CH341.

Herr Kainka sagt auf seiner Internetseite Windows (ab Windows 98 bis Windows 10, 32-Bit/64-Bit)
Myvesdin
Beiträge: 45
Registriert: Sa 5. Apr 2014, 10:20

Re: Der AVR-/ARDUINO-Faden

Beitrag von Myvesdin »

Moin Moin,

hab derzeit nen massiven Gehirnknoten.

Ich will mit einem Arduino SMS empfangen und auf einem LCD Display den Inhalt ausgeben.
Ich hab jetzt aber schon mit dem korrekten auswerten der Seriellen Daten vom GSM-Modul (TC35) Probleme.
Kann mir da vlt. jemand helfen?

Code sieht bis jetzt so aus:

Code: Alles auswählen

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
int val = 0;
long abruf = 0;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  mySerial.begin(9600);
  pinMode(13, OUTPUT);
  pinMode(4, INPUT);
  digitalWrite(4, LOW);
  pinMode(4, OUTPUT);
  delay(100);
  pinMode(4, INPUT); 
  Serial.println("Goodnight moon!");
  delay(5000);
  //mySerial.println("AT");
  delay(1500);
  mySerial.println("AT+CPIN=7021");
  delay(1500);
  //mySerial.println("AT+CMGF=1");
  Serial.println("Ready");
  delay(200);
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write(mySerial.read());   
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
    
  }
   abruf = abruf + 1;
    if (abruf > 1000000){
    readsms(); 
    abruf=0;   
  }
   
 
  }

void readsms(){
  mySerial.println("AT+CMGF=1");
  delay(200);
  mySerial.println("AT+CMGR=1");
  delay(200);
  mySerial.println("AT+CMGD=1");
  delay(200);  
  }
Der Teil, den ich brauch wird von zwei "!" oder ":" vorne und hinten gekennzeichnet (jenachdem was besser passt).
Ich hoffe jemand kann helfen :?


Grüße
Antworten