www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Darstellungproblem


Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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');
}

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Beitragsinkontinenz

Der war gut!

;-)

...

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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');
}

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Profi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RC-Oszillator ?


Peter

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi peter,

du denkst dass es am Oszillator liegt. Warum dass denn?

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, dass Peter dich gefragt hat, ob du mit dem internen
RC-Oszillator arbeitest. Eine Antwort wäre hilfreicher als eine
Gegenfrage.

...

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach so, entschuldige.
Ich verwende bei mir einen externen 8Mhz Resonator.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, ein Baudratenquarz wäre vermutlich besser gewesen.

Die Frage sollte wohl klären, ob die Möglichkeit besteht, dass Zeichen
verloren gehen weil die Baudrate nicht genau eingehalten wird.

...

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Max F. (Gast)
Datum:

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

hab mich vertippt. So müsste es stimmen.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du mal in einem Debugger den Inhalt von printbuf näher angesehen?

Hast Du mal ausprobiert,

sprintf(printbuf, "200612.16.%2d1024 23\r\n", n);

aufzurufen?

Oder einfach nur

sprintf(printbuf, "#%2d#\r\n", n);

aufzurufen?

Warum gibst Du den Wert 23 mit dem Formatspezifizierer %3d aus?

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ich werds mal so testen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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.

...

Autor: Max F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jeweils ein Leerzeichen nach einem Punkt!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hannes

Das passt schon so.
In C kann man die Ausgabe sehr genau und feinfuehlig
ueber den Format-String steuern. Er hat fuer jede
Ausgabe exakt angegeben, wieviele Stellen sie umfassen
soll. Eigentlich sollte sich der sprintf daran halten.

Autor: Profi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.