Hallo, Ich muss einen FT230X mit einer half-duplex Schnittstelle (RS485) ansteuern. Dazu würde ich Python mit pyserial verwenden. Ich entwickle unter Linux, aber das Programm soll auch unter Windows laufen. Hinter dem FT230X sitzt ein AVRtiny der als Adapter für eine proprietäre Schnittstelle dient. Dafür soll ich die SW schreiben. Der FT230X muss einzelne Blöcke (2-20 Bytes lang) senden. Da es auch Blöcke gibt, die keine Antwort erwarten, die aber eine Pause von ca. 1 Byte dazwischen benötigen, dachte ich dafür kann man ja den CTS# Eingang des FT230X benutzen. Um zu erkennen, dass ein neuer Block kommt soll TXDEN verwendet werden. Der muss also auch nach jedem Block zurückgesetzt werden. Sobald der TXDEN inaktiv ist, wird also der CTS# des FT230X gesetzt um zu verhindern, dass neue Daten kommen, bevor die Pausenzeit vorbei ist. In der FAQ bei FTDI steht aber bezüglich des CTS# Eingangs: If CTS# is logic 1 it is indicating the external device cannot accept more data. the FTxxx will stop transmitting within 0~3 characters, depending on what is in the buffer. Die Frage ist also, wie ist der Buffer des FTDI Chips aufgebaut? Was muss darin stehen, dass immer sofort gestoppt wird, und wie generiere ich das mit Python? Entspricht der gesamte Buffer nur einem Block, oder können mehrere Blöcke im Buffer stehen? Da ich auch TXDEN verwende hat das wohl auch Auswirkungen darauf. Wenn also mehrere Blöcke im Buffer stehen können, wird dann auch der TXDEN nach jedem Block deaktiviert? Und wenn ja, wie lange? Und wenn nicht, wie sorge ich dafür dass immer nur ein Block im Buffer steht, so dass auch der TXDEN inaktiv wird? Wenn immer nur ein Block im Buffer stehen kann (entspricht einem pyserial write() Aufruf) muss der USB Treiber ja immer warten, bis alle Bytes dieses Blocks gesendet sind. Wird das eventuell so gemacht? Bei FTDI habe ich schon gefragt, aber noch keine Antwort. Aber vielleicht hat hier ja jemand Erfahrung mit RS485 und FTDI. Das ganze soll natürlich möglichst hohe Übertragungsraten erreichen. Die proprietäre Schnittstelle schafft ca. 3000 Byte/s, da sollte man möglichst nah ran kommen. Soweit ich weiß läuft USB mit 1KHz, da hängt es dann von der Blockgröße ab, was man erreicht. Im Augenblick habe ich noch keine HW zum Testen, das dauert wohl noch ein paar Wochen. Aber dann soll es schon SW für den AVR geben. Wie immer halt. Danke schon Mal, VG
> muss der USB Treiber ja immer warten, bis alle Bytes dieses > Blocks gesendet sind. Was der USB-Treiber macht haengt natuerlich davon ab wie er programmiert wird. Das ist halt der Nachteil wenn du dir das Leben einfach macht mit Python wo doch alles fertig ist. Da hast du halt keinen Einfluss drauf. Aber den Source des Treiber wirst du doch trotzdem lesen koennen. > Soweit ich weiß läuft USB mit 1KHz, da hängt > es dann von der Blockgröße ab, was man erreicht. Das war bei USB1.0 so. Ab USB2 sollte das bei 1/8ms liegen. Aber ja, das Geheimnis hoher Geschwindigkeit liegt in der Blockgroesse, und auch wie der Treiber darauf reagiert wenn du ihm z.B nur 1Byte schickst. Wartet er dann auf 63 weitere? Hat er einen Timeout und sendet irgendwann einfach trotzdem. Das haengt dann von deinem Treiber und eventuell dessen Konfiguration ab. Vanye
Beim FT230X steht im Datenblatt USB 2.0 Full Speed compatible. Das wäre dann wohl 1ms Zyklus. Unter Linux habe ich mal gesucht, was pyserial so macht. Soweit ich das gesehen habe ruft es Funktionen aus termios auf. Das gehört zum Linux System. Da habe ich auch Mal reingeschaut, aber es dann nicht weiter verfolgt. Darum geht es ja erst Mal nur sekundär, zuerst brauche ich Mal die Info über den FT230X, also was muss ich am USB senden, dass der FT230X den TXDEN so ansteuert, dass es meiner Blockgröße entspricht, und wie kann ich verhindern, das der nächste TXDEN zu schnell kommt (dafür soll der CTS verwendet werden). Von FTDI habe ich dazu nichts gefunden. Inzwischen habe ich auch Antwort von FTDI, die verweisen aber nur auf Dokumente die ich schon kenne, die aber meine Fragen nicht beantworten. Und dann sagen sie noch, ich solle es mit einer HW von ihnen testen. Das sieht dann so aus als wollten sie die Info nicht herausgeben, oder viel schlimmer, dass sie die Info gar nicht haben (Der Entwickler ist nicht mehr in der Firma). VG
Georg P. schrieb: > Wenn immer nur ein Block im Buffer stehen kann (entspricht einem > pyserial write() Aufruf) Wenn der FT230 einigermaßen clever gebaut ist enthält er einen großen Ringpuffer, der mit jedem USB-Transfer weiter aufgefüllt wird. Die Ausgabe-Blockgröße hätte dann also relativ wenig mit der Struktur der write() -Aufrufe zu tun. Mit einem USB-fähigen Mikrocontroller wär das ziemlich einfach umzusetzen, auch so dass es unabhängig vom Timing des PC ist. Mit Emulation eines COM-Port (CDC-ACM) oder ohne. Muss es unbedingt ein ATtiny sein?
Hallo, Aber irgendwie muss der FT230X ja den TXDEN für die RS485 ansteuern, dazu braucht er eine Info, wann er mit dem Senden fertig ist. Und wie genau er das macht ist mir nicht klar. Wenn es ein Ringbuffer ist, wird der TXDEN also erst inaktiv, wenn er leer ist? Ein anderer Controller mit USB ist auch möglich, ich habe schon Mal einen PIC18 dazu verwendet. Mit dem gab es aber Probleme wenn er mehrere Tage lang durch lief, irgendwann fing die UART dann an Daten zu schicken, die um ein Bit versetzt waren. Da ging dann gar nichts mehr. Von den AVRs gibt es da ja nicht viel Auswahl. Im Endeffekt bleibt nur der, der auch bei den Arduinos drauf ist. Außerdem war die Idee, dass man den AVR auch weglassen kann, damit man nur den FT230X mit dem proprietären physikalischen Interface dran verwenden kann. Aber dann halt nicht mit dem selben, auch proprietären, Protokoll. VG
Georg P. schrieb: > Wenn es ein Ringbuffer ist, wird der TXDEN also erst inaktiv, wenn er > leer ist? Das klingt sehr plausibel denke ich. Es gibt jede Menge Controller mit USB-Schnittstelle. Viele Cortex-M haben das, z.B. die meisten STM32. Sogar auch die ESP32S3. Für die STM32 spricht dass es gute Freeware Tools gibt. Ist das RS485 Protokoll denn fix? Kannst du nicht den Paketen ihre Länge voran stellen? Dann kannst du auf dem AVR problemlos die einzelnen Pakete unterscheiden und es ist egal, ob dazwischen das TXDEN aus geht oder nicht.
> Ein anderer Controller mit USB ist auch möglich, ich habe schon Mal > einen PIC18 dazu verwendet. Sowas ist eigentlich die intelligentere Loesung weil du dein Protokoll kennst und dann entsprechend Nachrichten orientiert handeln kannst. > Mit dem gab es aber Probleme wenn er mehrere > Tage lang durch lief, irgendwann fing die UART dann an Daten zu > schicken, die um ein Bit versetzt waren. Oh..du hast also einen Programmierfehler und anstatt den zu finden und zu beheben wechselst du die Hardware? Vanye
Hallo, Wäre schön gewesen, wenn es ein SW-Fehler gewesen wäre. Ich habe ewig gesucht und nichts gefunden was die Daten, die die UART ausgibt erst nach mehreren Tagen Betrieb um ein Bit verschiebt. Das Bit was gefehlt hat war dann im nächsten Byte. Ich habe den PIC18 dann durch ein FTDI Modul ersetzt, dann ging es. Ich hatte den PIC probiert, weil ich noch Portpins benötigt habe, die über USART gesetzt werden sollten. Das ging mit dem FTDI natürlich nicht, aber er hatte immerhin Portpins, allerdings werden die über USB angesprochen. Aber darum geht es hier nicht. Sondern um das Timing von TXDEN und CTS des FT230X. VG
Niklas G. schrieb: > Ist das RS485 Protokoll denn fix? Kannst du nicht den Paketen ihre Länge > voran stellen? Dann kannst du auf dem AVR problemlos die einzelnen > Pakete unterscheiden und es ist egal, ob dazwischen das TXDEN aus geht > oder nicht. Es läuft physikalisch nur über eine Leitung, also RS485. Das ist fix. Das Problem ist nicht, dass der TXDEN dazwischen weggeht, sondern, dass er das nicht macht. Dann ist zwischen zwei Blöcken keine Pause von ca. 1 Byte. Die wird aber benötigt. Die Frage ist also, wie generiere ich diese Pause, wenn die PC-Software nicht auf eine Antwort warten muss und somit sofort den nächsten Block sendet. Selbst wenn ich dazwischen auf der PC-Seite 1 Byte warte (ca 300µs) ist ja nicht garantiert, dass der Buffer des FT230X schon leer ist. Der FT230X könnte ja noch gar nicht alles gesendet haben, und dann hängt er es an den Ringbuffer und der TXDEN geht nicht weg. Für die Pause sollte der AVR über den CTS# Eingang des FT230X sorgen. Da die Blöcke ohne Antwort auch nur 2 Byte haben können, beim FT230X aber steht, dass es bis zu 3 Byte dauern kann bis der Sender stoppt, geht das wohl so nicht. Der AVR muss auch zuerst erkennen, was gesendet wird, und kann erst dann den CTS# aktivieren. Was muss man also über USB senden, dass der CTS# den FT230X rechtzeitig stoppt. Laut FTDI ist das abhängig vom Bufferinhalt. Wie genau wird aber nirgends erklärt, und auch auf meine Nachfrage dazu habe ich keine Info bekommen. Die sagen nur, man soll den latency timer auf 2ms setzen, dann werden incomplete frames sofort gesendet. Was genau ein incomplete frame ist wird nirgends erklärt, und was in diesem Fall mit TXDEN und CTS# passiert auch nicht. Ich habe leider von USB zu wenig Ahnung, deshalb auch die Frage ob das vom PC aus geht. Die FTDI Treiber stellen dazu ja eigentlich nur write() und flush() zur Verfügung. Es muss ja nicht zwangsweise jeder write() Aufruf sofort an den FT230X gesendet werden, soweit ich weiß passiert das eh nur jede ms. Wenn also ein write() kommt, bevor der USB Block (hat glaube ich 64 Byte) voll ist, könnte er ja einfach den Block vollschreiben und dann alles zusammen schicken. Was passiert dann mit dem TXDEN? Ein flush() könnte helfen, aber nur, wenn er wartet, bis der Buffer des FT230X leer ist, ich vermute aber er wartet nur bis die Daten über USB gesendet sind. Wenn es so ist, gibt es irgendeinen Weg zu warten bis der FT230X alles gesendet hat? Na ja, ich warte jetzt Mal auf die HW, und dann muss ich es wohl probieren. VG
Weil die angeschlossenen Geräte das so haben wollen. Die gibt es schon. VG
Das muss ich vielleicht noch näher erklären: Der AVR generiert eine proprietäre serielle Modulation. Das was der AVR ausgibt soll einen möglichst kurzen Zeitversatz haben. Das soll so sein, damit die Zeit bis zu einer Antwort nicht zu lang wird und dadurch der gewünschte Durchsatz nicht erreicht werden kann. Da läuft eine zyklische Abfrage und da soll eine möglichst große Anzahl von Abfragen pro Sekunde erreicht werden. Und die Antwort wird ja auch nochmal durch den AVR verzögert. Also fängt der AVR schon mit dem ersten empfangenen Byte vom FT230X an zu senden. Wenn er das Ende des Blocks erkennt hört er auf zu Senden und schaltet auf Empfang um. Auch da gibt er die empfangenen Bytes sofort weiter. Wenn der gesendete Block jetzt keine Antwort erwartet muss er eine kurze Pause vor dem nächsten zu sendenden Block einlegen. Dazu sollte der CTS# verwendet werden. Der AVR läuft also synchron zur seriellen Schnittstelle des FT230X. Er benutzt auch den Takt vom FT230X. Man könnte jetzt die Baudrate des FT230X größer machen, aber da benötigt man einen Buffer im AVR der, wenn keine Antwort erwartet wird, auch irgendwann voll ist. Somit muss man da den FT230X erst recht bremsen. Oder man macht die Baudrate des FT230X kleiner. Dann muss man aber die Antworten buffern. Und der Durchsatz geht auch runter. Oder man verdoppelt sie. Dann kann man eigene Bits für Blockstart und Blockende einbauen und wäre nicht auf den TXDEN angewiesen. Und man könnte einen NOP einbauen. Dann hätte man auch die Pause. Das hört sich irgendwie gut an, ich glaube, das werde ich probieren wenn das mit TXDEN und CTS# nicht geht. Mal sehen ob der AVR die Baudrate noch schafft. Sind ja dann ca. 6000 Bytes/s. Oder der AVR schickt alles zurück, was vom FT230X kommt. Dann hätte man am PC immer eine Antwort auf die man warten kann und somit die notwendige Pause. CTS# bräuchte man dann nicht mehr, aber den TXDEN schon. Das ist einfach zu realisieren und, da die Blöcke ohne Antwort nicht oft auftreten, sollte es den Durchsatz auch nicht vermindern. Ach ja, noch was zum TXDEN. Im Protokoll der angeschlossenen Geräte gibt es ein Start of Frame Signal. Da der TXDEN vor dem Senden gesetzt wird hat der AVR genug Zeit um dieses Signal zu erzeugen bevor das erste Datenbyte geschickt wird. Damit wird die durch den AVR verursachte Verzögerung sinnvoll genutzt und trotz AVR ist es dann nur wenig langsamer. Viel Text und viele Möglichkeiten. Schade nur, dass man wegen fehlender Doku so viel Aufwand hat. Mir hilft es immer sehr wenn ich versuche das was ich vorhabe jemandem zu erklären. Auch, wenn ich hier nicht zuviel sagen darf. Danke für's durchlesen und für's nachfragen. VG
Also mit dem AVR einen FT230 extern zu "bremsen" find ich irgendwie enorm gefrickelt, gerade wenn man einen bestimmten Durchsatz und Latenz erreichen möchte. Mit einem einzelnen USB-fähigen Controller könnte man das viel einfacher umsetzen, hätte die Garantie dass das Timing funktioniert, und hat sogar weniger Bauteileaufwand und -Kosten. Wenn man ein bisschen was leistungsfähigeres als AVR wählt (z.B. STM32) wird das Umsetzen des Timings wahrscheinlich auch entspannter.
Das ist wohl richtig. Die HW wird mir so gestellt. Und mit USB will der Kunde möglichst wenig zu tun haben. Das ist ihm zu kompliziert. Er möchte auch nichts anderes als AVR. Wenn es gar nicht geht ist er vielleicht bereit einen der wenigen AVRs mit USB zu nehmen. Mal sehen. Außerdem: Braucht man dann nicht auch einen eigenen Treiber dafür? Und wie sieht es dann mit den USB IDs aus. Braucht man da dann auch eigene? Da zieht er gar nicht mit. Er hätte gerne was, das in Windows und Linux ohne Treiberinstallation und Systemanpassung (Stichwort udev für Linux) geht. Wenn es da eine andere Möglichkeit als mit FTDI gibt, bitte her damit. Das kann ich ihm ja dann vorschlagen. VG
Georg P. schrieb: > Und mit USB will der Kunde möglichst wenig zu tun haben. Das ist ihm zu > kompliziert. Er möchte auch nichts anderes als AVR. Wenn du die Software machst kann ihm der Controller doch herzlich egal sein...?! Georg P. schrieb: > Außerdem: Braucht man dann nicht auch einen eigenen Treiber dafür? Nein. Mit WinUSB funktioniert das völlig ohne manuelle Treiberinstallation/Konfiguration. Einfach anstecken und funktioniert. Es ist sogar einfacher, weil man keinen COM-Port auswählen muss, und die PC-Software das Gerät anhand VID&PID identifizieren kann. Georg P. schrieb: > Braucht man da dann auch eigene? Ja, du müsstest eine VID kaufen (derzeit 6000$) oder schummeln. Die kannst du aber für alle Kunden wieder verwenden, halt mit anderer PID. Ist praktisch eine Investition, wie eine Software-Lizenz. Georg P. schrieb: > Systemanpassung (Stichwort udev für Linux) Das wird mit dem COM-Port aber auch nicht gehen, weil der User dafür auch Rechte erteilt bekommen muss (typischerweise plugdev Gruppe). On man jetzt eine udev-Regel anlegt um allen Usern Zugriff auf das Gerät zu geben (= 1 Datei kopieren) oder den User zu einer Gruppe hinzufügt um Zugriff zum COM-Port zu geben ist jetzt nicht so der Unterschied. Alternativ implementierst du die CDC-ACM Klasse (virtueller COM-Port) die sich aus PC-Sicht dann genau so verhält wie die Konstellation mit dem FT230. Das geht IIRC rein technisch auch mit VID=0... Ist aber auch nicht besonders toll. Georg P. schrieb: > Da zieht er gar nicht mit Das Argument dass ohne FT230 die Hardware billiger wird zieht gar nicht...?
:
Bearbeitet durch User
Niklas G. schrieb: > Das Argument dass ohne FT230 die Hardware billiger wird zieht gar > nicht...? Nein, er sagt, das akzeptiert er. Da sind keine großen Stückzahlen dahinter. VG
Niklas G. schrieb: > Das wird mit dem COM-Port aber auch nicht gehen, Also bei mir braucht bei Linux der User nur in der Gruppe dialout zu sein. Und bei Windows muss ich gar nichts machen. VG
Georg P. schrieb: > Also bei mir braucht bei Linux der User nur in der Gruppe dialout zu > sein Mit custom USB Protokoll muss man eine Datei nach /etc/udev/rules.d kopieren, ähnlicher Aufwand. Das kann auch als Teil des Installationspakets (.deb o.ä.) automatisch passieren. Georg P. schrieb: > Und bei Windows muss ich gar nichts machen. Du musst immer noch den COM-Port auswählen (war es jetzt COM23 oder COM56?). Auch das entfällt bei Custom USB Protokoll. Ein weiterer Vorteil davon wäre dass die Protokoll-Umsetzung sehr flexibel ist, du kannst rein per Software Update Anpassungen am Timing/Protokollstruktur ausliefern. Bei der FT230-Lösung mit den hart-verdrahteten Signalen ist man da schon festgelegter.
Niklas G. schrieb: > Du musst immer noch den COM-Port auswählen Ja, aber welcher Laptop oder PC hat heutzutage noch COM-Ports? Wenn es nur eines gibt, kann es auch nur das sein. Somit entfällt das in den meisten Fällen. Und wegen der Flexibilität: Bei dem proprietären Protokoll sind keine Änderungen zu erwarten, da hängt zuviel dran, was dann auch geändert werden müsste. Sollte das wirklich Mal der Fall sein, kann man ja einen neuen Adapter machen. Das geht dann in den anderen Kosten unter. VG
Georg P. schrieb: > Wenn es > nur eines gibt, kann es auch nur das sein. Somit entfällt das in den > meisten Fällen. Tja...
Georg P. schrieb: > Wenn es > nur eines gibt, kann es auch nur das sein. Somit entfällt das in den > meisten Fällen. je nachdem wie das gebaut ist bekommst du schon unterschiedliche com ports wenn du nur an eine andere USB Buchse ansteckst.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.