Hallo,
ich verwende das STI100 USB Interface (VNC1L Chip). Soweit funktioniert
alles, ich kann die Daten auf den Stick schreiben und Lesen. Aber es
gibt ein Problem.
Die Daten (jeweils ca 400 byte) werden mit 20 Hz, also alle 50ms
geschrieben. Ich benutze den /CTS Pin, der signalisiert wann neue Daten
geschrieben werden können. Das Problem ist nun, dass das Ding
anscheinend zu langsam schreibt, sprich der /CTS Pin ist teilweise nach
50ms noch nicht wieder auf LOW, so dass keine neuen Daten angenommen
werden.
Habe es mit unterschiedlichen USB Sticks probiert - das Verhalten bleibt
gleich. Wenn ich den Pins nicht auswerte und einfach drauf los schreibe,
werden teilweise vorhergehende Datensätze im Buffer überschrieben.
Hat jemand eine Idee, wie man das lösen könnte? Noch einen externen
Buffer vorschalten?
Danke!
Sorry, ich habe mich verschrieben - es ist natürlich RTS. Den Thread
kenne ich schon, aber habe nichts gefunden, was mir helfen würde.
Kann es sein, dass die "OPW" und "CLF" Befehle so langsam sind? Ich
öffne und schließe die Datei so vor/nach jedem Schreibvorgang
Die Baudrate ist bei 115.200, das gleiche Verhalten bei 57.600.
"D:\>" warte ich nicht ab, ich werte lediglich den RTS Pin aus.
Oder kommt der Prompt etwa vor dem LOW auf dem Pin?
>Die Baudrate ist bei 115.200, das gleiche Verhalten bei 57.600.>"D:\>" warte ich nicht ab, ich werte lediglich den RTS Pin aus.
Das reicht nicht aus. RTS-Pin Auswertung ist einige Ebenen tiefer
angesetzt und betrifft nur den Buffer. Nur die Prompt-Auswertung liefert
zuverlässig ein Ergebnis, wenn ein Befehl akzeptiert und ausgeführt
wurde. Erst dann darf weiter im Protokoll verfahren werden.
Aber würde es mein Problem dann nicht weiter verschlimmern? Wenn schon
alleine mit der RTS-Pin Auswertung die Datenrate nicht eingehalten
werden kann, dann wird es bei der Prompt-Auswertung eigentlich noch
langsamer, oder?
Würdest du mir erklären wieso? Irgendwie komme ich da logisch nicht
hinterher: Kann es also passieren, dass das Interface schon neue Daten
annehmen kann, obwohl der RTS Pin noch etwas anderes signalisiert?
Betrachte das UART-Interface unabhängig von der Befehlsebene. Der
serielle Datenstrom wird über die Handshakesignale geregelt (VNC1L-FIFO
ist nicht sehr groß!). Die eigentliche Kommunikation mit den
Disk-Commands. Die meisten Commands liefern an Ende ein Prompt, damit
man weiß, dass der Befehl ausgeführt wurde. Die Ausführungsdauer eines
Befehls ist von vielen Faktoren abhängig, wie zB. dem USB-Sticktyp, der
Formatierung, RW-Geschwindigkeit, Abnutzung usw.
Im Usermanual zur Firmware steht vieles nützliches zur Kommunikaton
drin.
Lade Dir das mal runter und beschäftige Dich damit;-)
http://www.vinculum.com/documents/fwspecs/UM_VinculumFirmware_V205.pdf
Da ist das Manual, meinst du eine bestimmte Stelle?
Mir ist immernoch nicht klar, warum man sich an die Prompt-Ausgabe
halten soll. Ich bin immer davon ausgegangen, dass der RTS Pin richtig
signalisiert, wann gesendet werden kann.
Der VNC1L hat einen FIFO-Buffer. Wenn der voll wird, zeigt das der VNC1L
durch setzen von RTS an.
Der eigentliche Prozessor in VNC1L arbeitet auch nur den FIFO ab,
kümmert sich aber nicht um die Ebene der UART-Kommunikation. Er geht
immer davon aus, das die Daten im FIFO gültig vorliegen.
Ohne die Prompt-Auswertung kommt nichts zuverlässiges raus. Vielleicht
klappt es mit einen bestimmten Stick auch mit großen DELAYs nach jedem
Befehl, bei einen anderen Stick muss es aber nicht mehr funktionieren.
Die gesamte Commando-Ebene basiert auf der PROMPT-Bestätigung.
Nur mal am Rande: Der VNC1L ist nicht als Einsteiger-Projekt geeignet.
Dafür sind schon einige grundsätzliche Schnittstellen- und
Mikrocontroller-Erfahrungen erforderlich.
Hallo Matthias,
ich glaube du verstehst mich falsch.
Die Befehlsebene funktioniert bei mir einwandfrei.
Wenn die Daten mit WRF geschrieben werden, wird zwischendurch immer
wieder der RTS Pin gesetzt. Dieser Vorgang dauert mit nur 400 bytes
schon über 50ms, was für meine Anwendung zu langsam ist.
Hier sind die möglichen Transferraten:
http://www.ftdichip.com/Support/Documents/AppNotes/AN_112_VNC1L%20Data%20Transfer%20Speeds.pdf
Riesige Geschwindigkeiten kannst Du jedoch nicht erwarten. Um Deine 400
Byte seriell mit 115200 Baud zu senden, vergehen schon theoretisch gut
35ms, ein kontinuierlicher Transfer, ohne jede Verzögerung
vorausgesetzt. Also sind Deine 50ms schon zielmlich realistisch.
Höhere Baudrate, Parallel-Interface.
20x pro Sekunde war auf einen USB-Stick schreiben, ist auch nicht ideal.
Macht der nicht lange mit.
Alternativ: Daten in einem Datenflash oder SRAM sammeln und nur in
größeren Abständen auf Stick schreiben.
>> Alternativ: Daten in einem Datenflash oder SRAM sammeln und nur in>> größeren Abständen auf Stick schreiben.
Das wäre eine gute Alternative. Nach welchen Bausteinen könnte ich mich
umschauen?
Habe noch was vergessen:
Was ich schon ausprobiert habe: ich sammle meine Daten in einem String
und schreibe nur noch 5x pro Sekunde, jeweils etwa 1kB.
usb schrieb:> Was ich schon ausprobiert habe: ich sammle meine Daten in einem String> und schreibe nur noch 5x pro Sekunde, jeweils etwa 1kB.
18000 Schreibvorgänge / Stunde ...
Immernoch sehr viel für einen Stick.
Och das wird nur an einem Rennfahrzeug benutzt, pro Wochenende ist es ca
3 Stunden unterwegs. Im Jahr sind es vielleicht 10 Wochenenden, also ca
30-40 Betriebsstunden. Wenn dann 2x Sticks pro Jahr fällig sind, kann
ich damit leben :)
Viel wichtiger wäre die Frage, die man die Daten buffern könnte, damit
ich letzendlich alles schreiben kann. Würde es etwas bringen die
Baudrate noch weiter zu steigern?
... Ich öffne und schließe die Datei so vor/nach jedem Schreibvorgang
...
Verstehe ich das richtig, 20 mal pro Sekunden 400 Bytes schreiben und
jedesmal die Datei offnen & schließen?
Da ist auch was dran - spricht eigentlich nichts gegen. Ich weiß nur
nich aus dem Kopf, ob die geschriebenen Daten verloren gehen, wenn die
Versorgungsspannung abgeschaltet wird und die Datei nicht geschlossen
wurde.
Du könntest dir auch überlegen, ob Du so viele Daten brauchst, oder ob
man hier eine Reduktion durch eine Vorauswertung erzielen kann.
20 mal pro Sekunde 400 Bytes erscheinen mir für ein Modellrennauto recht
viele Daten.
Wenn Du hier Werte loggst wie z.B. Akkuspannung, Temperaturen etc, dann
reicht dir dafür auch locker 1 Messwert pro Sekunde.
Ach so nochwas zur Datenreduktion, wie speicherst Du die Daten? Als
Binärwerte oder als String? Auch hier kann man mit binären Daten
deutlich die Menge reduzieren.
Ne, das ist kein Modellrennauto sondern ein Rennmotorrad in groß :)
Die Daten sind eigentlich schon recht stark gefiltert - es werden alle
200ms der GPGGA und GPRMC Strings vom GPS Sensor und alle 50 ms Werte
wie Drehzahl, Reifentemperaturen, Gasgriffstellung usw gespeichert.
1x pro Sekunde wäre ggf zu langsam, um beispielsweise Stürze
nachvollziehen zu können oder das Verhalten von 2 Fahrer zu vergleichen
(Bremspunkt, Rausbeschleunigen).
Die beiden GPS Strings ergeben zusammen etwa 400byte alle 200ms, die
restlichen Daten ergeben etwa 500 byte (grob aus dem Kopf). Damit werden
etwa 900byte, oder aufgerundet 1000 byte alle 200ms, also 5mal pro
Sekunde geschrieben.
Hmmm ich speichere die Daten als String, entweder stehe ich auf dem
Schlauch oder verstehe Dich falsch - wenn ich zb die "15" speichern
will, wären das 2 Stellen als String aber 4 Stellen als Binärzahl, die
übertragen werden müssten ("1111")
Hi
>wenn ich zb die "15" speichern>will, wären das 2 Stellen als String aber 4 Stellen als Binärzahl, die>übertragen werden müssten ("1111")
Nein.
15 als String: $31,$35, evtl. noch $00
15 binär : $0F
MfG Spess
Die GPS Strings geben 400 Bytes Wahnsinn!
Im Prinzip ist das doch nix anderes als z.B. bei UTM Koordinaten
"32 U 0528348
UTM 5396972"
Wie zum Geier verbrätst Du da 400 Bytes??????
Und auch diese UTM Koordinaten lassen sich deutlich schrunpfen indem man
nur die Werte binär als 4, 6, oder 8 Byte Integer ablegt.
Ja, ich speichere die noch komplett ab. Vielleicht sollte ich da mal
anfangen und nur die wirklich relevanten Daten vor dem Speichern schon
extrahieren.
Wie kann man denn die Werte direkt als Binärdaten rausschreiben?
Ich muss ja die Daten auf den UART rausschicken, und wenn eine Variable
"i" beispielsweise den Wert 15 hat, dann wird "print i" 15 als String
rausschicken.
Selbst wenn Du die weiter als String abspeicherst. Eine Koordinate
(sehen wir von der Höhe über NN ab, die ist eh nicht so genau) besteht
unabhängig vom verwendeten Koordinatensystem aus einem Hochwert und
einem Rechtswert.
bei UTM hast Du zusätzlich die Region z.B. "32U".
Bei UTM haben die beiden Werte dann noch 7 Stellen. Macht 117 Bytes wenn
man auf irgendwelche Trennzeichen wie Blanks oder Kommas verzichtet. Das
ist weniger als 1/20 deiner 400 Bytes!
Die beiden 7 stelligen Zahlen könntest Du als long Wert abspeichern (C
Funktion alol()). Dann hättest Du statt 7 Bytes ASCII nur 4 Bytes für
den Long Wert. Dazu musst Du aber die Datei binär öffnen und binär
schreiben. Und Du kannst die Werte nicht mehr einfach im Texteditor
sehen.
hast Du z.B. Koordinaten in Winkel, Minuten, Sekunden und
Dezimalsekunden dann sähe es vieleicht so aus
N34 25'36.5'' W130 56'43,1''
Auch das sind trotz der unnötigen Blanks und Minuten bzw. Sekunden
Kennzeichen weniger als 30 Bytes.
Ist also noch massig Optimierungspotential, auch wenn Du weiter einfach
lesbare BCD Zahlen speicherst.
Weitere Optimierungsmöglichkeit:
Da deine Rennstrecke wohl nicht größer als 10 km in NordSüd bzw OstWest
Richung sein wird, könntest Du Dich auf die letzten 5 Stellen (Auflösung
1m) beschränken und hättest 10 Bytes als Text (BCD codiert) oder 4 Bytes
als 2 mal Integer Werte für ein Koordinaten-Datensatz.
Die Absoluten Koordinaten könnte man einmalig zu Beginn der Messung
abspeichern, und alle weiteren Werte relativ dazu sehen.
Das wäre mal locker (fast) Faktor 100 gespart :-)