Darstellungproblem

Gast #303813
Lesenswert?

Ich sende über die UART vom ATMEGA8535 Temperatur und Luftdruckwerte
sowie Datum. Das alles geht ja schon mal. Nur ich bekomme nicht die
Daten so an wie hier:

2006 12. 16. 1 1014 23
2006 12. 16. 2 1014 23
2006 12. 16. 3 1014 23
2006 12. 16. 4 1014 23
2006 12. 16. 5 1014 23
2006 12. 16. 6 1014 23
2006 12. 16. 7 1014 23
2006 12. 16. 8 1014 23
2006 12. 16. 9 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 1 1014 23
2006 12. 16. 2 1014 23
2006 12. 16. 2 1014 23
2006 12. 16. 2 1014 23
2006 12. 16. 2 1014 23

Mit dem Terminalprogramm empfange ich immer dies hier:
Da sind immer Leerzeichen die da nicht hin sollen, sowie nach 16.
sollte eigentlich die Zahl von 1 bis 23 dargestellt werden. Hier sieht
man nur immer ein Zeichen.

 2006 12. 16. 1 1014 23
 2006 12. 16. 2 1014 23
 2006 12. 16. 3 1014 23
 2006 12. 16. 4 1014 23
 2006 12. 16. 5 1014 23
 2006 12. 16. 6 1014 23
 2006 12. 16. 7 1014 23
 2006 12. 16. 8 1014 23
 2006 12. 16. 9 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 1 1014 23
 2006 12. 16. 2 1014 23
 2006 12. 16. 2 1014 23
 2006 12. 16. 2 1014 23
 2006 12. 16. 2 1014 23

Meine Funktion sieht so aus:

void tagesprofil (void)
{
 unsigned char n, m;
 for (n=0; n<24; ++n)
    {
     if (n == 0)
      {
       putchar('T');
      }
     sprintf (printbuf,"%4i%2i.%2i.%2i
",2006,(int)12,(int)16,(int)n);
     sprintf (printbuf+15,"%4i%3i",1014,23);
     *(printbuf+24) = 0x0d;
     *(printbuf+25) = 0x0a;
     for (m=0; m<26; ++m)
        {
          putchar(*(printbuf + m));
        }
     {unsigned int i; for (i=1000; i>0; --i);}
    }
 putchar('E');
}
Gast #303814
Lesenswert?

Mist ich muss mich wieder korrigieren:

Ich möchte diese Darstellung haben:

2006 12.16.01 1014 23
2006 12.16.02 1014 23
2006 12.16.03 1014 23
2006 12.16.04 1014 23
2006 12.16.05 1014 23
2006 12.16.06 1014 23
2006 12.16.07 1014 23
2006 12.16.08 1014 23
2006 12.16.09 1014 23
2006 12.16.10 1014 23
2006 12.16.11 1014 23
2006 12.16.12 1014 23
2006 12.16.13 1014 23
2006 12.16.14 1014 23
2006 12.16.15 1014 23
2006 12.16.16 1014 23
2006 12.16.17 1014 23
2006 12.16.18 1014 23
2006 12.16.19 1014 23
2006 12.16.20 1014 23
2006 12.16.21 1014 23
2006 12.16.22 1014 23
2006 12.16.23 1014 23

Also ganz oben das ist falsch.
Persönliche Seite #303815
Lesenswert?

Warum so umständlich?

     sprintf (printbuf,"%4i%2i.%2i.%2i
",2006,(int)12,(int)16,(int)n);
     sprintf (printbuf+15,"%4i%3i",1014,23);
     *(printbuf+24) = 0x0d;
     *(printbuf+25) = 0x0a;

a) Die typecasts nach int kannst Du weglassen, die Konstanten sind
sowieseo vom Typ int.

Leerzeichen sollten auch im Formatstring angegeben sein.

b) Ein Aufruf von sprintf genügt völlig:


  sprintf(printbuf, "%04d %02d.%02d.%02d %04d %02d\r\n",
    2006, 12. 16, n, 1014, 23);



(Anstelle von %i kann auch das üblichere %d verwendet werden)

Natürlich könntest Du, wenn fast alle Parameter eh Konstanten sind,
auch sprintf wie folgt verwenden:

  sprintf(printbuf, "2006 12.16.%02d 1014 23\r\n", n);

aber das wäre vermutlich zu einfach.

Desweiteren kannst Du auf Dein Abzählen von Zeichen bei der Ausgabe des
Inhaltes von printbuf verzichten; printbuf enthält einen
nullterminierten String, und das kann man ausnutzen:

  char* p;  // Hilfspointer

  p = printbuf;

  while (*p)
  {
    putchar(*p++);
  }

Du musst nur sicherstellen, daß printbuf ausreichend groß ist, um einen
Deiner Strings aufnehmen zu können - und auch Platz für die
abschließende \0 hat, die von sprintf als Kennzeichnung des
Stringendes angehängt wird.

Im übrigen hätten zur Demonstration des gewünschten Formates zwei bis
drei Beispiele vollends genügt; 23 ist eindeutig übertrieben.

Ansonsten solltest Du die "BACK"-Funktion Deines Browsers nicht
verwenden, sonst passiert Dir diese Beitragsinkontinenz wie oben.
Gast #303817
Lesenswert?

Hab meinen Code abgeändert.
Jetzt erhalte ich vom Controller über die UART folgendes:

T 2006 12. 16. 0 1024 23
<0> 2006 12. 16. 1 1024 23
<0> 2006 12. 16. 2 1024 23
<0> 2006 12. 16. 3 1024 23
<0> 2006 12. 16. 4 1024 23
<0> 2006 12. 16. 5 1024 23
<0> 2006 12. 16. 6 1024 23
<0> 2006 12. 16. 7 1024 23
<0> 2006 12. 16. 8 1024 23
<0> 2006 12. 16. 9 1024 23
<0> 2006 12. 16. 10 1024 23
 2006 12. 16. 11 1024 23
 2006 12. 16. 12 1024 23
 2006 12. 16. 13 1024 23
 2006 12. 16. 14 1024 23
 2006 12. 16. 15 1024 23
 2006 12. 16. 16 1024 23
 2006 12. 16. 17 1024 23
 2006 12. 16. 18 1024 23
 2006 12. 16. 19 1024 23
 2006 12. 16. 20 1024 23
 2006 12. 16. 21 1024 23
 2006 12. 16. 22 1024 23
 2006 12. 16. 23 1024 23
E

Woher kommt da das Zeichen <0>? Ich möchte dass das Zeichen <0> nicht
erscheint bzw vorhanden ist.Desweiteren sollte nach 12. und nach 16.
kein Leerzeichen vorhanden sein. Ich weiss nun nicht wo ich da meinen
Code abändern muss.

Der Code sieht so jetzt aus:

void tagesprofil (void)
{
 unsigned char n, m;
 for (n=0; n<24; ++n)
    {
     if (n == 0)
      {
       putchar('T');
      }
     sprintf
(printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,(int)12,(int)16,(int)n,1024,23 
);
     for (m=0; m<26; ++m)
        {
          putchar(*(printbuf + m));
        }
     {unsigned int i; for (i=1000; i>0; --i);}
    }
 putchar('E');
}
Persönliche Seite #303818
Lesenswert?

Du solltest Dir mal die Bedeutung des Formatstrings von printf() und
Konsorten näher ansehen.

Der von Dir gepostete Formatstring kann jedenfalls die von Dir
gepostete  Ausgabe nicht erzeugen:

  "%4d%2d"

  mit den Argumenten 2006 und 12 (lass den Typecast weg!)

  ergibt

  "200612"

Ohne dazwischengesetztes Leerzeichen und auch ohne Leerzeichen oder
sonstwas vor 2006.

Mir scheint, Code und Ausgabe"beispiel" passen nicht zusammen.

Hast Du eigentlich wirklich gelesen, was ich vor drei Tagen schrieb?
Gast #303819
Lesenswert?

vielleicht sendest Du zu schnell und das Terminal bringt etwas
durcheinander:
     for (m=0; m<26; ++m)
        {
          putchar(*(printbuf + m));
        }
     {unsigned int i; for (i=1000; i>0; --i);}

teste mit Pause nach jedem Zeichen statt nur vor dem E:
     for (m=0; m<26; ++m)
        {
          putchar(*(printbuf + m));
          {unsigned int i; for (i=1000; i>0; --i);}
        }
und pass auf, ob der Compiler die Warteschleife nicht wegoptimiert.

oder Dein Compiler hält sich nicht an die Konventionen und hält vor
jeder integer-Zahl ein Zeichen für das Vorzeichen frei.
caste mal mit (unsigned int)
aber das kann ich mir gar nicht vorstellen.

Versuche mal rauszufinden, ob der Fehler in der sprintf-Zeile passiert
oder in der Ausgabeschleife.
Gast #303820
Lesenswert?

Tja, ich hab alles mögliche versucht. Ohne Erfolg.Ich in verschiedenen
stellen delays eingebaut.

unsigned char printbuf [96];

void tagesprofil (void)
{
 unsigned char n, m;
 for (n=0; n<24; ++n)
    {
     if (n == 0)
      {
       uart_transmit('T');
      }
     sprintf
(printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,(int)12,(int)16,(int)n,1024,(i 
nt)23);
     for (m=0; m<25; ++m)
        {
          uart_transmit(*(printbuf + m));
        }
     delay_ms(20);
    }
 uart_transmit('E');
}

Also beim Empfangen sieht es mal schon besser aus.
Leider ist es aber noch immer so, dass zwischen den Punkten (Datum)
immer noch ein Leerzeichen vorhanden ist.
Ich hab soger mal nur ein paar Zeichen gesendet da sieht es auch nicht
besser aus.
ich finde das echt komisch!
Gast #303826
Lesenswert?

Ok das könnte vielleicht sein, aber diesen String
"2006 12. 16. 11 1024 23" empfange ich 24 mal korrekt.
Da sind wie gesagt nach den Punkten immer ein Leerzeichen. Die sollen
da nicht vorkommen.

sprintf
(printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,12,)16,n,1024,23);

Genau so verwende ich den Code bei mir.
#303830
Lesenswert?

Das ist in der Tat seltsam.
Das sollte nicht so sein.

Sag. Welchen Compiler in welcher Version benutzt du?
Vielleicht klingelts da bei irgendjemandem.

Hmm.

sprintf
(printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,(int)12,(int)16,(int)n,1024,(i 
nt)23);
     for (m=0; m<25; ++m)
        {
          uart_transmit(*(printbuf + m));
        }

Hmm. Beim sprintf sollte eigentlich gar kein String der
Laenge 25 entstehen. Wenn ich den Format-String durchgehe,
komme ich auf 21 Zeichen

PS:
Die int-casts im Aufruf kannst Du Dir sparen, die bewirken
gar nichts. Kannst Du Dir die Laenge des entstandenen Strings
in printbuf mal ausgeben lassen. Ziel ist es abzuklaeren ob
die zusaetzlichen Zeichen im sprintf entstehen oder ob die
irgendwie waehrend der Datenuebertragung hineingeschmuggelt
werden.
#303831
Lesenswert?

> Da sind wie gesagt nach den Punkten immer ein Leerzeichen. Die
> sollen da nicht vorkommen.

Hmmm...
Sind die Leerzeichen nun nach den Punkten oder vor den Zahlen?

Denn in VB muss ich die Zahlen über TRIM(zahl) ausgeben, wenn ich die
Leerzeichen davor vermeiden will.

Von C habe ich aber keine Ahnung, AVRs programmiere ich in ASM.

...
Gast #303834
Lesenswert?

Nicht nach einem Punkt, sondern vor einer 2-stelligen Zahl (beachte:
vor dem 12 ist auch ein falsches Leerzeichen).

Versuche mal, statt %2d nur %d  und auch mal %2u  und %u zu verwenden.
Bitte teile uns auch die Ausgaben von  %02d und %02u  mit.

Ich vermute, er reserviert vor einer 2-stelligen Zahl ein Zeichen für
das (bei positiven Zahlen nicht vorhandene) Vorzeichen. Sind Zahlen
länger als angegeben, werden sie auch länger ausgegeben. Bei der Angabe
handelt es sich um eine Mindestbreite.

Welchen Compiler / Version verwendest Du?

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