Pages: 1 [2]   Go Down
Author Topic: Arduino steuert verschiedene SPI devices an  (Read 1045 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Faraday Member
**
Karma: 97
Posts: 3512
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, ich habs glaube ich gefunden:
http://arduino.cc/de/Reference/StringToCharArray

Code:
String str = "123";
char* cstring [str.length() + 1];
cstring[str.length()] = '\0';    \\ <---- ganz, ganz wichtig! C-strings sind Null-terminiert.
str.toCharArray(cstring, str.length());

Damit sollte man ein String Object in einen c-string umwandeln können und diesen dann mit atoi() in einen Integer:
http://www.cplusplus.com/reference/cstdlib/atoi/

Code:
int i = atoi(cstring);

Der Code ist nur zum Anreiz. Getest habe ich das nicht!

Ist sicher alles ein wenig kompliziert, aber das haben String-Operation so an sich.


EDIT:
Das ist die bessere Wahl:
http://arduino.cc/en/Reference/StreamReadBytesUntil

Damit kannst du bis zu einem Terminator direkt in ein char-Array lesen (den Puffer kann man z.B. auf 5 setzen, für 4 Ziffern + Null)! Wenn du dann deine Datensätze konstant lang machst, kannst du das immer 3-mal machen. Und dann atoi(). Lediglich beim letzten mal musst du abfragen was wirklich drinsteht und ob umgewandelt werden soll.

Ich würde daher auf die "Optimierung" mit der variablen Länge der Datensätze verzichten. Das ist mir auch erst eingefallen, nachdem ich deinem Ansatz gefolgt bin. Du hast dann ein paar Byte mehr auf der SD-Karte, aber der Code ist kürzer und läuft auch wesentlich schneller. smiley
« Last Edit: July 05, 2013, 04:33:26 am by Serenifly » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 56
Posts: 2979
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Abgesehen davon , dass man String Objekte nicht braucht, und alles einfacher ist, wenn man gleich mit char array arbeitet, ...

- brauchst du nur einen char * cstring und nicht ein ganzes Array davon
- ist es meist besser, den Speicherplatz nicht dynamisch auf dem Stack durch eine lokale Variable, sondern statisch zu belegen.
- sowohl getByes wie toCharArray fügen eine Endekkennung an, und schneiden zu lange Strings ab, so dass die 0 noch Platz hat.
- leider ist der Zugriff auf den internen buffer ( der auch eine Endekennung enthält ) protected.
   ( Wenn ich nicht prinzipiell gegen String wäre, könnte ich eine abgeleitete Klasse erfinden,
      die das umkopieren erspart und gleich Zugriff auf den buffer erlaubt...  smiley-wink   )

Sereniflys Beispiel sollte also z.B. so aussehen:

Code:
String str = "123";
static char cstring [10];  // Platz für max 9 Zeichen
str.toCharArray(cstring, 10);  // sizeof(cstring)   geht auch, statt 10 hier fest einzutragen

Serial.print(cstring);  // sendet 3 Zeichen :    '1' , '2' , '3'

Logged

Offline Offline
Faraday Member
**
Karma: 97
Posts: 3512
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops. smiley

Ja, das mit char-arrays ist klar besser. Auf die String-Objekte bin ich nur gekommen weil ich erst blind dem Modell gefolgt bin wo die Länge der Datensätze variabel ist. Das ist so ein typisches Beispiel wo man meint etwas zu sparen und sich dann später nur Ärger einhaltet weil die Behandlung der Daten wesentlich komplizierter wird (das hatte ich auch letztens wo ich meinte mehrere Variablen in verschiedene Nibbles und Bits eines Bytes packen zu müssen).

Das wäre natürlich auch so mit c-strings gegangen, aber der Code wäre dann noch viel weniger verständlich. Wie ich es dann fertig geschrieben hatte, ist mir eingefallen, dass es wesentlich einfacher ist immer drei Zeichen zu schreiben und einen deaktivierten Wert durch einen Buchstaben zu kennzeichnen.

Das die Strings gleich Null-terminiert sind war aus der Dokumentation nicht ersichtlich. Wäre sinnvoll dass mal reinzuschreiben smiley
« Last Edit: July 05, 2013, 04:37:12 am by Serenifly » Logged

Offline Offline
Sr. Member
****
Karma: 2
Posts: 272
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo  und zwar geht es wegen dem ansteuern der SPI geräte, versuche immer noch eine universelle lösung bzw eine allgemeine lösung zu finden um verschiedene SPI-Devices anzusteuern, doch das problem ist, dass einige 8-bit werte senden, die anderen 12 bit und einge brauchen 2 parameter die anderen 3.
Kennt jemand von euch einen ausweg?

Bin langsam am verzweifeln.
Die Sache ist die, dass das SPI.Protokoll leider keinen standard hat und das für jedes gerät immer anders ist.

Logged

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

SPI-Schnittstelle ist schon Standardisiert (mehr oder weniger).
Was nicht Standart ist ist sind die Daten, die an die verschiedenen Devices gesendet werden.  Wie kannst Du denken daß Die Ansteuerung 2 verschiedener Devices die gleichen Daten erfordert.
Wenn Du mit dieser Logik kommst dann ist weder USB noch RS232 noch Centronics, noch RS485 Standardisiert.

Es ist das gleich wie wenn Du in eine Pizzeria, in den Chinesen nebenan oder in eine Frittenbude gehst und darauf bestehst mit den gleichen Worten was zu essen bestellen zu können. Schon bem Sprudel ist Schluß.

Grüße Uwe
Logged

Offline Offline
Faraday Member
**
Karma: 97
Posts: 3512
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es geht hier immer noch darum Datensätze auf einer SD-Karte zu speichern, oder?

Du fügst eine Art Definitions-Zeichen/Parameter ein, der die Art des Devices anzeigst. Das kommt ins erste Feld eines Datensatzes. Dann weiß du was in den darauf folgenden Feldern steht.

z.B. sähe ein Datensatz dann so ähnlich aus:
Device Kennung  , Wert (Byte 1) , Wert (Byte 2) , Parameter 1 , Parameter 2 , Parameter 3

Nicht verwendete Parameter werden nicht ausgewertet und z.B. auf '0' gesetzt. '0' ist wahrscheinlich besser, da du dann auch atoi() darauf ausführen kannst.
"Wert (Byte 2)" ist für die anderen 4 Bit von 12-Bit Werten

Du kannst auch über die Device Kennung wissen wie viele Felder folgen. Damit wäre wieder eine variable Länge der Datensätze möglich. Aber wie gesagt SD-Karten haben mehrere GB. Daher hier nicht unnötig optimieren! Das macht nur den Code komplizierter. Wenn die immer die gleiche Länge haben kann man einfach n-mal ReadBytesUntil(',') machen und gut ist.

Das kann man dann gut in einem struct darstellen:
Code:
typedef struct
{
uint8_t deviceKennung;
uint8_t wert1;
uint8_t wert2;
uint8_t parameter1;
uint8_t parameter2;
        uint8_t parameter3;
} record;

deviceKennung sagt dir dann welche Variablen du auswerten musst. Da schreibst du dann die Werte von der SD-Karte rein und kannst sie wo anders im Programm verwenden.

z.B. so:
Quote
void loop()
{
   record rec;
   getDataFromSD(&rec);
}

void getDataFromSD(record *rec)
{
    //hier von der SD Karte lesen und rec beschreiben
}

Falls die Methode das struct nicht schluckt, es statt dessen als "struct record{ };" definieren (ohne typedef) und bei der Methode "getDataFromSD(struct record *rec)" machen (ohne typedef muss man dann jedesmal "struct" vor "record" schreiben). Damit hatte ich schon Probleme.
« Last Edit: July 06, 2013, 08:31:47 am by Serenifly » Logged

Offline Offline
Sr. Member
****
Karma: 2
Posts: 272
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi bei mir geht es um die gui, die dem arduno die Parameter sendet.
Das problem is die gestaltung, bzw wieviel felder ich als Parametereingaben hinzufüge, damit es allgemein für alle devices in SPi anwendbar ist.

Hat da jemand eine idee? Sorry falls ich mich vorhin unklar ausgedrückt habe.
Logged

Offline Offline
Faraday Member
**
Karma: 97
Posts: 3512
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gleiche Sache im Prinzip. Du kannst z.B. als erstes eine Listbox machen um die Art des Devices auszuwählen (darüber hat man gleichzeitig die deviceKennung). Und je nachdem zeigt du andere Felder an. Felder kann man z.B. deaktivieren damit sie ausgegraut sind, oder eventuell mit Methoden wie show/hide auch gar nicht erst anzeigen. Das kommt auf die Programmiersprache an.
Logged

Offline Offline
Sr. Member
****
Karma: 2
Posts: 272
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke dir, sowas habe ich gebraucht smiley-grin.
Ja dann kann ich die parseInt funktion doch beibehalten, wenn das mit dem EIn und ausblenden klappt smiley-grin.
Logged

Pages: 1 [2]   Go Up
Jump to: