Hallo,
wende mich hier mal an mein "kleines" Problem.
Vorgeschichte. Habe eine Schaltung (danke an die Hilfe der Kollegen
hier) gebaut die mit einem Sensor ein Analog Signal an den
Mikrocontroller gibt.
Dort wird er umgewandelt und dann am Display ausgegeben.
Jetzt passt alles so weit. Jetzt möchte ich gerne die Daten auch vom
Mikrocontroller auf die SD-Karte schreiben lassen.
Das Board ist ein: Stellaris LM3S8962
verwendete Fatlibrary: FatFs - FAT file system R0.04b
Hier mein Code bis jetzt:
static FRESULT fresult;
static FATFS fatfs;
static FIL fil;
void sd_card(double value)
{
RIT128x96x4Disable();
if (k<160 && Benutzerdelay>0)
{
sprintf(&array_value[k], "%.2f\n", value);
k+=8;
}
WORD written;
if (k==160)
{
k=161;
fresult = f_mount(0, &fatfs);
fresult = f_open(&fil, "value.txt" , FA_CREATE_NEW | FA_WRITE);
fresult = f_write(&fil, array_value, sizeof(array_value) ,&written);
fresult = f_close(&fil);
}
RIT128x96x4Enable(1000000);
RIT128x96x4Init(1000000);
RIT128x96x4StringDraw("Werte werden geschrieben", 60, 46, 15);
SysCtlDelay(5000000);
}
Mein Wunsch ist das das es die Daten so anzeigt.
XX.XX Einheit 1. Messung
XX.XX Einheit 2. Messung
usw.
ich kriege es damit hin das die Daten nacheinander hingeschrieben
werden.
12.30 14.56 11.87 12.01 usw.
jedoch krieg ich nicht eine neue Zeile hin und den Text.
Habe jetzt die ganze Zeit überall was gesucht und nichts gefunden.
Könnt ihr mir weiterhelfen?
Habt ihr vielleicht eine Möglichkeit (die finde ich 100 Mal besser aber
krieg sie nicht hin)
das z.b. das Programm so abläuft.
Funktion wird aufgerufen, Wert wird in ein Array geschrieben, das in ein
String und dann in die Datei. Falls es nochmal aufgerufen wird soll es
dort anfangen wo es aufgehört hat und einfach eine Zeile
weiterschreiben.
Im Moment wartet er bis das Array voll ist und schreibt das ganze Array
rein.
Mit dem nächsten hätte ich immer eine feste Arraygröße und es schreibt
einfach im nächste block weiter auf der SD
char temp_array[20]; //
int i = 0;
for (i;i<20;i++)
{temp_array=0;}
Array sieht folgendermaßen aus mit Beispiel werten
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
[1][2][.][3][2][][m][s][][1][.][][M][e][s][s][u][n][g][\n] // \n für
neue Zeile?
sprintf(&array_value[0], "%.2f\n", value);
array_value[5] = ' ';
array_value[6] = 'm';
array_value[7] = 's';
array_value[8] = ' ';
array_value[9] = (int) laufvariable; /hier soll immer die aktuelle
zahl stehen wie mach ich da ein typecast?
array_value[10] = '.';
array_value[11] = ' ';
array_value[12] = 'M';
array_value[13] = 'e';
array_value[14] = 's';
array_value[15] = 's';
array_value[16] = 'u';
array_value[17] = 'n';
array_value[18] = 'g';
array_value[19] = '\n';
WORD written;
fresult = f_mount(0, &fatfs);
fresult = f_open(&fil, "value.txt" , FA_CREATE_NEW | FA_WRITE);
fresult = f_write(&fil, array_value, sizeof(array_value) ,&written);
fresult = f_close(&fil);
Hi
Windows will als Zeichen am Zeilenende ein carrige return + linefeed
aber dein /n erzeugt wohl nur den LF es müsste gehen wenn du /r/n
schreibst oder in nem ordentlichen Texteditor (ich verwende Notepad++)
das end of line Symbol änderst/konvertierst.
Und was das weiterschreiben in der gleichen Datei angeht kenn ich zwar
die FAT Bibliothek nicht aber intuitiv würde ich sagen das du beim Datei
öffnen nicht FA_CREATE_NEW verwenden darfst sondern irgendwas mit append
oder so, da musst du mal in die doku schauen.
Ich hoffe das hilft dir weiter.
Gruß
Und wenn du schon dabei bist, das C Buch zum Thema "was kann ich mit den
Formatieroptionen der printf Funktionen anstellen", dann kies auch
gleich noch das Hauptkapitel ueber Strings noch mal durch. Auch da
duerften so einige Grundlagen nicht verstanden worden sein.
Sprich: Du hast massive Wissensdefizite. Aber nicht in der Benutzund der
SD-Karten Funktionen sondern am ganzen drumherum.
Habe den Befehl sprintf nicht genau angeschaut muss ich zugeben.
Habe bis jetzt nur mit c++ programmiert und dachte das wird schon. Merke
aber das es doch nciht so leicht transerierbar ist da ich mit der
namespace std gearbeitet habe.
Ich bin jetzt so weit das auf der Karte das geschrieben wird (Text File
im Anhang)
Hier der Code
Da fehlt immer noch der Zeilentrenner: \n z.b.
Und der buffer wert_char kann zu klein werden, wenn messung mehrstellig
ist. Ausserdem brauch der Terminator \0 noch Platz.
Also noch mal im K&R über Strings und Files lesen.
nicht sizeof benutzen.
Du willst den String, der in wert_char steht, so wie er ist aufs File
geschrieben haben. sizeof liefert dir die Größe des Arrays in Bytes. Die
Größe des Arrays! Aber das ist nicht notwendigerweise die Länge des
Strings, der in diesem Array gespeichert ist. Diese Länge kriegst du
z.b. mit strlen.
jetzt schreibt f_write genau den String, so wie er ist, auf das File.
Nicht mehr und nicht weniger. Wenn dann am File immer noch Quatsch
steht, dann hast du den String nicht richtig zusammen gebaut.
Und sorg dafür, dass das Array ausreichend groß ist! Es hat keinen Sinn
an dieser Stelle zu kleckern (zumindest jetzt noch nicht. Wenn das
Programm mal fertig ist, sieht die Sache anders aus). Da stolpert man
immer wieder drüber, dass man sich eine Formatierung zusammenbaut, die
in Summe dann das Array überläuft. Da das ganze in einer FUnktion lokal
zusammengefasst ist und du auf deinem µC wahrscheinlich nicht unter
Speichermangel leidest, brauchst du hier nicht knausern. Definiere das
Array zb 256 Zeichen gross, dann hast du erst mal ausreichend Reserven
ohne dass du bei der geringsten Formatieränderung sofort in
Speicherüberläufe reinläufst.
Dafür kannst du dir das
ist auch sicher nicht das, was du tun willst.
-> Nochmal die Doku der SD_Routinen studieren. Da gibt es sicher ein
Append Flag, dass du beim Open angeben kannst und welches dafür sorgt,
dass hinten am bisherigen File weiter geschrieben wird.
Vielen Dank an euch drei (Karl Heinz, PittyJ und LittleHelper)
Durch PittyJ habe ich mich nochmal explizit mit sprintf zusammengefasst.
Ich finde es auf c++ einfacher.Wusste aber bis dato nicht das man es so
in c benutzen kann.
Durch LittleHelper habe ich den richtigen Modus ausgewählt
(FA_OPEN_ALWAYS) und f_lseek. Habe sogar beim recherchieren noch ein
paar Funktionen für mich entdeckt die ich gleich mit implementiert habe
(lösch Funktion des Files).
Durch KarlHeinz habe ich meine Funktion wirklich sauber implementiert.
Ich hatte es zwar vorhin mit sizeof hinbekommen jedoch war es sauber
implementiert für messungen bis 9999 (Speicherbereich). Mehr wäre auch
nicht nötig gewesen.
Aber ich fand deinen Ansatz mit strlen um längen besser da man mit der
Zeit vielleicht doch mal mehr Messungen machen möchte und/oder man das
Programm für eine andere Anwendung nehmen könnte.
Vielen Dank euch drein nochmal :)
Falls jemand Interesse haben sollte an dem Code kann er mir gerne
schreiben dann schicke ich ihm den Code gerne zu.
Nijen T. schrieb:> Durch KarlHeinz habe ich meine Funktion wirklich sauber implementiert.> Ich hatte es zwar vorhin mit sizeof hinbekommen
Mit Sichderheit nicht.
Wie lang der String ist, der hier
ensteht, kannst du doch ohne Kenntnis der Werte gar nicht wissen. Vor
allen Dingen die Anzahl der Messungen nimmt bei überschreiten der 10-er,
100-er Grenze etc. um 1 Zeichen zu.
Fazit: Dein String hat keine definierte, immer gleiche Länge. Damit
kannst du dein Array überhaupt nicht passend dafür dimensionieren und
damit ist auch ein sizeof sinnlos. sizeof ist eine statische Sache, die
vom Compiler erledigt wird. Da ist nichts mit 'zur Laufzeit ermitteln'.
(Ja ich weiss, mit dem letzten C Standard gibt es da eine Ausnahme. Aber
um die gehts hier nicht)
Damit schreibst du aber 0-Bytes ins File und bei Textfiles ist so etwas
oft tödlich. Wiviele Leseroutinen von weiterverarbeitenden Programmen
damit rechnen und damit klar kommen, will ich lieber nicht wissen. Die
Anzahl dürfte nicht allzu hoch sein.
> jedoch war es sauber> implementiert für messungen bis 9999 (Speicherbereich). Mehr wäre auch> nicht nötig gewesen.> Aber ich fand deinen Ansatz mit strlen um längen besser da man mit der> Zeit vielleicht doch mal mehr Messungen machen möchte und/oder man das> Programm für eine andere Anwendung nehmen könnte.
Vor allen Dingen ist es DIE Methode mit der man Texte in ein File
schreibt, wenn man schon kein fprintf hat oder eine andere Funktion die
einen String in ein File schreibt, welches das von alleine regelt.
@ Nijen T. (nijen)
>Habe den Befehl sprintf nicht genau angeschaut muss ich zugeben.>Habe bis jetzt nur mit c++ programmiert und dachte das wird schon.
LÄCHERLICH! Du hast nicht mal die GRUNDLAGEN von C drauf und faselst von
C++? Du hast bestenfalls ein paar Arduino Beispielscripte kompiliert!