Suche eine kleine LCD library für den ATTiny26

OP #472611
Lesenswert?

Hallo,
stehe gerade vor dem Problem, dass mein hex File für den AtTiny26 obwohl 
im eigentlichen Programm nicht viel getan wird durch die LCD Ausgabe 
viel zu groß wird (9kB), gibt es da eine ganz abgespeckte Version für 
die Ausgabe am LCD (HD44780U komp. 2x16 LCD), die ich im Tiny verwenden 
könnte, oder wie macht ihr das?
OP #472825
Lesenswert?

Hi,
das ist schon klar, aber in meiner lcd.c muss ich die Sachen ja auch 
ausprogrammieren!

Habe jetzt einige Sachen auch meiner lcd.h und lcd.c gelöscht, die Größe 
des hex-Files ist jedoch nicht kleiner geworden.

Wie verhält es sich eigentlich mit dem einbinden von Headerfiles, wenn 
ich z.B. nur itoa() aus stdlib verwende, wird dann auch nur der Code 
itoa() ins hexfile aufgenommen, oder alle Funktionen von stdlib?
Gast #472896
Lesenswert?

Zeich doch mal deinen Code! Da lässt sich vielleicht an Stellen drehen, 
wo du es selber nicht siehst (ist einfach so, passiert mir und anderen 
genauso).




("Zeich" = Kielerisch/Norddeutsch für "zeig")
Gast #472905
Lesenswert?

Float-Berechnung kostet natürlich auch Speicher...
"dtostrf" erscheint mir sehr, sogar zu mächtig...

Und dann schluckt die LCD-Library vermutlich auch eine ganze Menge 
Speicher.

Sehe ich es richtig, dass du eine (Spannung) bzw. zwei (Strom) Stellen 
vor und 2 nach dem Komma darstellen willst?

Das mache ich so:

zehner = '0';
einer = '0';
zehntel = '0';
hundertstel = '0';
f = spg;
while (f>0.0) {f -= 1.0; einer++;)
while (f>0.1) {f -= 0.1; zehntel++;}
while (f>0.01) {f-= 0.01; hundertstel++;)

Die Zehner-Stelle genauso...
Durch '0' wird die float gleich in ASCII-Zeichen gewandelt.
Führende Nullen kann man auch noch herausfiltern...
OP #472920
Lesenswert?

Hi,
es wird in der ersten Zeile einfach ein Stromwert (zur Zeit auch noch 
der dazu gehörige ADC WErt) angezeigt und in der zweiten Zeile der 
Spannungswert.

Entstehen dann in den char Variablen zehner, einer,... die einzelnen 
Ziffern als Character?

Würde das für die Zehnerstelle so aussehen?
while (f>10.0) {f -= 10.0; zehner++;)

Solll ich statt double dann auch lieber float nehmen?
#472921
Lesenswert?

> Und dann schluckt die LCD-Library vermutlich auch eine ganze Menge
> Speicher.

Das ist aber nicht viel. Die Fleury Lib ist ziemlich einfach
gestrickt:
  Basisfunktionen zur Byte-Ausgabe
  Initialisierung
  Ausgabe eines Charcater
  Ausgabe eines String
Mit ein paar Zig Bytes ist man da dabei.

Das meiste wird wohl durch die floating point Arithmetik +
die Formatierfunktionen draufgehen.
#472928
Lesenswert?

> Solll ich statt double dann auch lieber float nehmen?

Das bringt mit gcc nichts.
float und double sind dort gleich gross und haben
daher auch dieselbe Implementierung.

Wenn du die floating point Library wegbekommen willst,
dann musst du komplett auf float bzw. double verzichten.

Ist aber kein Problem:
Deine Berechnung sieht so aus:

  spg = (adc_str * 5.0) / 1024.0;

Das kannst du auch mit Fixkommaarithmetik im long
Bereich machen:

  spg = ( adc_str * 500L ) / 1024;

(spg ist dann eine int Variable. Die long Rechnerei braucht
man nur deshalb, damit adc_str * 500 nicht den int Zahlen-
bereich überläuft).

Anstatt Zahlen im Bereich 0 bis 5 (als float) kommen da
jetzt Zahlen im Bereich 0 bis 500 heraus. Die Zehner- und
Einerstelle sind dabei deine ursprünglichen Nachkommastellen.
D.h. Wenn du jetzt bei der Ausgabe zwischen Hunderterstelle
und Zehnerstelle ein '.' einschmuggelst dann sieht die
Ausgabe aus wie vorher. Nur halt ohne Floating Point
berechnet.

  lcd_putint( spg / 100 );
  lcd_putc( '.' );
  lcd_putint( spg % 100 );

Was ähnliches kann man noch mit der anderen Berechnung machen
und schon fällt die Floting Point Library aus deinem Program
raus.
OP #472959
Lesenswert?

Hab das mit dem Strom jetzt mal so gelöst:
strom = ((spg - 250) ) / 0.025;
lcd_gotoxy(11, 0);
lcd_putint( strom / 100 );
lcd_putc( '.' );
lcd_putint( strom % 100 );

Bin jetzt immerhin von 9kB auf 6kB runter gekommen!


Ich benutze  in meiner lcd.c auch noch stdlib für itoa, kann(soll) ich 
das auch noch rausbekommen? Hier mal meine Ausgabe für int am lcd:

void lcd_putint(int value)
{
  char string[4];

  itoa(value, string, 10);
  lcd_puts(string);
}
#472962
Lesenswert?

> strom = ((spg - 2.5) *1000L) / 0.025;

Denk nach. Da sind immer noch Kommazahlen drinn!

Ich geh mal davon aus, dass du

  spg = ( adc_str * 5000L ) / 1024;

gemacht hast. spg hat also einen Wertebereich 0 bis 5000

Aus den 2.5 muessen dann klarerweise 2500 werden

   spg - 2500

sind dann Zahlen im Bereich -2500 bis +2500

Die durch 25 dividieren ( 0.025 * 1000) liefert
-100 bis +100.

Wenn ich mich jetzt nicht vertan habe (Chef war am
Telefon), dann sind das -0.1 Ampere bis +0.1 Ampere.
D.h. '.' wieder an der richtigen Stelle einschmuggeln.

#472964
Lesenswert?

> Bin jetzt immerhin von 9kB auf 6kB runter gekommen!

Wenn du floating point komplett weg hast, müsstest
du nochmal einen grossen Sprung sehen.

itoa()
Ich denke, wenn floating point weg ist, hast du keine
Notwendigkeit mehr darüber nachzudenken. Ausserdem:
itoa() ist nicht soooo teuer. Irgendeine Umwandlung
brauchst du sowieso und ob du die jetzt selbst schreibst
oder ob du itoa() benutzt sollte Jacke wie Hose sein.
OP #473328
Lesenswert?

Hallo,
habe die Änderungen noch übernommen und bin jetzt auf 5kB.

Habe mir jetzt auch einmal die Größe anzeigen lassen, nur in was wird da 
gemessen, Byte?

I:\AVR Programme\UILogger>avr-size *.o
text    data     bss     dec     hex filename
 458       0       0     458     1ca lcd.o
 566      17       3     586     24a uilogger.o
#473334
Lesenswert?

Ja, Byte

> habe die Änderungen noch übernommen und bin jetzt auf 5kB.
Wo liest du die 5K ab?
Doch hoffentlich nicht von der Größe der .hex Datei.


Wenn ich dein Pgm jetzt durch meinen Compiler jage,
dann lande ich bei
  Program:  1218 bytes (59.5% Full)
  Data:       25 bytes (19.5% Full)

Das reicht dann schon um gebrannt werden zu können.
Mit Floating Point waren die Daten übrigens:
  Program:  5916 bytes (288.9% Full)
  Data:       33 bytes (25.8% Full)

Kleine Umstellung, grosse Wirkung
#473345
Lesenswert?

Bernd Edlinger wrote:
> Ich glaube die Ausgaben ans LCD fressen so viel Platz, denn wenn ich
> alle Ausgaben wegmache komme ich auf 3kB runter, wenn ich rein Strom und
> Spannungswert ausgebe bin ich auf 4 kB

Nochmal:
Du darfst nicht nach der Größe des .hex Files gehen.

Dein Program ist zur Zeit 1218 Bytes gross und füllt
den Tiny zu rund 60% aus.
Persönliche Seite #476150
Lesenswert?

Noch zwei Sachen:
Du verwendest alle globalen Variablen als volatile -soweit OK.
1. Du beschreibst "adc_str" in einem Interrupt - das ist eine 16Bit 
Variable.
Wenn die Anzeige einigermaßen Zuverlässig sein sollte, musst du die 
Interrupts deaktiveren bevor du die an die LCD Libray übergibst. Sonst 
könnte es in seltenen Fällen dazu kommen dass die erste Hälfte es alten 
Wertes mit dr zweiten 8 Bit Hälfte des neuen Wertes auf dem Display 
angezeigt wird.
2. Wenn du volatile Variablen lokal mehrfach verwendet lohnt es sich 
eine lokale Kopie anzulegen um unnötige RAM Zugriffe zu vermeiden.

Also:
1
cli();
2
uint16_t adc_str_l = adc_str;
3
sei();
4
lcd_putint(adc_str_l);
Bei 8 Bit Variablen ist das natürlich nicht unbedingt nötig.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren