Der AVR-/ARDUINO-Faden

Der chaotische Hauptfaden

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

Benutzeravatar
Sunset
Beiträge: 1510
Registriert: Fr 6. Dez 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sunset »

ando hat geschrieben:Die "For" Schleife hab ich mir nich selbst ausgedacht. Die hab ich aus nem Beispielprogramm geklaut.
Ist doch ok. Ich habe ein bisschen das Gefühl, das Du zwar weißt, was die FOR Schleife macht, aber über die dahinterstehende Logik an dieser Stelle des Programms könnte ein Missverständnis entstanden sein.

Ich möchte noch einmal versuchen, das anders zu erklären:

Nachfolgend soll ein Zeitstrahl sein, dabei sollen die Sybole darstellen:
+ über dem Schwellwert
- unter dem Schwellwert
0 der Schwellwert
P die Messung
V der Vergleich ob der Schwellwert über oder unterschritten ist
. Füllzeichen, macht nix

Die FOR Schleife macht jetzt folgendes:
Zeit -> 000000+++++++0+++0-000----------00---00000++++++++
Loop 1: PPPPPV.........................................................
Loop 2: ........PPPPPPV.................................................
Loop 3: .................PPPPPV.......................................
Loop 4: ..........................PPPPPPV...............................
Loop 5: .....................................PPPPPV..................

Alternativ, wenn man mit einer Tabelle arbeitet, die den jeweils 1. Messwert vergisst und die neue Messung am Ende zufügt, dann wandert der Messbereich anstatt zu springen:

Zeit -> 000000+++++++0+++0-000----------00---00000++++++++
Loop 1: PPPPPV.........................................................
Loop 2: .PPPPPV........................................................
Loop 3: ..PPPPPV.......................................................
Loop 4: ...PPPPPV......................................................
Loop 5: ....PPPPPV.....................................................
Loop 6: .....PPPPPV....................................................
Usw.

Ich glaube, so wird der Unterschied besser deutlich, oder?
Beide Methoden sind valide, weder ist die erste falsch, noch die 2. richtiger, es kommt halt nur drauf an, was man erreichen bzw. machen und messen möchte.
ando hat geschrieben:
Ich nehm meinen Helligkeitswert- Wenn der über dem Schwellwert ist, addiere ich zu einer Variable x "1" dazu.
Dann mache ich einen Delay, von zb 5000ms und prüfe wieder.
Das ganze dann 6 mal hintereinander.
Wenn x = 6 , dann schaltet mein Ausgang. ( digital High)
Wenn nicht, (digital LoW)

Sollte gehn, oder?
Was macht das Programm denn, wenn ein Messwert kleiner oder gleich dem Schwellwert ist?
Die Variable x muss doch auch irgendwie wieder kleiner werden können, oder?

Das addieren von Variablen hat xexplox schon erklärt, subtrahieren geht genauso: x = x - 1 oder abgekürzt x--

Viel Spaß beim frickeln ;-)
ando
Beiträge: 2638
Registriert: Sa 31. Aug 2013, 23:30

Re: Der AVR-/ARDUINO-Faden

Beitrag von ando »

So,
die Hysterese habe ich hinbekommen.

Code: Alles auswählen

void loop()
{
  // Nimmt N Abfragen in einer Reihe, mit einem kurzen delay
  for (int i=0; i < abfrageZahl; i++)
  {
    abfrage[i] = analogRead(ldr);
    delay(400);
  }
  
  // Mittelt alle Abfragen
  durchschnitt = 0;
  for (int i=0; i < abfrageZahl; i++)
  {
    durchschnitt += abfrage[i];
  }
  helligkeit = durchschnitt/abfrageZahl;
  
  // Ausgabe an den Seriellen Monitor
  Serial.print("LDR ");
  Serial.println(helligkeit);
  
  // Schalte bei Dunkelheit die LED an
  if ((helligkeit < 300) && (digitalRead (led) == LOW))  // grüne LED oder Relais
  {
    digitalWrite(led, HIGH);
  }
  else {
    if ((helligkeit > 600) && (digitalRead(led) == HIGH))
    {
      digitalWrite(led,LOW);
    }
  }
}
Jetzt will ich natürlich den Helligekitswert mit nem Poti einstellen können.
So wie ich das sehe, brauche ich nun aber 2 Potis, für die obere und die untere Stellung.

Boah, ich hab langsam nen Knoten im Hirn. Leider sollte die ganze Sache bis morgen am laufen sein.

Edith: ICh stell meinen Dämmerungswert jetzt analog ein, indem ich nen Poti in Reihe zum LDR schalte. ( Da war ohnehin nen 1K Ohm R , der mit dem LDR nen Spnnungsteiler gebildet hat.
damit funktioniert es ersteinmal einigermassen.

Ando
Benutzeravatar
Sunset
Beiträge: 1510
Registriert: Fr 6. Dez 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sunset »

ando hat geschrieben:Jetzt will ich natürlich den Helligekitswert mit nem Poti einstellen können.
So wie ich das sehe, brauche ich nun aber 2 Potis, für die obere und die untere Stellung.
Das Poti liest Du genau so ein wie den Ldr, nur halt von einem anderen Pin.
Danach berechnest Du den oberen und unteren Grenzwert und anstelle der festen Werte vergleichst Du mit den berechneten Werten.

Code: Alles auswählen

const int poti = A2;
const hysterese = 50;

int grenze=0;
int oGrenze=0;
int uGrenze=0;

pinMode (poti, INPUT);

grenze = analogRead(poti);
oGrenze = grenze + hysterese;
uGrenze = grenze - hysterese;
So in etwa, dann die Werte 300 und 600 aus Deinem Programm durch oGrenze und uGrenze ersetzen.
Der Code oben ist natürlich für sich alleine so nicht lauffähig... :geek:
ando
Beiträge: 2638
Registriert: Sa 31. Aug 2013, 23:30

Re: Der AVR-/ARDUINO-Faden

Beitrag von ando »

Hi,

das ist ne super Idee, die ich auch direkt umgesetzt habe.

Code: Alles auswählen

// Konstanten
const int abfrageZahl = 2;      // Je mehr abfragen, desto stabiler isr das Ergebnis
const int ldr = A1;             // Pin für den Fotowiederstand
const int led = 12;
const int led2=11; 
const int hysterese = 50;

// Variablen
int helligkeit = 0;            // Variable für die Helligkeit  
int abfrage[abfrageZahl];      // Array Variable für das Mitteln der Temperatur
float durchschnitt = 0;        // Variable für das Mitteln der Temperatur
int grenze = 0;
int oGrenze = 0;
int uGrenze = 0;
int poti = A2;

void setup()
{  
  Serial.begin(9600);       // Baudrate für die Ausgabe am Serial Monitor
  pinMode(ldr, INPUT);      // Pin des NTC Wiederstands als Eingang
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode (poti, INPUT);   // Schwellwertpoti

}


void loop()
{
grenze = analogRead (poti);
}

oGrenze = grenze + hysterese;

uGrenze = grenze - hysterese;

{
  // Nimmt N Abfragen in einer Reihe, mit einem kurzen delay
  for (int i=0; i < abfrageZahl; i++)
  {
    abfrage[i] = analogRead(ldr);
    delay(400);
  }
  
  // Mittelt alle Abfragen
  durchschnitt = 0;
  for (int i=0; i < abfrageZahl; i++)
  {
    durchschnitt += abfrage[i];
  }
  helligkeit = durchschnitt/abfrageZahl;
  
  // Ausgabe an den Seriellen Monitor
  Serial.print("LDR ");
  Serial.println(helligkeit);
  
  // Schalte bei Dunkelheit die LED an
  if ((helligkeit < 40) && (digitalRead (led) == LOW))  // grüne LED oder Relais
  {
    digitalWrite(led, HIGH);  // einschalten
  }
  else {
    if ((helligkeit > 160) && (digitalRead(led) == HIGH))
    {
      digitalWrite(led,LOW);
    }
  }
}
Läuft aber nicht:

am_hys.cpp:36:1: error: †˜oGrenze†™ does not name a type
dam_hys.cpp:38:1: error: †˜uGrenze†™ does not name a type
dam_hys.cpp:40:1: error: expected unqualified-id before †˜{†™ token

ÄH- ich hab die Fehlermeldung gegoggelt- stack overflow?? bzw soll es an irgendwelchen dateien liegen? kanndochncisein, oder?


Ich hab ja zwischenzeitlich noch ne weitere Idee: Wenn ich die Hysterese so wie im Beispiel als Konstant angebe, könnt eich die ja auch mit nem zweiten Poti einstellen, und zb als Blinkende LED ausgeben lassen: Shcnell blinken: kleine Hysterese, langsam Blinken, große Hysterese.
Das wäre nahezuperfekt- nur leider scheiterts grade eher an der Programm Syntax *grumel*

Ando
Benutzeravatar
Sunset
Beiträge: 1510
Registriert: Fr 6. Dez 2013, 15:19

Re: Der AVR-/ARDUINO-Faden

Beitrag von Sunset »

Überprüfe bitte mal Deine Klammern }{.

Ich glaube unter grenze ist eine } zu viel und unter uGrenze eine { zu viel.
So besteht die Funktion loop() nur aus einer Zeile.

Selbstverständlich kannst Du den Wert von hysterese auch von einem Poti einlesen und damit einstellbar machen.
Benutzeravatar
Raider
Beiträge: 1121
Registriert: Fr 11. Jul 2014, 16:58
Wohnort: Ellerhoop

Re: Der AVR-/ARDUINO-Faden

Beitrag von Raider »

Genau, da sind zwei Klammern zu viel.

Code: Alles auswählen

// Konstanten
const int abfrageZahl = 2;      // Je mehr abfragen, desto stabiler isr das Ergebnis
const int ldr = A1;             // Pin für den Fotowiederstand
const int led = 12;
const int led2=11; 
const int hysterese = 50;

// Variablen
int helligkeit = 0;            // Variable für die Helligkeit  
int abfrage[abfrageZahl];      // Array Variable für das Mitteln der Temperatur
float durchschnitt = 0;        // Variable für das Mitteln der Temperatur
int grenze = 0;
int oGrenze = 0;
int uGrenze = 0;
int poti = A2;

void setup()
{  
  Serial.begin(9600);       // Baudrate für die Ausgabe am Serial Monitor
  pinMode(ldr, INPUT);      // Pin des NTC Wiederstands als Eingang
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode (poti, INPUT);   // Schwellwertpoti

}


void loop()
{
grenze = analogRead (poti);


oGrenze = grenze + hysterese;

uGrenze = grenze - hysterese;


  // Nimmt N Abfragen in einer Reihe, mit einem kurzen delay
  for (int i=0; i < abfrageZahl; i++)
  {
    abfrage[i] = analogRead(ldr);
    delay(400);
  }
  
  // Mittelt alle Abfragen
  durchschnitt = 0;
  for (int i=0; i < abfrageZahl; i++)
  {
    durchschnitt += abfrage[i];
  }
  helligkeit = durchschnitt/abfrageZahl;
  
  // Ausgabe an den Seriellen Monitor
  Serial.print("LDR ");
  Serial.println(helligkeit);
  
  // Schalte bei Dunkelheit die LED an
  if ((helligkeit < 40) && (digitalRead (led) == LOW))  // grüne LED oder Relais
  {
    digitalWrite(led, HIGH);  // einschalten
  }
  else {
    if ((helligkeit > 160) && (digitalRead(led) == HIGH))
    {
      digitalWrite(led,LOW);
    }
  }
}
So macht Arduino bei mir keine Fehlermeldung mehr....
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

Aus einem anderen Thread hierher kopiert, damit es dort nicht zu sehr OT wird:
zauberkopf hat geschrieben:Der nachteil : Zeitkritische Dinge.. also im ms bereich.. würde ich sein lassen.
Stimmt! An so Etwas klemptnere ich gerade herum (da kommt es auf 10µs an). Nachdem ich dem "Framework" durch Patchen eines Files den Timer0-Interrupt klauen konnte (trommle direkt auf den Registern herum), funktionierte es zwar so halbwegs, aber es tauchten sehr seltsame Effekte auf. Nun versuche ich es (durch Umstricken der Makefiles) mit "pure gcc", was soeben zur Folge hatte, daß das Nano-Board nun überhaupt nix mehr macht :(
Andere Idee : Arduino-Board und ASM oder GCC Compiler. Dazu ein Makefile von ozonisator und virtex.. und man hat die volle kontrolle über das teil.
Ok, den Weg sind auch schon Andere gegangen... Sind Erfahrungen (bzw. Makefiles) dazu hier verfügbar?
Benutzeravatar
zauberkopf
Beiträge: 9523
Registriert: So 11. Aug 2013, 15:33
Wohnort: gefährliches Halbwissen

Re: Der AVR-/ARDUINO-Faden

Beitrag von zauberkopf »

Also, das klappt eigentlich ganz gut..
Ich brauchte das auch mal, also ein paar signale in us Bereich.. das habe ich dann mit Assembler gelöst, ohne Timer.
Der effekt, das der Arduino nicht reagiert habe ich auch.
Aber dann im Betrieb. Beim einschalten oder reset, kann ich ihn für ein paar sek lang ansprechen.. dann beginnt mein Programm.
Es sei denn, Du hast die Serielle Leitung für Deine Zwecke angezapft..
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

zauberkopf hat geschrieben:Es sei denn, Du hast die Serielle Leitung für Deine Zwecke angezapft..
Jau, auf den USART-Registern trommele ich auch rum ;) Mit dem Arduino-Make läuft das Programm, mit "pure-gcc" nicht. Ich vermute mal, da fehlt noch ein ganz klein wenig von dem Gebimsel, was das Arduino-Make da noch einbindet. Momentan habe ich die Interrupt-Vektorliste im Verdacht...
Benutzeravatar
zauberkopf
Beiträge: 9523
Registriert: So 11. Aug 2013, 15:33
Wohnort: gefährliches Halbwissen

Re: Der AVR-/ARDUINO-Faden

Beitrag von zauberkopf »

Denk dran.. sobald Du die Arduino IDE verwendest, wird auch der komischer timer.. etc.. gestartet.
Und dann beginnt der ganze mist..

Ich halte es so : Zeitkritisch = gcc und Makefile = Normaler AVR halt mit Bootloader....
Nicht Zeitkritisch und andere Anfänger sollen auch damit rumspielen können : Arduino IDE.
Ich sehe das so : Mit dem 8051er AH Basic konnte ich schon damals nicht alles machen, was in Assembler ging.
Aber das Basic hat mir schon ein wenig damals die Lust am Controller gegeben.
Obwohl ich damals schon am C64 Assembler konnte.
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

zauberkopf hat geschrieben:Denk dran.. sobald Du die Arduino IDE verwendest, wird auch der komischer timer.. etc.. gestartet.
Die (Java) IDE benutze ich zwar nicht, aber das Zeugs, was "darunter" werkelt, also die Arduino-Klassen (das "Arduino.mk"). Und die versuche ich gerade loszuwerden, indem ich mir ein eigens entsprechendes Makefile erzeuge ;)
ozonisator
Beiträge: 1653
Registriert: So 11. Aug 2013, 19:53
Wohnort: bei Frankfurt/Main

Re: Der AVR-/ARDUINO-Faden

Beitrag von ozonisator »

Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

Danke für den Link! Das sieht (auf den ersten Blick) genau nach so etwas aus, was ich suche :D Ich probiere es mal aus.
Benutzeravatar
Fritzler
Beiträge: 12597
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

Besorgt euch WinAVR, da is nen makefile Editor bei und das Linkerscript auch.
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

Fritzler hat geschrieben:Besorgt euch WinAVR, da is nen makefile Editor bei und das Linkerscript auch.
Ich bin mir nicht so sicher, daß das einem Linux-Nutzer irgendeinen Vorteil bringen könnte ;)
Benutzeravatar
Fritzler
Beiträge: 12597
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

Denn nimmste det hier: (Programmierung in C)
https://wiki.ubuntuusers.de/AVR
Ist quasi das WinAVR für Linux, das makefile sieht auch 1zu1 gleich aus.
Musst ja nichtmal geany nutzen, das Makefile lässt sich ja kopieren.

Ansonsten eben avr-gcc selber nageln :mrgreen:
hab ich jetz erstmal alles für MIPS durch:
gcc nageln
Linkerscript mit .data von flash nach RAM kopieren etc.
Makefile dazu
kann ich ja mal Anleitungen heute Abend hochladen, gibt aber keinen Support, hab zu wenig Zeit :P
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

Fritzler hat geschrieben: gibt aber keinen Support, hab zu wenig Zeit :P
Das ist ja wohl klar -> Durch so etwas muss sich jeder selbst durchwurschteln ;) Aber ich habe den Fehler an meinem Makefile gerade gefunden: Es wurde keinerlei Interrupt ausgelöst, da das globale "interrupt enable" bei dem Arduino-Zeugs aktiv ist, bei meinem Kram aber nicht :oops: -> ein "sei()" wirkt Wunder...
Benutzeravatar
Fritzler
Beiträge: 12597
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

Trotzdem gibts etwas Hirninput, da man sich sowas sonst immer zusammensuchen muss:
Doku_GCC_nageln_ff.pdf
(11.22 KiB) 151-mal heruntergeladen
Doku_Startup_Linker_Make_ff.pdf
(54.42 KiB) 140-mal heruntergeladen
Das Linkerscript muss antürlich an die Adressen im AVR angepasst werdn und andere libc Funbktionen werden im Startup benötigt, da flash/RAM andere Speicherbusse haben.
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

Fritzler hat geschrieben:...an die Adressen im AVR angepasst werdn und andere libc Funbktionen...
Genau deshalb habe ich das "Arduino.mk" als "Ausgangsmaterial" genommen ;)
Benutzeravatar
Fritzler
Beiträge: 12597
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: Der AVR-/ARDUINO-Faden

Beitrag von Fritzler »

*würg* *röchel*
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

Fritzler hat geschrieben:*würg*
Und genau das möchte ich mit der Aktion entfernen ;)
Benutzeravatar
zauberkopf
Beiträge: 9523
Registriert: So 11. Aug 2013, 15:33
Wohnort: gefährliches Halbwissen

Re: Der AVR-/ARDUINO-Faden

Beitrag von zauberkopf »

Fritzler : *kicher*..

Aber ozonisator und virtex : Ich muss noch mal danke sagen für Euer Makefile !
Ich stand ja immer schon mit Makefiles irgendwie auf Kriegsfuß.. keine Ahnung warum.
Aber das Makefile hat mir echt den spass wiedergegeben !
Keine Fuses mehr... Und ich kann mit meiner geliebiten Kate (Editor) weiterarbeiten.
(ich habs gern puritanisch.. zwar nicht so puritanisch.. wie die vi leute.. aber .. )
Wie doch ein paar Bytes manchmal freude bereiten können..
Benutzeravatar
xoexlepox
Beiträge: 4815
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Der AVR-/ARDUINO-Faden

Beitrag von xoexlepox »

zauberkopf hat geschrieben:Ich stand ja immer schon mit Makefiles irgendwie auf Kriegsfuß.. keine Ahnung warum
Ich vermute mal, daß du dir nie die Mühe gemacht hast, in diese (zugegebenermaßen etwas kryptische) "Sprache" weiter einzusteigen. Iirc gibt es sogar ein eigenes "Handbuch" (aus der Serie mit den lustigen Viechern drauf) dafür ;)
zauberkopf hat geschrieben:Wie doch ein paar Bytes manchmal freude bereiten können..
Tja, auch ohne "bunt und hübsch anzusehen" lassen sich u.U. "kleine, unscheinbare, aber funktionale Meisterwerke" schaffen ;)
Benutzeravatar
felixh
Beiträge: 593
Registriert: So 11. Aug 2013, 13:46

Re: Der AVR-/ARDUINO-Faden

Beitrag von felixh »

Hi!

nutze AVR-GCC (Winavr-2010) und Code::Blocks.

Versuche gerade das eeprom von nem Mega128 zu lesen.
Soweit ich verstanden habe, wird ein eeprom_read_dword zu einem __eerd_dword_m128 "umdefined", um dann eine fehlermeldung 'undefined reference to "__eerd_dword_m128"' zu werfen.
wenn ich die build-optionen auf nen mega32 umstelle klappt alles...

ich nehme mal an, dass da irgendwo ne library falsch eingebunden ist?

Jemand nen Tipp?

Im ganzen web scheint sonst keiner diese problem zu haben, mit google bin ich jedenfalls nicht schlauer geworden

//edit: ich hab versucht, an das makefile zu kommen, aber das wird von Codeblocks wohl on the fly erzeugt.
Linker-optionen sind jedenfalls:

Code: Alles auswählen

-mmcu=atmega128
-Wl,-Map=$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).map,--cref
sorry, ich kann einigermassen akzeptabel Programmieren, aber sobald ich das Wort "makefile" usw höre, setzt es bei mir aus ;-)
(ich hab also nicht die leiseste ahnung, was die Zeile da oben macht. ich kann gerade noch mittels -l weitere librarys linken)

//edit: OK, das linken von /avr/lib/avr51/libc.a hat geholfen! Kompiliert jetzt. Obs geht zeigt die Zukunft.
xanakind
Beiträge: 12594
Registriert: So 11. Aug 2013, 21:55

Re: Der AVR-/ARDUINO-Faden

Beitrag von xanakind »

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!

Modus Weiss und sogar RGB (mit Potiauswertung) funktioniert!
Ich fasse es nicht! :D

Dann kann der ganze Kram endlich mal in ein Gehäuse und dann geht´s an die Lepton.... :?
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: 9415
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: 4815
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: 12597
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: 2638
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: 12594
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: 2638
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: 1771
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: 11540
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).
Antworten