Hallo Wissende, vielleicht ist es das Alter oder .... ich komme nicht darauf, wie ich auf dem GLCD die über den Analogeingang eingelesene Temperatur auf dem Display auch angezeigt bekomme. Als Info anbei das Arduino-Programm. Ich wäre ja sowas von dankbar.
Peter D. schrieb: > Z.B. mit sprintf() den Wert in einen Text umwandeln. Das wird nicht funktionieren, weil im Arduino Framework mit sprintf keine Floats implementiert sind (er aber genau Floats ausgeben möchte - warum auch immer - ). Hier wäre ein geeigneterer Weg (aber nicht unbedingt guter Weg) ein dtostrf:
1 | float f; |
2 | char s[20]; |
3 | |
4 | f= 2.3 * 4.6; |
5 | dtostrf(f,6, 2, s); // 6 Zeichen insgesamt, 2 Nachkommastellen |
6 | u8g.drawStr(10, 24, s); |
Hallo Ralf S. zuerst Peter D. Variante funktioniert wirklich nicht. Das Tragische, Deine Variante aber auch nicht. Nun noch einmal zum Verständnis: Ich habe nach dem gesendeten Programm auf dem GLCD die Aufschrift "Der Test" zur anzeige. In dem Programm lese ich über den Analog-Pin 0 einen Temp.-Fühler LM35 ein. Bei einer Ausgabe von resultTemp über den seriellen Monitor ist auch alles i.O. NUR, ich möchte diesen Temperaturwert auf dem GLCD angezeigt bekommen. 95 % der Verweise im Internet beziehen sich auf die Ausgabe zum seriellen Monitor (frustierend). Vielleicht hast Du noch 5 Minuten.
Zu allererst: Ich bin sicherlich nicht der Arduino-Experte und beschäftige mich aufgrund eines anderen Spaßprojektes gerade damit. Für dich habe ich jetzt einmal die u8glib Library installiert und hoffe, dass es dieselbe Library ist, die du hast. In Ermangelung deines Displays habe ich ein Display genommen, das ich hier verfügbar habe, ein N5110 (84x48 Pixel) mit PCD8544 Controller. Aus diesem Grund habe ich dann auch einen kleineren Schriftstil als Deinen gewählt. Grundsätzlich sollte aber das folgende kurze Demoprogramm Aufschluß geben, da du auf Deinem Display ja schon etwas gesehen hast (und von daher das Display richtig verdrahtet und initialisiert ist):
1 | /* |
2 | ------------------------------------------ |
3 | u8g_floatout.ino |
4 | ------------------------------------------ |
5 | */ |
6 | |
7 | #include "U8glib.h" |
8 | |
9 | U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8 |
10 | |
11 | void setup(void) { |
12 | u8g.setRot180(); |
13 | u8g.setFont(u8g_font_profont10r); |
14 | } |
15 | |
16 | float f = 4.61; |
17 | char s[30]; |
18 | |
19 | void loop(void) |
20 | { |
21 | f += 2.61; // irgendeine Rechnung |
22 | if (f > 300) f= 4.61; |
23 | |
24 | delay(500); |
25 | |
26 | dtostrf(f,6, 2, s); // 6 Zeichen insgesamt, 2 Nachkommastellen |
27 | |
28 | // Hier kommt die Ausgabe hin ! |
29 | u8g.firstPage(); |
30 | do |
31 | { |
32 | u8g.drawStr(0,24, "Ergebnis:"); |
33 | u8g.drawStr(46, 24, s); |
34 | } while(u8g.nextPage() ); |
35 | } |
Grundsätzlich erfolgt eine Ausgabe zuerst im RAM des Mikrocontrollers und nicht auf das Display. In der Beschreibung zu u8glib wird das als "Display-Loop" bezeichnet. Soll die Ausgabe auf dem Display erscheinen wird dieses "Display-Loop" mit "u8g.firstPage();" eingeleitet und in einer do-while Schleife deren Abbruchbedingung "u8g.nextPage()" ist dann angezeigt. Nach Abarbeitung dieser Schleife ist der Ram im Mikrocontroller (ich und andere auch nennen das Framebuffer) grundsätzlich gelöscht und du hast keinen Zugriff mehr auf gemacht Ausgabe. Jedes neue Beschreiben mittels Methoden von u8glib beschreiben einen leeren Framebuffer.
Beitrag #6571724 wurde vom Autor gelöscht.
... jetzt habe ich noch eine Variante aus meinen C-Quellen (nicht C++) in Arduino ausprobiert und hat auch gleich funktioniert. Ich habe die Funktion "my_ftoa" benannt: void my_ftoa(char *s, float f, char komma) my_ftoa erwartet als Parameter für "*s" einen Pufferspeicher, der den String aufnimmt, mit "f" den Floatwert, der in einen String konvertiert werden soll und in "komma" die Anzahl der Nachkommastellen, die der String haben soll. Als String ist hier ein Ansi-String (nullterminiert) gemeint und kein String aus "class string".
Hallo Ralph S. zuerst vielen Dank für Deine Nachtarbeit. Es funktioniert !! siehe beiliegendes Float.jpg. Jetzt werde ich nur noch versuchen, aus dem ursprünglichen Programm den Temperaturwert zur Anzeige zu bringen Noch einmal Danke ( und ich habe übrigens noch solch ein Display - falls Interesse ? dann Bescheid sagen) Gruß Ulrich
Freut mich, dass das geklappt hat. Die Temperatur zur Anzeige zu bringen sollte jetzt aber kein großes Problem mehr sein. Bei deinem Code
1 | float resultTemp = 0.0; |
2 | for(int i = 0; i < cycles; i++) |
3 | { |
4 | int analogValue = analogRead(sensorPin); |
5 | float temperature = (5.0 * 100.0 * analogValue) / 1024; |
6 | resultTemp += temperature; |
7 | delay(DELAY); |
8 | resultTemp /= cycles; |
9 | } |
glaube ich nicht, dass das so gewollt ist. Zumindest wirst du in resultTemp nicht den Mittelwert der Temperatur haben. resultTemp /= cyles muß hier ausserhalb der Schleife liegen.
1 | float resultTemp = 0.0; |
2 | for(int i = 0; i < cycles; i++) |
3 | { |
4 | int analogValue = analogRead(sensorPin); |
5 | float temperature = (5.0 * 100.0 * analogValue) / 1024; |
6 | resultTemp += temperature; |
7 | delay(DELAY); |
8 | } |
9 | resultTemp /= cycles; |
Außerdem solltest du dir Gedanken darüber machen, ob du jedesmal in der Schleife (hier also 20 mal) den Meßwert schon auf einen Float umrechnest, diesen addierst und dann mittelst. Besser wäre es wohl, eine uint32_t Variable aufzuaddieren und nach Beendigung der Schleife in eine Temperatur umzurechnen:
1 | uint32_t valadd= 0; |
2 | float resultTemp= 0.0; |
3 | for (i= 0; i< cycles; i++) |
4 | { |
5 | valadd += analogRead(sensorPin); |
6 | } |
7 | resultTemp = (5.0 * 100.0 * valadd) / (1024.0 * cycles); |
Das Ganze sollte dann in etwa so lauffähig sein (ich hab den analogen Teil jetzt nur simuliert):
1 | char s[30]; |
2 | |
3 | void loop(void) |
4 | { |
5 | uint32_t valadd= 0; |
6 | float resultTemp= 0.0; |
7 | for (i= 0; i< cycles; i++) |
8 | { |
9 | valadd += analogRead(sensorPin); |
10 | delay(DELAY); |
11 | } |
12 | resultTemp = (5.0 * 100.0 * valadd) / (1024.0 * cycles); |
13 | dtostrf(resultTemp,6, 2, s); // 6 Zeichen insgesamt, 2 Nachkommastellen |
14 | |
15 | // Hier kommt die Ausgabe hin ! |
16 | u8g.firstPage(); |
17 | do |
18 | { |
19 | u8g.drawStr(0,24, "Temp.:"); |
20 | u8g.drawStr(46, 24, s); |
21 | } while(u8g.nextPage() ); |
22 | } |
Anmerkung hierzug: Macht man aus nur 20 Meßwerten eine Mittelung, würde für valadd auch eine Variable vom Typ uint16_t reichen, weil bei einem Aufaddieren der Maximalwerte die der ADC liefern kann (1024) der Wertebereich eines 16-Bit Integers noch nicht überschritten ist. Vielleicht solltest du auch über die Referenzspannung des ADC nachdenken, da du mit einer sehr kleinen Steigung arbeitest. Bspw. liefert ein LM35 bei 20°C 200mV. Am ADC mit 5V als Referenz wird (bei absoluter Genauigkeit der Referenz und keinem Fehler am LM35) der ADC den Wert 40 liefern: 0,2V * 1024 / 5V = 40,96. Der Nachkommateil kann natürlich nicht abgebildet werden und so wird für 200mV der Wert 40 geliefert. Nach der Temperaturumrechnungsformel oben ergibt ein ADC-Wert von 40 den Temperaturwert 19.53°C. Immerhin schon hier (ohne Sensor- und ADC-Fehler) schon ein systematischer Fehler von 0.47 Kelvin. Hier wäre es besser, die interne Spannungsreferenz des ATMega zu nutzen (wenn es ein ATMega328 ist, sind das 1.1V). analogReference(INTERNAL); Deine Temperaturumrechnung müßte dann lauten: resultTemp = (1.1 * 100.0 * valadd) / (1024.0 * cycles); Hier ergibt sich dann für 20°C = 200mV ein ADC-Wert von (uint8_t)186.18 = 186. Das Umrechnen in eine Temperatur ergibt hier dann: 19.98°C Ulrich R. schrieb: > ( und ich habe übrigens noch solch ein > Display - falls Interesse ? dann Bescheid sagen) Vielen Dank, aber wenn ich Displays in dieser Größe und mit 240 Pixeln oder mehr verwende, nehme ich ein farbiges TFT-Display (und dann meistens einen STM32 Controller). Ich wünsche dir viel Erfolg mit deiner Temperaturmessung
Hallo Ralph S. nochmals Danke - ich werde die Temp. Umrechnung nach Deinem Beispiel vornehmen. Die in meinem alten Programm genutzte LM35 Routine stammt übrigens aus "Die elektronische Welt mit Arduino entdecken" von Erik Bartmann O´REILLY Verlag 2014 Die Beschreibung Deiner Berechnungsroutine ist natürlich einleuchtender und genauer. Nun ja, er kannte Dich nicht. Gruß Ulrich
... würde mich dann interessieren, ob es dann auch so geklappt hat wie gewünscht !
Hallo Ralph, im Anhang ein Beweisfoto und das Programm (wird natürlich noch um weitere Spielereien erweitert). Nochmals Danke Ulrich
Mea Culpa, hatte ich wahrscheinlich nicht ordentlich angehangen.
Freut mich sehr, dass es ausschaut wie es ausschaut ! Viel Spaß beim weiteren Ausbau und herumspielen
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.