Modbus Half-duplex

  • Hallo Leute,
    vorab möchte ich kurz erwähnen, dass ich hier Brandneu bin und mir deshalb nicht ganz sicher ob ich unter dem richtigen Forum Poste.

    Also dann mal zur Sache. Ich hab mir einen Sensor von Wago für ein Schulprojekt besorgt. Nachdem ich jetzt die Grundlegendsten Schwierigkeiten beseitigt habe, ist es mir gelungen was halbwegs anständiges mit der "modbus.h" library zu erstellen. Ich arbeite hierbei über Modbus RTU mittels eines der UARTs. Ich habe mir jetzt einen Adapter vom UART auf RS485 (MAX485ECPA) gebaut. Ich habe in der libmodbus aber nichts zum Enable der einzelnen Kanäle oder sonst was zum Half-duplex Betrieb gefunden.

    Deshalb habe ich einfallsreich wie ich bin, einfach beide dauerhaft auf Enable. Wie man sich denken kann, bringt mich das ganze kaum weit. Denn egal ob ich einen Sensor habe oder nicht, des Raspberry empfängt sich bloß selbst (ähnlich dem Gedanke von minicom, was auch wie in Butter läuft).

    Hat jemand eine Idee wie ich dem ganzen Abhilfe schaffen kann? Ohne ein komplettes Modbus Protokoll schreiben zu müssen. Adden der Lib, oder sowas...

    Gruß Dominic

  • Soweit ich weiß läuft Modbus immer im Halbduplex Modus, auch wenn physikalisch Sende und Empfangskanäle getrennt sind und damit Vollduplex möglich wäre.

    Der Master fragt und wartet auf die Antwort vom Slave. Kommt die Antwort oder die maximale Antwortzeit ist um, dann das ganze für den nächsten Job. Master und Slave senden also nie gleichzeitig.

    Ich kenne die modbus library nicht und weiß auch nicht wie die mit dem Echo der eigenen Telegramme zurechtkommt. Du solltest vielleicht mal den Bus belauschen um herauszufinden ob denn der Slave überhaupt antwortet.

  • Also, ich hab mal n Oszi ran geklopft, sowie es den Anschein macht reagiert der Sensor innerhalb der dafür vorgesehenen Zeit.

    Jedoch interessiert sich der Raspberry dafür gar nicht, da er einfach das was er selbst sendet als Antwort auffasst. Das kann ich daran feststellen, dass ich mit und ohne Sensor am RPI immer die selbe Rückmeldung bekomme. Und logischer weise auch einen CRC Fehler.

    Ich hab da praktisch ein echo von dem was ich selbst sende. Ich hab nur keine Ahnung wie ich das unterdrücken kann.

  • Wie sieht die Leitung aus: zweidraht oder vierdraht ?

    Bei vierdraht geht es einfach:
    * Ausgang mit dem Eingang des Geraets verbinden
    * Eingang mit dem Ausgang des Geraets verbinden

    Zweidraht ist eigentlich nicht komplex, ABER das Timing kriegt man mit
    grossen OS fast nicht hin ...

    Zweidraht:

    * Tx auf Leitung schalten
    * Senden (und dabei den Empfaenger zuhalten oder die Daten ignorieren)
    * SCHNELL Rx auf die Leitung schalten
    * Daten empfangen und verarbeiten

    Das Problem bei einem OS wie Linux: man weiss nicht, wann der Seriell-
    Chip wirklich sendet. Die Daten werden erst mal gepuffert, und dann
    gesendet wenn das OS gerade Zeit dafuer hat.

    Nach dem Senden muss die Leitung so schnell wie moeglich wieder
    freigegeben werden. Ein schneller Mikroprozessor am anderen Ende
    der Leitung kann das in einer Millisekunde oder noch schneller.

    Das Problem eines User-Space Prozesses in Linux ist, dass er
    erstens gar nicht weiss, wann das letzte Byte der Meldung voll-
    staendig gesendet ist. Zweitens kann er auch nicht schnell genug
    reagieren, weil Linux bestimmt, wann er laeuft.

    Es mag sein, dass es haeufig gelingt, schnell genug die Leitung
    umzuschalten, aber eine saubere Loesung gibt es so nicht.

    Vermutlich ist die einzig saubere Loesung ein Kernel-Driver.

  • Moin Tell,


    ...
    Das Problem bei einem OS wie Linux: man weiss nicht, wann der Seriell-
    Chip wirklich sendet. Die Daten werden erst mal gepuffert, und dann
    gesendet wenn das OS gerade Zeit dafuer hat.
    ...


    knapp daneben geschossen ;) ... Armbrust verzogen?

    Im raw (uncooked) Modus sollte der schon zuverlässig genug senden ... wär ja schlimm, wenn nicht ;) ...
    Hab' ich seinerzeit -> hier <- mal realisiert für unseren Oberguru ... arbeitet mit IRQ und raw und ist evtl. eine brauchbare Vorlage.

    cheerio,
    -ds-

  • > Im raw (uncooked) Modus sollte der schon zuverlässig genug senden ... wär ja schlimm, wenn nicht
    Auch im raw-Mode kopiert der write System-Call die Daten bloss in einen Buffer und kommt dann
    zurueck zum User-Space. Im Hintergrund laeuft ein Interrupt-Handler im Kernel und bedient
    den Seriell-Chip. Dessen Timing ist vollkommen entkoppelt vom Prozess.

    Wann der Chip (nicht der Interrupt-Handler !) das letzte Bit ausgebeben hat, kriegt der User-Space
    nicht mit.

    Und selbst es der Prozess wuesste, muesste er erst noch den Scheduler davon ueberzeugen,
    dass er JETZT SOFORT scheduled werden muss, damit er schnell genug umschalten kann.
    Das geht bei einem normalen Linux nicht.

    Und auch der Device-Driver fuer das Pin darf nicht lange brauchen, sonst ist es zu spaet.
    (Das ist auf dem PI noch loesbar weil man vom User-Space direkt in die GPIO-Pins
    schreiben kann)

  • Ok Tell,
    wenn Du vom Timing soo genaue Ausgaben willst, gebe ich Dir vollkommen recht.
    Aber ist das wirklich so zeitkritisch?
    Streng genommen müsste man sonst sagen, dass Linux, da kein Realtime-OS, dafür nicht geeignet ist ;)
    Ich bin allerdings nach wie vor der Meinung, dass ein normales RAW-Handling der Schnittstelle mit SIGIO ausreichen sollte. Und da es -> hier <- z.B. fertige RS485-Platinchen oder -> hier <- gar ein Shield gibt, wird's wohl auch so gehen ...

    //EDIT:
    Wenn schon Treiber, dann würde ich direkt einen RS485 Baustein nehmen.
    Irgendwo glaube ich mich zu erinnern hatte ich mal was zu diesem Thema gelesen.
    Da gibt's wohl was ... ich weiss bloss nicht mehr, wo das war - ist zu lange her und hat mich damals wohl auch nicht allzusehr interessiert.

    //Noch'n EDIT:
    Kommando zurück, das war CAN-Bus ...

    cheers,
    -ds-

  • Also wie angekündigt, habe ich ausführlich versucht die Modbus lib anzupassen. Ich weis nicht wie derjenige der diese Patch Beispiel gemacht, das alles genau gemacht hat. Aber wenn es bei ihm Funktioniert, is des schön für ihn, bei mir will es nicht.

    Hier mal n Link dazu:
    http://www.github.com/stephane/libmodbus/pull/35

    Ich hab einiges ausprobiert aber ohne den geringsten Erfolg. :helpnew:

    Einmal editiert, zuletzt von DominicS (18. Juni 2014 um 09:49)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!