Pages: [1]   Go Down
Author Topic: Merkwürdigkeit bei der formatierten Ausgabe eines Analogwertes  (Read 1272 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 3
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo zusammen:
ich grüble schon einige Stunden über folgenden Effekt:

gegeben ist ein Drehpotentiometer am Analogeingang A0, ein 2009er und ein 16x4 LC-Display,

entsprechend dem untenstehenden Code lese ich den momentanen Wert an A0 ein und gebe ihn auf der zweiten Zeile des Displays aus.
Zur besseren Lesbarkeit (und zu Fingerübungszwecken) smiley-wink ) bemühe ich eine Funktion "mach4", den eingelesenen Wert zwischen 0 und 1023 auf 4 Stellen zu formatieren, also mit führenden Leerzeichen aufzufüllen.
Im Ergebnis erhalte ich dieses Format (die Ausgabe endet immer unterhalb des Buchstabens "t" vom oberen Wort "Start",
aber ich bekomme nur maximal den Wert "996" bis "998" !
Alles ab 1000 wird nicht dargestellt, ich bemerke sogar einen spürbaren Leerweg bis zum Ende des Drehweges, ohne dass sich ein höherer Wert als 998 einstellt.
Für Debuggingzwecke habe ich eine weitere Ausgabeanweisung zur Ausgabe des ursprünglichen Zahlenwertes unter der eigentlichen Ausgabeanweisung eingebaut und hier auskommentiert,
daran sehe ich, dass durchaus am Ende des Drehweges der Wert bis auf 1023 steigt.

Kann sich mal jemand die Zeilen unten in der Funktion zu Gemüte führen,vielleicht sehe ich einfach das Simpelste nicht mehr.

Gruß
Manfred


Code:
/*
   LCD Ausgabeversuche / Analogwerte am Port A0
 
   Die Schaltung:
   Anschluss 1M Dreh-Potetiometer zwischen +5V und GND,
   Mittelabgriff an Analog-Eingang AD0 (Pin AD0)
   Ausgabe des Eingangswertes (0-1023) auf LCD Zeile 2
 */
 
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);


int analog_pin = A0;       // Analogport 0
int einlesewert = 0;       // Variable erhält den digitalen Wert 0 bis 1023 des Analogwertes
int ausgabewert = 0;       // Variable erhält den auszugebenden Wert
String ausgabe;            // Ausgabezeichenkette

void setup() {
  // set up the LCD's number of rows and columns:
  lcd.begin(16, 4);
  // Startmeldung auf die erste LCD Zeile
  lcd.print("Wert am Eingang");
 
}

void loop() {
  einlesewert = analogRead(analog_pin);
//
  ausgabe = mach4(einlesewert);  // Funktion formatiert auf 4 Stellen

  lcd.setCursor(0, 1);
  lcd.print(ausgabe);
   
// lcd.print("  ");
// lcd.print(einlesewert);

  delay(250);
}


String mach4(String eingabe)  // Eingabe auf 4 Stellen formatieren
{
  eingabe = eingabe.trim();   // evtl. "white spaces" entfernen
  int l = eingabe.length();   // Variable l hält die Länge (1-4 Zeichen)
  String ergebnis;            // Rückgabevariable
 
  switch (l)
  {
    case 1:
      ergebnis = "   " + eingabe; // plus 3 führende Leerzeichen
      break;
    case 2:
      ergebnis = "  " + eingabe;  // plus 2 führende Leerzeichen
      break;
    case 3:
      ergebnis = " " + eingabe;   // plus 1 führende Leerzeichen
      break;
    ergebnis = eingabe;           // unverändert 4 Zeichen
   }
    return ergebnis;
 }
Logged

Heidelberg
Offline Offline
Full Member
***
Karma: 1
Posts: 207
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo

womöglich hängt es nur an der 4 Stelligen Abfrage in der case- Schleife, die nicht als default: gekennzeichnet ist ?
Logged

 

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 257
Posts: 21460
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo ManfredH
Quote
womöglich hängt es nur an der 4 Stelligen Abfrage in der case- Schleife, die nicht als default: gekennzeichnet ist ?
Glaube ich auch.

Du kannst das einfacher schreiben:
Code:
switch (l)
  {
    case 1:
      eingabe = " " + eingabe; // plus 1 führende Leerzeichen total 3
    case 2:
      eingabe = " " + eingabe;  // plus 1 führende Leerzeichen total 2
    case 3:
      eingabe = " " + eingabe;   // plus 1 führende Leerzeichen
    }
    ergebnis = eingabe;       
   

Ohne "break;" werden die darauffolgenden Zeilen ausgeführt.

Grüße Uwe
Logged

0
Offline Offline
Jr. Member
**
Karma: 3
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Uwe, hallo Df6ih,

am fehlenden "default" liegt es nicht - default: ist auch in der Referenz als optional bezeichnet.

@Uwe
Deine Variante funktioniert auch nicht, sondern produziert noch eine weitere Merkwürdigkeit
(versetzen der Ausgabe um eine Stelle nach rechts bei Zahlen mit weniger als 4 Stellen).

Mit folgender stupiden Variante bin ich erfolgreich
(die unsichtbaren Blanks habe ich dieses Mal gegen Nullen getauscht, um eventuelle "Platz"Fehler zu erkennen):

Code:
String mach4(String eingabe)  // Eingabe auf 4 Stellen formatieren
{
  eingabe = eingabe.trim();   // evtl. "white spaces" entfernen
  int l = eingabe.length();   // Variable l hält die Länge (1-4 Zeichen)
  String ergebnis;            // Rückgabevariable
 
  if (l == 1)
  {
    eingabe = "000" + eingabe;
  }
  else if (l == 2)
  {
    eingabe = "00" + eingabe;
  }
  else if (l == 3)
  {
    eingabe = "0" + eingabe;
  }
 
  ergebnis = eingabe;
  return ergebnis;
 }

und weil danach auch die alte "case" Geschichte in gleicher Weise funktioniert

Code:
String mach4case(String eingabe)  // Eingabe auf 4 Stellen formatieren
{
  eingabe = eingabe.trim();   // evtl. "white spaces" entfernen
  int l = eingabe.length();   // Variable l hält die Länge (1-4 Zeichen)
  String ergebnis;            // Rückgabevariable
 
  switch (l)
  {
    case 1:
    eingabe = "000" + eingabe;
    break;
 
    case 2:
    eingabe = "00" + eingabe;
    break;
 
    case 3:
    eingabe = "0" + eingabe;
    break;
  }
 
  ergebnis = eingabe;
  return ergebnis;
}

kommen nur zwei Erklärungen in Frage:

1.) Nullen als Leerstellen statt Blanks   
sehr unwahrscheinlich

2.) die Zuweisung der verlängerten Strings in der Form "eingabe = "00" + eingabe" und erst ganz am Schluß die Zuweisung an die Variable ergebnis = eingabe

Das sieht mir sehr wahrscheinlich aus.  smiley

Werde morgen mal den Kreuzversuch mit Blanks statt Nullen machen.

Gruß
Manfred
Logged

Heidelberg
Offline Offline
Full Member
***
Karma: 1
Posts: 207
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo

Ja, aber wenn "optional" in der logischen Abfolge den nicht abgedeckten Fall klärt dann ist es zwar optional aber unabdingbar im Sinne der von dir gesuchten Lösung.

 smiley-wink
Logged

 

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 257
Posts: 21460
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo ManfredH
Ich hatte den Kode nicht kontrolliert Entschuldige.
Grüße Uwe
Logged

0
Offline Offline
Jr. Member
**
Karma: 3
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Uwe,
kein Problem!
Ich hatte ja verstanden, dass Du mir einen verkürzten Code zeigen wolltest.

@df6ih
ist schon klar.
Ich wollte mit "optional" nur klarstellen, dass der Kompiler die Anweisung default: nicht zwingend benötigt,
sie ist sicher immer sinnvoll, wenn es neben 3 oder 4 vorhersehbaren Fällen eine unbekannte Zahl anderer Möglichkeiten gibt.

Kann man eigentlich für "case <Wert> auch einen Ausdruck einsetzen oder einen Wertebereich?

Gruß
Manfred
Logged

MK (D)
Offline Offline
Full Member
***
Karma: 8
Posts: 170
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Kann man eigentlich für "case <Wert> auch einen Ausdruck einsetzen oder einen Wertebereich?
Für Letzteres hilft vielleicht ein Blick ins alte Forum:
http://arduino.cc/forum/index.php/topic,30297.msg224193.html#msg224193
Logged

Gruß Peter

0
Offline Offline
Jr. Member
**
Karma: 3
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke Schwarzfuss!
Dafür ein <Grün> smiley-wink
Logged

Italy
Offline Offline
Full Member
***
Karma: 3
Posts: 142
jayduino rox
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Hier eine Alternative, typischerweise C und sehr kompakt:

Code:
char outb[8];  // vorsicht hier, wenn du mehr 'drucken' moechtest
sprintf(outb, "%04d", meinwert); // 4 stellen mit fuehrender null
lcd.print(outb);

Wenn du nun den Format String aenderst "%04d" kannst du verschiedene Darstellungen schnell hinbekommen:
Code:
"%4d" // (keine fuehrenden Nullen)
"%+5d" // positive werte haben immer ein fuehrendes +, negative ein fuehrendes -

Du kannst aber auch bequemerweise mehrere Werte gleichzeitig 'formatieren' und Text hinzufuegen:
Code:
char outb[32];
sprintf(outb, "[A0=%4d A1=%4d]", analogRead(0),analogRead(1));
lcd.print(outb);
// druckt: [A0=    2 A1= 945]

Und zur Vollstaendigkeit, prozent angabe
Code:
char outb[32];
sprintf(outb, "A0=%3d%%", (short)((long)analogRead(0)*100/1024)); // bit verlust when in short gerechnet
lcd.print(outb);
// druckt: [A0= 61%]

HTH  smiley-wink

Logged

Juergen

0
Offline Offline
Jr. Member
**
Karma: 3
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke HTH!

Das muß ich doch ein paar Mal, gaaaanz langsam, durchsehen und verstehen.
Werde es nach dem Kaffee mal umsetzen und die resultierende Codegröße betrachten...
Da mein Mini ein 168er ist, bin ich für jedes Byte weniger dankbar!

sprintf() ist eine gültige "Arduino"-Funktion?

Gruß
Manfred
Logged

0
Offline Offline
Jr. Member
**
Karma: 3
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@ HTH:
funktioniert!

Und das Beste ist, dass statt 5132Bytes (if- oder case-Konstruktion) nur 3924 Bytes benötigt werden!

Gruß
Manfred
Logged

Italy
Offline Offline
Full Member
***
Karma: 3
Posts: 142
jayduino rox
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Manfred

sorry wegen des 'HTH', internet jargon, auf schlecht deutsch: Hope That Helps!

sprintf funktioniert, ABER keine floating points, eben wegen des platz mangels (mit fix point geht's ja auch dann, ist aber komplizierter).


Juergen
Logged

Juergen

Pages: [1]   Go Up
Jump to: