Ich habe ein Programm, in dem ich mit vsnprintf() gerne Fließkommazahlen ausgeben möchte. Bei den kleinen AVRs deaktiviert die Arduino IDE aber leider die Unterstützung dafür. Ich habe bisher nur Möglichkeiten gefunden, den Code umzuwursteln und eine Arduino Spezialfunktion zur Wandlung eines Fließkommawertes in eine Zeichenkette zu nutzen oder um die Unterstützung für Fließkommazahlen in printf() u.ä. auf meinem Rechner und meinem Login für alle AVR Cores zu aktivieren. Ersteres ist etwas aufwändig. Zweiteres ist schlecht, weil auch ein Kollege mal das Programm übersetzen können soll, aber ich mich nicht um dessen Projekte kümmern mag, die plötzlich und unverhofft nicht mehr in den Speicher passen. Gibt's da auch noch eine Möglichkeit ?
Flunder schrieb: > Bei den kleinen AVRs deaktiviert die Arduino IDE aber > leider die Unterstützung dafür. Ich kenne mich mit den AVRs zwar nicht aus aber es wird wohl einen Grund haben, dass das so ist. Der Grund könnte Speichermangel sein weil sprintf ein riesen Batzen Code ist.
Hallo, man kann bei Arduino eine platform.local.txt anlegen und Compiler Flags wie bspw. "-Wl,-u,vfprintf -lprintf_flt -lm" setzen. Die Ressourcenbelegung muss man sich dann anschauen.
:
Bearbeitet durch User
Obelix X. schrieb: > Der Grund könnte Speichermangel sein weil > sprintf ein riesen Batzen Code ist. So gigantisch ist es nun auch wieder nicht, mit anderen Compilern kann man das auch auf kleinen AVRs verwenden. Für manch einen liegt zwar viel Ehre darin, jede C-Libraryfunktion selbst neu zu schreiben (im festen Glauben, das viel besser zu können als diejenigen, die die Libraries für die Compiler zur Verfügung stellen), anderen aber liegt es mehr daran, ein Programm von überschaubarer Quelltextgröße zu erhalten, das einfach das tut, was es macht. Auch wenn sprintf 2 kiB Code umfasst - bekommt man Geld zurück, wenn man das Flash des Controllers ungenutzt lässt? Wir sind ja nicht alle professionelle Produktdesigner, die Programme für zigmillionenfach gefertigte Geräte schreiben, bei denen es sich lohnen könnte, drei Cent am Controller einzusparen ...
Harald K. schrieb: > mit anderen Compilern kann > man das auch auf kleinen AVRs verwenden. Geht auch mit dem von Arduino mitgeliefertem Compiler Siehe: Veit D. schrieb: > man kann bei Arduino eine platform.local.txt anlegen und Compiler Flags > wie bspw. "-Wl,-u,vfprintf -lprintf_flt -lm" setzen. Durch wegnehmen des # die gewünschte Variante aktivieren.
1 | # erlaubt float in sprintf und seinen Brüdern.
|
2 | #compiler.c.elf.extra_flags=-Wl,-u,vfprintf -lprintf_flt
|
3 | # -lm
|
4 | |
5 | # erlaubt float in sscanf und seinen Brüdern.
|
6 | #compiler.c.elf.extra_flags=-Wl,-u,vfscanf -lscanf_flt -lm
|
7 | |
8 | # erlaubt float in sscanf,sprintf und ihren Brüdern.
|
9 | #compiler.c.elf.extra_flags=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt
|
Flunder schrieb: > Fließkommazahlen in > printf() Ach ja.. Für printf() brauchts auch noch etwas Vorbereitung . z.B. so, oder so ähnlich:
1 | int writeChar(char c, FILE *) |
2 | {
|
3 | return !Serial.write(c); |
4 | }
|
5 | |
6 | int readChar(FILE *) |
7 | {
|
8 | int c; |
9 | while(-1 == (c=Serial.read())); |
10 | return c; |
11 | }
|
12 | |
13 | |
14 | |
15 | FILE stdiostream; |
16 | |
17 | |
18 | void setup() |
19 | {
|
20 | fdev_setup_stream(&stdiostream, writeChar, readChar, _FDEV_SETUP_RW); |
21 | stdin = stdout = stderr = &stdiostream; |
22 | |
23 | |
24 | Serial.begin(9600); |
25 | |
26 | signed value = 72; |
27 | printf("testHex 0x%02X\r\n",value); |
28 | printf("testDezimal %02d\r\n",value); |
29 | }
|
30 | |
31 | void loop() |
32 | {
|
33 | }
|
:
Bearbeitet durch User
Veit D. schrieb: > Hallo, > > man kann bei Arduino eine platform.local.txt anlegen und Compiler Flags > wie bspw. "-Wl,-u,vfprintf -lprintf_flt -lm" setzen. Die > Ressourcenbelegung muss man sich dann anschauen. Diese Lösung hatte ich schon gesehen, aber die Datei muss unter den lokalen Anwendungsdaten eines Benutzers angelegt werden. D.h. jeder muss diese Datei auf jedem Rechner anlegen, um meinen Quellcode übersetzen zu können. Andererseits ändert derjenige, der das tut, damit die Einstellungen mit denen er jedes Arduino Projekt für AVR Mikrocontroller übersetzt. Beide Punkte sind extrem hinderlich, wenn man etwas an Kollegen weiter geben will, die das abändern und schnell mal compilieren können sollen.
Flunder schrieb: > Diese Lösung hatte ich schon gesehen, aber die Datei muss unter den > lokalen Anwendungsdaten eines Benutzers angelegt werden. D.h. jeder > muss diese Datei auf jedem Rechner anlegen, um meinen Quellcode > übersetzen zu können. > > Andererseits ändert derjenige, der das tut, damit die Einstellungen mit > denen er jedes Arduino Projekt für AVR Mikrocontroller übersetzt. > > Beide Punkte sind extrem hinderlich, wenn man etwas an Kollegen weiter > geben will, die das abändern und schnell mal compilieren können > sollen. Dann solltet Ihr auf eine andere IDE umsteigen, bei der nicht alles global geändert wird. Die Arduino-IDE ist ja ganz nett, hat aber so ihre Macken (Der Wechsel zwischen zwei Controllerfamile gilt für jedes Projekt...).
Flunder schrieb: > .... Was ein Gejammere.... Es sollte doch mit den gegebenen Informationen, kein Problem sein, eine eigene Hardwaredefinition/Boarddefinition in sketchbook/hardware anzulegen.
:
Bearbeitet durch User
Was spricht gegen ein makefile um die Kontrolle wieder zu erlangen?
Norbert schrieb: > Was spricht gegen ein makefile um die Kontrolle wieder zu erlangen? Hast du einen Plan, wie Makefiles in der Arduino IDE bzw. mit dem Arduino Framework nutzt? Ich glaube, das ist dort nicht vorgesehen.
Monk schrieb: > Hast du einen Plan, wie Makefiles in der Arduino IDE bzw. mit dem > Arduino Framework nutzt? Ich glaube, das ist dort nicht vorgesehen. Könnte mir vorstellen, das man einfach ein Terminal öffnet und dann make eintippt. ;-) Aber mal ernsthaft, Arduino nutzt doch soweit ich mich erinnern kann (und das ist ne sehr lange Zeit her) die GCC suite. * Kompiliert einen Sack voll. * Erstellt ein Archiv. * Kompiliert weiter und linkt den Plunder zusammen. Na und ein einfaches Makefile erstellen gehört doch sozusagen zu den Grundfertigkeiten.
Norbert schrieb: > Arduino nutzt doch Keine Makefiles! Aber dafür einen Builder Den Arduino Builder, der die Boarddefinitionen lesen kann. Wie make, lässt sich der auch einzeln aufrufen, ohne IDE. Heißt dann Arduino CLI, oder so ähnlich. Macht z.B. richtig Sinn, wenn man nach einer Lib/System Änderung, alle abhängigen Projekte im Stapel neu übersetzen möchte. Für alle verwendeten µC/Boards. Norbert schrieb: > Na und ein einfaches Makefile erstellen gehört doch sozusagen zu den > Grundfertigkeiten. Der Builder macht so einige Dinge, die ein Makefile bzw. make nicht so ohne weiteres kann.
:
Bearbeitet durch User
Anstatt Klopper wie printf kann man evtl. auch Konverter wie atof oder ftostr verwenden? https://avrdudes.github.io/avr-libc/avr-libc-user-manual-2.2.0/group__avr__stdlib.html
Johann L. schrieb: > Anstatt Klopper wie printf kann man evtl. auch Konverter wie atof oder > ftostr verwenden? Serial(erbt von Print) und auch String können float verarbeiten. Eine Notwendigkeit für printf und seine Brüder gibt es in der Arduinowelt eigentlich nicht. Ich selber verwende printf nur, weil/wenn ich uralt(?) C oder C++ Programme mit der Arduino IDE übersetze. Bei scanf ist das etwas anders, das vermisse ich schon eher mal.
:
Bearbeitet durch User
Arduino F. schrieb: > Eine Notwendigkeit für printf und seine Brüder gibt es in der > Arduinowelt eigentlich nicht. Naja, die Formatierung mit printf ist schon komfortabler: Man kann alles in einen Formatstring packen und spart sich "zeilenweise" prints. Arduino F. schrieb: > Bei scanf ist das etwas anders, das vermisse ich schon eher mal. Noch nie benutzt.
Johann L. schrieb: > Anstatt Klopper wie printf kann man evtl. auch Konverter wie atof oder > ftostr verwenden? Wenn es einem völlig wurscht ist, wie die Ausgabe formatiert wird, ja. Sobald man aber ein bestimmtes definiertes Format braucht (führende Leerzeichen, rechtsbündige Ausgabe, definierte Anzahl Nachkommastellen etc.) muss man den eigenen Code mit Kram aufblähen, den man nur braucht, weil man den gefühlten "Klopper" printf einsparen will. Die Zeit, aus der die Weisheit stammt, printf um wirklich jeden Preis zu vermeiden, ist eigentlich schon lange vorbei, jedenfalls, wenn man mit µCs arbeitet, die mehr als 2 kiB Flash-ROM haben.
printf braucht aber auch einiges an RAM der vom Stack genutzt wird, das dürfte eher ein Grund sein warum das bei den kleinen AVR deaktiviert ist. Eigene Compilerschalter kann man einfach bei PlatformIO nutzen, die packt man da in die platformio.ini und gehört damit zum Projekt. Auch die Abhängigkeiten mit den nötigen Versionen kann man da eintragen, das ist ja ebenfalls ein Problem bei der original Arduino IDE.
Norbert schrieb: > Na und ein einfaches Makefile erstellen gehört doch sozusagen zu den > Grundfertigkeiten. Nein, schon lange nicht mehr. Make ist nicht Bestandteil der GNU Compiler Collection, das muss man ggf. separat installieren. Wie viele andere IDE auch arbeitet auch die Arduino IDE ohne Make. Sie enthält ihren eigenen Build-Prozessor.
Harald K. schrieb: > Dafür hat man jetzt CMake. CMake ist nicht Bestandteil der GNU Compiler Collection, das muss man ggf. separat installieren. Wie viele andere IDE auch arbeitet auch die Arduino IDE ohne CMake. Sie enthält ihren eigenen Build-Prozessor
Und Cmake ersetzt ein make nicht, das wird trotzdem gebraucht. Oder es wird ninja benutzt, muss aber auch extra installiert werden. Auch deshalb ist Pio angenehmer, aus der kleinen platformio.ini ist ersichtlich was zum bauen nötig ist und wird automatisch installiert.
Monk schrieb: > CMake ist nicht Bestandteil der GNU Compiler Collection, das muss man > ggf. separat installieren. Das hab' ich auch nicht behauptet. J. S. schrieb: > Und Cmake ersetzt ein make nicht, das wird trotzdem gebraucht. Genau, noch eine Schicht auf dem Schichtkuchen mehr. CMake erzeugt nur Makefiles in einem zum gewünschten make hoffentlich passenden Format - das kennt sogar Microsofts nmake. J. S. schrieb: > Oder es wird ninja benutzt, muss aber auch extra installiert werden. Wieder 'ne andere Schicht. > Auch deshalb ist Pio angenehmer, Eigentlich auch nicht, nur weil es wohl mit dem von Dir verwendeten Toolkit mitkommt ...
@Monk Nur weil du keine Ahnung hast must nicht die Leute mit deinem 'Schichtkuchen'verunsischern, das ist einfach Bullshit. Cmake ist eine Metasprache die eben etwas unabhängig von OS und Buildsystemen macht. Ja, es generiert makefiles für make oder ninja (ist dem make sehr ähnlich), aber vermeidet das bei jedem Build Abhängigkeiten geprüft werden müssen. Das macht bei großen Projekten einen gewaltigen Unterschied. Auch das Intellisense wird dabei unterstützt durch Export einer Datei compile_commands.json die dem Intellisense bei den tatsächlich verwendeten Includes und defines hilft. Das hat alles nichts mit irgendwelchen zusätzlichen Schichten zu tun. Harald K. schrieb: > Eigentlich auch nicht, nur weil es wohl mit dem von Dir verwendeten > Toolkit mitkommt ... auch falsch, die Toolkits werden installiert wenn die Platform es braucht.
J. S. schrieb: > @Monk Nur weil du keine Ahnung hast Habe ich etwas falsches geschrieben? > Cmake ist eine Metasprache ... Das ändert nichts daran, dass kein Make-Programm Bestandteil der gcc ist, und mit Arduino nichts zu tun hat und auch nicht mehr zu den Grundfertigkeiten gehört.
Make erzeugt nur die Kommandozeile für den Compiler, z.B. GCC. Man kann daher sämtliche Aufrufe genauso gut in eine Batchdatei schreiben. Eine Batchdatei kann sogar Errorlevel auswerten und so den Compilevorgang abbrechen. Oder Umgebungsvariablen und externe Tools einbinden.
Ich habe den Eindruck, dass hier nicht alle wissen, was der Arduino Builder so alles tut. Dem kann abgeholfen werden: https://arduino.github.io/arduino-cli/0.21/sketch-build-process/ Damit der TO sein Problem einfach lösen kann, wäre das erstellen einer eigenen Boarddefinition eine praktikable Möglichkeit, damit der Arduino Builder auch seinen Job erledigen kann. Wie man eine solche erstellt findet sich hier: https://arduino.github.io/arduino-cli/0.21/platform-specification/
Flunder schrieb: > ich mich nicht um dessen Projekte kümmern mag, die plötzlich und > unverhofft nicht mehr in den Speicher passen. > Gibt's da auch noch eine Möglichkeit ? Auch wenn die Antwort erstmal OT erscheint ist sie grundsätzlich ganz einfach: keine Fließkommazahlen nehmen auf einem Rechner, der eh keine FPU hat. Ich bin mir sicher, dass in deutlich über 99% der Fälle, wo ein üblicher Arduinist einen 32-Bit Float nimmt, ein 32-bit Integer die Arbeit mindestens gleich gut erledigen könnte. Wenn schon beim Berechnen einer Spannung aus einem ADC-Wert der Faktor 1024.0 (oder schlimmer noch 1023.0) drin seht, dann ist das sicher der Fall. Denn statt mit Float in Volt
1 | float u; // V |
2 | u = adc*5.0/1024.0; |
könnte man auch mit einem Integer in mV rechnen und schreiben
1 | uint32_t u; // mV |
2 | u = adc*5000/1024; |
Und wenn man keine Float-Zahlen im Programm hat, muss man logischerweise keine Floatzahlen ausgeben. Problem gelöst. Jetzt dürft ihr das Problem aber weiterhin auf die andere Art lösen. Viel Erfolg dabei.
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Ich bin mir sicher, dass in deutlich über 99% der Fälle, wo ein üblicher > Arduinist einen 32-Bit Float nimmt, ein 32-bit Integer die Arbeit > mindestens gleich gut erledigen könnte. Lustiger Weise ist eine Division in float auf dem AVR sogar schneller, als mit int32. Float rechnet nämlich nur mit 23 Bit Mantisse. Flash kostet auch nur der erstmalige Aufruf einer Funktion, jeder weitere Aufruf kostet einfach nur den Call. Besonders bei Regelungen bin ich es gründlich Leid, wenn sie wegen Rundungsfehlern oder Überläufen gegen den Baum laufen. Solange zeitlich nichts dagegen spricht, nehme ich für Berechnungen aller Art grundsätzlich nur noch float. Selbst ein 8-Pinner (ATtiny85) kann float rechnen. Als Anfänger muß man erstmal lernen, nur dort zu optimieren, wo es auch einen signifikanten Effekt hat.
Peter D. schrieb: > Als Anfänger muß man erstmal lernen, nur dort zu optimieren, wo es auch > einen signifikanten Effekt hat. Eben. "Premature optimization" und so ...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.