Go Down

Topic: Serielle Kommunikation: String Maskieren (Read 3749 times) previous topic - next topic

sunnyboi19

Heyho Community.

Hoffe ihr könnt mir weiterhelfen. Als Arduino Neuling, hab ich zu folgendem noch keine richtigen Infos bekommen:

Ich möchte einen String an den Arduino per Serieller Schnittstelle senden, die mehrere Informationen enthällt.
Ziel ist es meine RGB-Strip per PC steuern zu können und wenn ich z.B. 255255255 als str an Arduino sende, dass er mir die ersten 3 Zeichen in Var1(rot), die nächsten 3 in Var2(grün) und.... wer hätte es gedacht die letzten 3 in Var3(für Blau) speichert.


Jemand eine Idee?
schonmal Danke im Vorraus ;)

TERWI

... ja ich. Arbeite grade an einen universellem Protokoll zur Datenübergabe. Leider noch nicht wirklich fertig ...
In den nächsten Tagen schreibe ich dazu hier mal ne 'Vorstellung'.
Wenn du noch so lange Geduld hast ....
... ansonsten helfen dir andere logo hier auch weiter.
To young to die - never to old for rock'n roll

Eisebaer

hi,

das ist ein falscher ansatz, gerade in diesem fall, und gleich ist Dir klar, warum.

Du willst werte zwischen 0 und 255 übergeben, also jeweils ein byte (das werte zwischen 0 und 255 annehmen kann).

die serielle schnittstelle kann NUR BYTES übertragen. wenn Du strings übergibst, zb "255", sendest Du 3 byte, also 2, dann 5, dann nochmal 5 (bzw. die ASCII-entsprechungen).

dazu wandelst Du einen wert, den Du sicher als byte hast, in einen string, sendest die 3 bytes und wandels danach wieder in einen byte-wert. umständlich und uneffizient.

sende gleich das byte, empfange das byte und schick das byte an den strip, der kann nämlich mit einem string auch nichts anfangen.

befreie Dich davon, einen wert als "geschriebene zahl" zu sehen, das ist nur eine krücke, die aber behindert.

gruß stefan

sunnyboi19

Ok haste recht, ABER MEIN PROBLEM:

Wollte es so lösen, da ich es mit der gegenseitigen Syncronisation nicht hinbekomme. Muss ja so sein:

PC sagt, ich sende Rot. Arduino empfängt Rot. In der Zwischenzeit muss PC ja warten bis empfang erfolgreich war. Dann Muss Arduino PC sagen, kann weiter gehen, schick mir Grün... usw.

Arbeite mit Visual Studio 2012, denke wird ja wohl mit nem Timer gelöst, daher wollte ich es eben über die Stringkette lösen.

Serenifly

#4
Jul 22, 2013, 09:18 pm Last Edit: Jul 22, 2013, 09:54 pm by Serenifly Reason: 1
Handshaking brauchst du hier nicht. Beide Seiten haben Empfangspuffer. Das heißt du musst nicht sofort die Daten auswerten, sondern kannst sie auf einmal schicken. Das wäre bei den paar Bytes totaler Overkill.

Abgesehen davon, solltest du dir in .NET mal EventHandler ansehen:
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx

Das ist im Prinzip eine Methode, die automatisch aufgerufen wird wenn Daten ankommen.

Das gibt es auch beim Arduino:
http://arduino.cc/en/Tutorial/SerialEvent

Quote
denke wird ja wohl mit nem Timer gelöst, daher wollte ich es eben über die Stringkette lösen.

Das hat nichts miteinander zu tun. Wenn du alle x Sekunden Daten schicken willst, spielt es keine Rolle welche Form diese Daten haben. Damit handelst du dir nur Probleme ein, da String-Handling auf dem Arduino relativ kompliziert ist.

In C# hast du dir mit den Wrapper-Klassen gleich ein Byte aus einem String gebastelt:
Code: [Select]

byte val = Byte.Parse(str);


Falls du VB verwendest gibt es da auch ähnliches.

TERWI

@sunnyboi19
Wenn du etwas Geduld / Zeit hast .... ich arbeite grade mit Volldampf an genau so etwas.
To young to die - never to old for rock'n roll

michael_x

#6
Jul 23, 2013, 10:51 am Last Edit: Jul 23, 2013, 11:21 am by michael_x Reason: 1
Wenn du Texte schickst, statt Stefans Binär-Vorschlag, erleichtert es das Leben ( genaugenommen die Synchronisation der zwei Maschinen) gewaltig, wenn einige wenige Steuerzeichen drin sind: z.B.
255;001;123<NL>  

Der Arduino liest dann z.B. alles bis zum NewLine Zeichen
und ersetzt die Trennzeichen jeweils durch eine Ende-Kennung 0.

Code: [Select]

int c; char buf[10];
if (Serial.available() >=9)
{
 int i = 0;  
 while ( ( c=Serial.read() ) != '\n' ) buf[i++] = c;

 buf[3] = buf[6] = buf[9] = 0;
 int i1 = atoi(buf+0);  // wandeln der Teilstrings
 int i2 = atoi(buf+4);
 int i3 = atoi(buf+7);
 // Auswerten ...
}

[Nachtrag:]Editiert, immer noch schneller aber ungetestet ;), vielleicht wird Terwi's Lösung besser und/oder einfacher verständlich

TERWI

#7
Jul 23, 2013, 12:34 pm Last Edit: Jul 23, 2013, 12:42 pm by TERWI Reason: 1
.... prinzipiell genau so was ! Nur etwas 'aufgeblasener" (na ja) als LIB zum universellen Einsatz.
Ein paar Worte vorweg dazu:
Ein "Kommando" kann bei mir enthalten:
- Eine Checksumme über alles (für solche, die Sicherheit wollen - abschaltbar)
- Selbstdefinierbare Zeichen als LeadIn und LeadOut (z.B. zum unverwechselbar machen - abschaltbar)
- Einen Integer-Wert z.B. zum identifizieren eines bestimmtes Shields (oder was anderes - abschaltbar)
- Dito für eine bestimmte Funktion (mit SwitchCase auszulesen ? - abschaltbar)
- Ein bestimmtes Kommando für irgendwas (wie Funktion - abschaltbar)
- Ein Integer (NumberValue), welcher entweder einen Wert selbst oder die Größe einer Werte-Liste bestimmt. (Fest !)
- Optional danach eine Reihe von tintegern als Werte-Liste

Diese ganze Reihe von integern wird durch ein frei konfigurierbares Zeichen getrennt (Vorgabe ein Komma).
Am Ende steht wieder ein frei konfigurierbares "Kommando-Ende" Zeichen. (hier CR)
Das sähe dann z.B. komplett so aus:
Quote
CRC, ##, Shield, Function, Command, NumberValue, Val1, Val2, ..., ** (CR)

oder auch simpelst einfach nur NumberValue als einzelne Zahl.

Eine interne Funktion prüft das ganze je nach eingeschalteten Option auf Plausibilität und ggf. die Checksumme
und gibt dann die Werte Shield, Function, Command, NumberValue ggf. mit einer gefüllten Werte-Liste an eine im Sketch zu definierende CallBack-Funktion weiter.
Dort kann der User dann selbst auswerten wie er lustig ist ....

Diese CallBack-Funktion erwartet einen Rückgabewert in Form eines Integer.
D.h., wenn der User selbst in seinen Funktionen ein "Ergebnis" oder Rückgabewert definiert, wird dieser automatisch zusammen mit den Kommandos als Bestätigung der Sendung zurückgeschickt. Mit vertauschtem LeadIn / LeadOut und allen eingestellten Optionen. Also etwas so komplett:
Quote
CRC, **, Shield, Function, Command, Result, ## (CR)

oder auch eben simpelst nur Result.

Damit erhält man dann auf ein gesendetes Kommando automatisch ein Echo und kann die ordnungsgemäße Funktion prüfen oder auch einen Wert abrufen.
Senderseitig wartet das (Beispiel-) Programm max. 500ms (einstellbar) auf dieses Echo.

Selbstverstämdlich kann man die "Echo-Funktion" auch z.B. in einer Interrupt-bedingten Routine einbinden und sich Ereignisse / Werte zeigen lassen.
Senderseitig wird ein gesendetes Kommando ohne direkte vorherigen Aufruf als "Event" interpetiert.

Praktisch kann man damit auch Zeichenketten (mit begrenzter Länge ?) übertragen. Dazu muss man die einzelnen Zeichen zuvor senderseitig in eine Werte-Liste zusammendröseln (je Integer 2 uchar) und auf dem Arduino entsprechend wieder auseinanderpulen.
Umgekehrt geht das natürlich auch .... wenn man will.

So viel zunächst mal als vorab-Info.
Ich hoffe ich hab was taugliches für die Allgemeinheit bis zum WE fertig.
Da gibt es dann einen Test-Sketch, die entsprechende LIB und ein Steuerprogramm für WinDoof zum sofort ausprobieren dazu.

Hat jemand vielleicht nen passend klingen Namen dafür ?

To young to die - never to old for rock'n roll

TERWI

... Steuerprogramm ist fertig. Richtig schick geworden.
Noch ein wenig an der LIB und dem Demo-Sketch fummeln ...
To young to die - never to old for rock'n roll

Go Up