Hallo.
Kann mir vielleicht irgend jemand erklären wie das Lesen von der SD Karte funktioniert?
Bei Serial.read durchläuft es irgendwie irgend etwas und letzten Endes habe ich einfach nacheinander jedes einzelne Zeichen in einer Variable gespeichert. Wieso ist das so? Und wie kann man da einfach eine Zahlenkette in einer Variable speichern, und diese nachher wieder aufteilen in mehrere Variablen, zB die ersten 3 Zahlen in eine Variable, 4. - 8. in eine andere, und die letzten 5 wieder in eine andere?
Und kann das sein das beim lesen von der SD Karte wieder genau das gleiche ist und man irgendwie jedes Zeichen einzeln in einem Durchgang bekommt?
Wie lese ich den da eine bestimmte Zeile aus, zB Zeile 10, speichere diese Zeile (bestehend aus Buchstaben und Zahlen) in einer Variable, und Teile diese Variable wieder in mehrere auf? Evtl durch Codewort suche, steht in der Variable dieses Wort, dann setzte alles was zwischen zwei Kommas mit diesem Wort drin ist in eine andere Variable. Wie mach ich das?
Wie durchsuche ich überhaupt einen bestimmte Zeile mit Buchstaben-Zahlen-Text nach irgend welchen Schlüsselwörter, schneide mir alles was zwischen 3. Komma und 4. Komma ist heraus und speichere in einer andern Variable, und benütze die 5 Zahlen zwischen den Buchstaben vielleicht in einer anderen Variable um zu rechnen?
Wenn mir das jemand erklären könnte wäre es super, ich blicke hier überhaupt nicht durch.
Also der Link sieht schon etwas besser aus, aber ich verstehe es auch nicht wirklich. Das erste mal mit Serial.print das "uino Uno" ergibt scheint ja noch logisch, wieso beim nächsten Serial.print der Zeiger auf o ist kann ja vielleicht auch sein, aber spätestens beim nächsten Serial.print zeigt der Zeiger auf einmal auf das letzte o obwohl alles genau gleich ist ausser ein weiteres r in strrchr. Ist den das überhaupt ein normaler Name oder so etwas wie eine Funktion, oder woher kommt das aufeinmal?
Wie gibt man den einfach 4. bis 8. Zeichen aus aus einem Array? Oder vom 1. o bis 2. o? Das macht gar keinen Sinn das man einen Zeiger irgendwo drauf zeigen muss, eine Festplatte oder SD Karte kann doch gar nicht funktionieren wenn nicht so etwas wie ein Zeiger integriert wäre, sonnst müsste man ja um die letzte Datei aufzurufen den ganzen Speicher von Anfang an bis zum Schluss durchsuchen nach der letzten Datei?
Und auch mit dem Zeiger den ich nicht so ganz verstehe, wie gibt man den etwas zwischen zwei Zeigern aus?
Und in den Arduino Beispielen sehe ich nur etwas von ganzer Datei ausgeben, was wenn eine 3GB grosse Datei darauf ist, wie kann den der Arduino die auslesen und eine bestimmte Zeile heraus suchen? In einem Array wird er es wohl nicht speichern können nehme ich an? Sollte ja viel zu gross sein um auf dem Arduino zu speichern.
Kann man überhaupt so eine grosse Datei auslesen?
In den Dokumentationen finde ich auch nicht das was ich suche...
Ein Unterschied ist aber dass die serielle Kommunikation sehr langsam ist. Wenn man vernünftig nicht-blockierend programmiert kann man daher immer nur ein Zeichen einlesen und muss immer wieder nachschauen bis die ganze Nachricht da ist.
Wenn man es richtig macht kann man da aber trotzdem die gleiche Funktion wie bei einer SD Karte verwenden
Und in den Arduino Beispielen sehe ich nur etwas von ganzer Datei ausgeben, was wenn eine 3GB grosse Datei darauf ist, wie kann den der Arduino die auslesen und eine bestimmte Zeile heraus suchen?
Zeilen sind mit CR/LF abgeschlossen (und auch bei Serial sollte man das LF als Endzeichen nehmen). Dann kann Zeile für Zeile einlesen und überprüfen ob man gefunden hat was man möchte. Der Puffer muss dann nur groß genug für eine Zeile sein
Eine andere Option ist es alle Zeilen gleich lang zu machen. Dann kann man den Lesezeiger mit seek() direkt auf die gewünschte Position setzen
@ Serenifly:
Weisst du ein Beispiel wie man 2 Zeichen über Serial in ein Array einliest ohne in einer Schleife gefangen zu sein und trotzdem zu einem Ende kommt?
Vielleicht indem man auf das End-Zeichen wartet? Aber wie ist das mit der Zeit, ich muss ja eine gewisse Zeit warten bis ich das nächste Zeichen erhalte, kann ich auch zu lange auf das nächste Zeichen warten? So das ich dann einfach das übernächste bekomme weil ich zu spät war oder wartet die Serielle Kommunikation darauf bis man das nächste Zeichen ausliest?
@ noiasca:
Aber so muss der Arduino ja um zur letzten Zeile zu kommen die ganze Datei auslesen, was bei 3GB eine weile dauern sollte. Sollte da nicht eben ein Zeiger irgendwo schon auf die letzte Zeile zeigen?
Danke vielmals für das Beispiel. Ich verstehe aber so viel davon nicht...
Heisst das man könnte auch warten bis alle Zeichen da sind und dann alle Zeichen auf einmal lesen? Ich dachte man kann nur immer eines nach dem anderen abrufen. Die maximale Zeit sollte doch eigentlich auch berechnet werden können die es braucht um alle Zeichen zu senden?
Und seek() ist dazu da um zu einem bestimmten Byte in der Datei zu springen? Das wäre ja auch noch ok, manchmal vielleicht sogar besser.
Was passiert den eigentlich wenn ich lese bis zum Zeichen Zeilenende, dann etwas anderes mache, und wieder lese bis zum Zeilenende? Habe ich dann 2x die erste Zeile gelesen oder die erste und zweite Zeile?
Aber es wäre sehr einfach für mich, und es kommt ja wieder etwa auf das gleiche heraus wenn bei der SD Karte auch alle Zeilen gleich lang sein müssten. Ich könnte einfach bevor die Zeichenkette da ist etwas machen. Irgend etwas muss man ja sowieso machen in dieser Zeit wenn man alle Zeichen auf einmal braucht, also könnte man sich auch einfach einen Timer machen der Bescheid gibt wenn alle Zeichen da sind.
Und eine Zeichenkette in einem Array Speichern würde dann etwa so gehen?:
char var1[] = readLine(Serial);
Und kann es vielleicht sogar sein das man mit:
int var2 = var1[5];
eine Variable mit dem 5. Zeichen aus dem var1 Array erhält sofern dort eine Zahl steht?
Wie kann ich den mehrere Zeichen aus dem Array in die zweite Variable kriegen? Irgendwie so?:
int var2 = var1[1,2,3,4,5];
int var2 = var1[1-5];
Edit: Ah und mit "if (Serial.available() > 9)" könnte man auch schauen ob schon min 10 Zeichen angekommen sind, dann könnte man es ja auch einfach so machen
Du musst etwas Grundlagen zu Arrays und Zeigern lernen. Die sind eng miteinander verwandt. Sonst wird das nichts und to tippt nur willkürlich Code ein. Es gibt dafür genug Anleitungen und Erklärungen im Internet
Und weiterhin was zu C Strings/Zeichenketten lesen. Siehe auch ASCII. C Strings sind erst mal nur Null-terminierte ASCII Zeichen. Keine Integer. Dir fehlt anscheinend jegliches Wissen zu Datentypen und Konvertierungen.
Wie man das umwandelt, hängt vom Aufbau des Strings ab. Gewöhnlich trennt man da Zahlen mit Kommas oder Strichpunkten. Dann kann man sowas machen:
char str[] = "100,200,300";
int var1 = atoi(strtok(str, ","));
int var2 = atoi(strtok(NULL, ","));
int var3 = atoi(strtok(NULL, ","));
atoi() (ascii to integer) und strtok() (string tokenizer) sind Standard-Funktionen die man nachschlagen kann. Da gibt es auch noch anderen Funktionen für andere Datentypen wie float oder long
-.-
Was ist wenn ich nur Zahlen von 0 - 9 verwende? Könnte ich dann alles so machen mit int anstatt mit char vor den Variablen?
Da tun sich immer nur mehr und mehr Befehle auf die ich nicht kenne und mich darüber informieren könnte, irgendwann muss man doch auch mal auf einen grünen Zweig kommen, da bin ich ja noch Monate dran wenn ich alles Nachlese, und ich finde nicht mal eine richtige Erklärung zu atoi, nur 20 Forum Einträge, aber ich verstehe nicht was all die Klammern bedeuten darin.
Kann man das nicht einfach nur mit Zahlen so machen wie ich es oben hin geschrieben habe? Irgendwie mit var1 = var2 aber mit Array Variablen?
@ Tommy56
Ich habe den Link durchgesehen, aber ich sehe nur 100 Seiten Sonderzeichen, und die meisten Zeilen verstehe ich nicht. Wenn ich alle Zeilen mit Serial.print heraussuche finde ich das auch nicht heraus, und wenn ich selber lese komme ich spätestens beim Zeiger zum 2. o nicht mehr mit.
Ich weiß zwar nicht, wie Du da auf 100 Seiten Sonderzeichen kommst, aber egal. Du suchst ja nur Gründe (ich könnte auch Ausreden sagen), um nichts lernen zu müssen.
Dann wirst Du da auch nicht weiter kommen.
Ist Dein Google defekt, dass Du keine der 2.280.000 Ergebnisse zu atoi findet? Z.B. diesen hier.
verstehe ich nicht. Ich weis nicht wieso da const steht, auch nicht wieso char *string, wenn es doch zu int soll?? Ausserdem was ist den char jetzt? Eine Variable wie abc oder etwas wie int? Wieso der Stern am string klebend und nicht mit Abstand auch zwischen string?
Genau so mit fast allen anderen Zeilen auf der ersten Seite die du verlinkt hast, ich verstehe die Satzdarstellung nicht, oder die Wörter.
verstehe ich nicht. Ich weis nicht wieso da const steht, auch nicht wieso char *string, wenn es doch zu int soll?
Wenn dir solche absoluten Grundlagen nicht klar sind, wieso versuchst du dann selbst Routinen zu entwickeln um eine Datei einzulesen? Das sind einfach Dinge die bekannt sein müssen auch wenn du nicht weißt welche Funktionen du genau verwenden musst.
Das mag harsch klingen, aber ein gewisses Grundwissen muss vorhanden sein wenn man sowas macht. Wenn nicht musst du kleiner anfangen um es zu lernen
char* ist ein Zeiger auf einen char. In C sind Zeichenketten Null-terminierte Arrays aus char. Wenn irgendwo was von "C String" steht ist das gemeint. Nicht zu verwechseln mit der Arduino String Klasse (welche gerade diese Teilungs- und Konvertierungsfunktionen nicht hat)
Array-Variablen sind äquivalent zu Zeigern auf das erste Element. Wenn man also ein Array an eine Funktion übergibt hat man einen Zeiger als Parameter.
Deshalb gebe ich in meiner Funktion auch einen char* zurück um von außen Zugriff auf das lokale Array zu haben (Achtung: das geht nur mit static Variablen!)
const bedeutet einfach "konstant" und heißt dass man den Inhalt nicht verändern kann. Wobei es da bei Zeigern ein paar feine Unterschiede gibt (ob der Zeiger selbst const ist oder das worauf er zeigt. Oder beides). Das ist hier nötig weil String Literale automatisch const sind. Wenn man ein Literal an eine Funktion übergibt bei der der Parameter nicht const ist bekommt man eine Warnung
Wieso der Stern am string klebend und nicht mit Abstand auch zwischen string?
Also ich habe mir das überlegt, vielleicht setzte ich besser auf eine gute Serielle Kommunikation mit dem Raspberry Pi. Dort habe ich auch keine Probleme mit Text, und kann mit diesen Befehlen die ich kenne eigentlich (fast) alles machen was ich will.
Eine Frage noch, wenn ich 64 Bytes über die Serielle Kommunikation auslese die schon da sind, ist das dann schneller als wenn ich 64 Bytes von einer SD Karte auslese? Weil es so wie es aussieht im Ram gespeichert wird? Nur das warten bis alle Zeichen da sind geht lange?