www.mikrocontroller.net

Forum: Compiler & IDEs AVR TSIC Auswertung => riesen Programm


Autor: rogger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe gerade ein Programm zur Auswertung eines TSIC-Temperatursensors 
zur Steuerung von einigen Ausgängen geschrieben. Dazu benutze ich den 
C-Code von Beitrag "wie Daten an MSP430F1611 seriell einlesen?" . Allerdings 
erzeugt der avr-gcc compiler daraus eine ziemlich große Datei... Wenn 
ich alles andere weglasse und nur die Funktion zum Auslesen und die 
Umwandlung in einen String im Programm (Anhang) drin lasse ist die 
erzeugte binary immer noch 4406 bytes groß.

Kann mir einer sagen wie ich das Programm kleiner bekomme?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Temp_celsius = ((float)temperatur / 2047 * 200) - 50;

Diese Berechnung durch eine integer-Berechnung ersetzen.

Autor: rogger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh ok vielen Dank!

ich habs jetzt mal in
 Temp_celsius = ((temperatur*100 / 2047 * 200) - 5000)/10;

geändert... Sollte eigentlich rein Mathematisch funktionieren, odeer hab 
ich da was übersehen?
jetzt muss ich mich nur noch um das richtige setzen des Kommas 
kümmern...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rogger schrieb:
> ist die
> erzeugte binary immer noch 4406 bytes groß.

Dann hast Du den Compilerschalter "-lm" vergessen.


Peter

Autor: rogger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auch mit "-lm" komme ich auf 4406 bytes...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rogger schrieb:
> auch mit "-lm" komme ich auf 4406 bytes...

Komisch, ich komme auf 1438 Byte:

4.3.2
   text    data     bss     dec     hex filename
   1438       0       0    1438     59e test.out


Peter

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rogger schrieb:
> auch mit "-lm" komme ich auf 4406 bytes...

-lm ist ja auch eigentlich kein Compilerschalter, sondern ein 
Linkerschalter. ;-)
Also wahrscheinlich einfach in die falsche "Schalterliste" eingetragen.

Autor: rogger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin im AVR-Studio scheinbar noch nicht so fit... Hab jetzt "-lm" als 
Linkerschalter eingetragen und komm immernoch auf 4kb...
Ich werds morgen nochmal unter gewohnter Umgebung (linux + avr-gcc) 
probieren da kann ich wenigstens die Linkeroptionen selbst verändern^^

Ich glaube ich werde trotzdem die festkommarithmetische Lösung benutzen 
die ist ja trotzdem nur halb so groß. Damit komme ich nur auf 720 bytes.

rogger...

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Darf ich noch ketzerisch ein "Optimierung aktiviert?"  einwerfen?

Autor: rogger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn du die Compileroption -Os meinst, dann muss ich sagen die ist 
aktiviert...

Gibt es sonst noch Möglichkeiten eine Optimierung zu Aktivieren?

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wenn du die Compileroption -Os meinst, dann muss ich sagen die ist aktiviert...
Ja, die meinte ich.
Beim AVR-Studio (wieso hast du das nicht im ersten post erwähnt?) setzt 
man das "-lm", indem man in den project-options, linkeroptions (oder 
hieß das libraries? -- hab kein Avr-studio hier) die 'libm.a' auswählt.

hth, Jörg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rogger schrieb:

> ich habs jetzt mal in
 Temp_celsius = ((temperatur*100 / 2047 * 200)
> - 5000)/10;
>
> geändert... Sollte eigentlich rein Mathematisch funktionieren, odeer hab
> ich da was übersehen?

Warum stellst du nicht einfach so um
   Temp_celsius = (temperatur * 200 / 2047) - 50;

(Hintergedanke:
Du willst die Division so spät wie möglich machen. Bei der Division 
gehen dir die Nachkommastellen flöten, daher willst du es solange wie 
möglich hinauszuögern. Bei den anderen Operationen kann dir nichts 
verloren gehen, dafür droht allerdings die Gefahr eines Overflow. Das 
muss man mit den tatsächlichen Werten abklären, ob die Multiplikation 
mit 200 einen Overflow generieren kann.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist eine teure Operation
        temp_value1 |= 1 << (8-i);         // get the bit

Um mit einer variablen Bitanzahl zu schieben, muss ein AVR ganz schönen 
Aufwand treiben. Besser ist es eine 'Maske' zu haben und die Maske nach 
jeder Operation eine Stelle weiterzuschieben.

In deinem Fall ist es allerdings noch einfacher, einfach das Ergebnis um 
1 Stelle weiterzuschieben und immer nur das Bit 0 bei Bedarf zu setzen
  for (i = 0; i < 9; i++) {
    while (TSIC_SIGNAL_HIGH);              // wait for falling edge
    _delay_us(60);
    if (TSIC_SIGNAL_HIGH)
        temp_value1 |= 1;
    temp_value1 <<= 1;
    while (TSIC_SIGNAL_LOW);           // wait until line comes high again
  }

Und warum hast du den Code um Bits einzulesen doppelt im Code anstelle 
einer Funktion die 2 mal aufgerufen wird?

Selbiges nochmal in grün für das Checken der Parity.

Wobei du dem AVR viel Arbeit (und damit auch einiges an Code) abnehmen 
kannst, wenn du von vorneherein das Parity Bit extra betrachtest und nur 
8 Bit + Parity Bit empfängst. Dann brauchst du dafür keine 16 Bit 
Variablen und der AVR muss nicht nutzlose Bits durch die Gegend 
schieben.

Autor: rogger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätte ja nicht gedacht dass man noch so viel aus dem Programm 
rausholen kann!

Ich werde mich dann nacher wenn ich Zeit habe mal hinsetzen und das 
ganze Etwas umbauen...
Meine Lösung werde ich dann wieder hier Posten.

Vielen Dank soweit!

roggerb

Autor: rogger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
so ich bin endlich mal wieder dazu gekommen etwas weiter zumachen und 
habe einmal versucht eure Vorschläge einzubauen. Das Ergebnis findet ihr 
im Anhang.
Im Moment komme ich auf 752 Bytes.

Ich konnte meine Änderungen bisher noch nicht auf dem Atmega testen, 
deswegen weiß ich auch noch nicht ob mein Programm fehlerhaft ist.

rogger

Autor: Dude (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Programm hat noch ein paar Macken:

- Zuviele bits werden gelesen
- Daten werden einmal zuviel nach links geschoben
- parity prüft zu wenig bits
- zu großer datentyp als zählvariable
- itoa aus der bibliothek scheint kleiner
- temperatur zu klein (z.B. 930*200=186000)
- konstanten ggf. mit "L" kennzeichnen
- ein else kann eingespart werden

Ansonsten danke für den Code!

Autor: dagdag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Dude könntest Du Deine korrigierte Codevariante hier mal reinstellen?

Danke

dagdag

Autor: roger.k (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieser Beitrag ist zwar schon kalter Kaffee, aber ich kann es mir mein 
Unverständnis über solche Leute nicht verkneifen.

@ Dude schrieb:
...
> Ansonsten danke für den Code!

Das sind sie, das Forum nutzen und nur nehmen. Mir würde dieser Code 
bestimmt auch weiterhelfen. Ist zwar in C, aber ein Debuggerlauf zeigt 
mir ja auch Assembler.

mfg Roger

Autor: peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche mich gerade auch mit dem TSIC-206. Die ausgewerteten 
Temperaturen gebe ich momentan per UART aus. Jedoch kommen keine 
vernünftigen Werte zustande. Gibt es eine funktionierdende Version von 
testtemp.c?

Gruß

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl Heinz Buchegger schrieb:
> Temp_celsius = (temperatur * 200 / 2047) - 50;

eventuell noch in

Temp_celsius = (temperatur * 200 / 2048) - 50;

ändern, damit hat es der µC noch ein wenig einfacher.

Beitrag #2252499 wurde von einem Moderator gelöscht.
Autor: Anton Aus tirol (bingo_)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So ich poste jetzt hier eine Version, die die vorgeschlagenen Änderungen 
von Dude beinhaltet.
Das Beispiel ist ein Eclipse Projekt mit LCD.
Die gleichen Dateien aus dem Projekt sind nochmal extra angehängt.

Diese Version kommt ohne Interrupt oder Timer aus

PS: Ich sehe den Derben Umgangston hier im Forum immer mit einem Lächeln 
im Gesicht an, weil es erschreckend ist, wie kurz bei einigen hier die 
Soziale Kompetenz kommt.
Das Verhalten von "Dude" passt ganz dazu. Und jetzt macht mich und 
"mein" Code fertig, ich warte schon darauf...  ;) ;) ;)

Autor: Carsten (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ahoi!

Ich habe heute gerade an einer ZACwire-Implementierung per Interrupt 
gearbeitet. Danach bin ich auf diesen (alten) Thread gestoßen.

Vielleicht hilft mein Code ja jemanden, der's per INT bauen will.

Der TSic wird hier kontinuierlich ausgelesen, auf eine Steuerrung der 
Spannungsversorgung des TSic habe ich deshalb verzichtet. Das ist meiner 
Meinung nach auch nur beim Polling sinnvoll.
Lt. Datenblatt verheizt der TSIC 80µA bei 5V.

Als Eingang benutzt der Code Pin D4 mit der PCINT20-Funktion.
Zugegebenermaßen ist es ein schneller Hack aber es sollte nicht 
schwierig zu sein, den Code an eigene Bedürfnisse anzupassen.
So können natürlich auch andere Pin-Change-Interrupteingänge oder 
INT0/INT1 benutzt werden, wobei die Polarität fallend sein muss. Bei 
Benutztung von PCINT wird die steigende Flanke in der ISR rausgefiltert.

Als einzige Verbesserungen zum Code von Anton sind lediglich das Timeout 
bei der Flankenerkennung und die im Datenblatt empfohlene Messung der 
Breite des Startbits zu nennen. Ersteres bewirkt, dass das Programm 
nicht hängenbleibt, wenn der TSic ausfällt/abgezogen wird, Zweiteres 
sollte für ein genaueres Timing sorgen und das Auslesen robuster machen.

Durch die Strobemessung und das Timing beim Einlesen der einzelnen Bits 
ist die Laufzeit der ISR etwas größer als die Übertragungsdauer eines 
Datenwortes. Geschätzt sind es 2,7mS: (1 Startbit + 18 Datenbits inkl. 
Parity + 1/2 Stopbit) * 125µS. Der TSic sendet 10 Messungen/Sekunde, 
also verbraucht die ISR ca. 27,5mS/S.

Grundsätzlich ist das Interruptverfahren also nicht unbedingt 'besser'. 
Je nach Andwendungsfall kann es aber bequemer sein. Auf jeden Fall 
verbraucht es insgesamt mehr Rechenzeit und Strom als das Polling mit 
Spannungssteuerung des TSic. Wobei beim Polling zu beachten ist, dass 
der TSic nach dem Einschalten zwischen 65mS und 85mS braucht, um das 
Messergebnis zu liefern und empfohlen wird, V+ des TSic mit einem 
Tiefpassfilter an den µC zu koppeln -> mehr Bauteile.


/Carsten

Autor: Anton Aus tirol (bingo_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Version die ich gepostet habe hat noch ein Problem.
Es wird eine temperatur ca 2°C zu hoch angezeigt. Das Problem liegt 
irgendwo in der Parrity-Verarbeitung.
uint8_t readParity() {
  while (TSIC_SIGNAL_HIGH)
    ;             // wait for falling edge
  _delay_us(63);
  if (TSIC_SIGNAL_HIGH)
    return 1;
  return 0;
}

müsste heißen:
uint8_t readParity() {
  while (TSIC_SIGNAL_HIGH)
    ;             // wait for falling edge
  _delay_us(63);
  if (TSIC_SIGNAL_HIGH){
      while (TSIC_SIGNAL_LOW)
  ;           // wait until line comes high again
      return 1;
  }
   while (TSIC_SIGNAL_LOW)
      ;           // wait until line comes high again
  return 0;
}

Leider ist noch mehr faul, da dann nur noch gerade Zahlenwerte am LSB 
rauskommen.
Vielleicht liegt es auch irgendwie an der Pointer Verarbeitung, weil 
meiner Meinung nach macht das Programm genau das was die Version von 
Carsten macht.

@Carsten: mein Compiler meint das die parity_even_bit-Fkt. nichts macht.

Schade die Version von Rogger finde ich sehr elegant und schön 
geschrieben..
Aber nach mehreren Tagen des Versuchens gebe ich an dieser Stelle auf :(

Autor: Anton Aus tirol (bingo_)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So jetzt hier eine Version die wirklich geht, auch ohne Fehler soweit 
ich das jetzt beurteilen kann.

PS: es ist eine Mischung aus der Version von rogger und Carsten, jedoch 
komplett neu aufgebaut.

Autor: Holger W. (holgerw)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal meine Version, beide Bytes werden eingelesen und gleich die 
Parität geprüft. Das läuft so seit Monaten erfolgreich.
Geschrieben für PIC 18F2620 mit C18.
Vielleicht lässt sich aus dem Code noch die eine oder andere Anregung 
entnehmen.

Holger

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.