Einstieg serieller Port?



  • Hallo zusammen,

    ich würde gerne Daten über den seriellen Port mit CPP auslesen und über HTTP verfügbar machen.

    Den seriellen Port behandelt man ja als File Deskriptor. Allerdings bin ich mir nicht ganz im klaren ob/wie die Verbindung zu einem Web server hergestellt werden sollte.

    Ich bin relativ unerfahren mit C++ - freue mich aber auf hilfreiches Feedback zum Vertiefen der C++ Kenntnisse.

    Vielen Dank!



  • farsi schrieb:

    Hallo zusammen,

    ich würde gerne Daten über den seriellen Port mit CPP auslesen und über HTTP verfügbar machen.

    Den seriellen Port behandelt man ja als File Deskriptor. Allerdings bin ich mir nicht ganz im klaren ob/wie die Verbindung zu einem Web server hergestellt werden sollte.

    Ich bin relativ unerfahren mit C++ - freue mich aber auf hilfreiches Feedback zum Vertiefen der C++ Kenntnisse.

    Vielen Dank!

    Hallo,

    das sind 2 unabhängige Probleme. Zum einen möchtest Du mit C++ Daten über den seriellen Port lesen und zum anderen etwas, was in einem C++-Programm vorliegt über HTTP verfügbar machen.

    Daten vom seriellen Port zu lesen hast Du ja offensichtlich verstanden. Du öffnest einfach das Device und liest davon.

    Für den Webserver musst Du Dir überlegen, welchen Du verwenden möchtest. Da Du Dich für C++ (und Linux) entschieden hast, drängt sich regelrecht mein Tntnet auf. Damit kannst Du Webapplikationen mit C++ erstellen.

    Wobei die Frage gestattet sei, warum Du das in C++ machen willst? Es hört sich nicht wie ein typisches Problem an, wo man üblicherweise C++ einsetzen würde, auch wenn ich persönlich immer damit machen würde.



  • Vielen Dank! In der Tat habe ich mit dem tntnet gespielt. Die Idee ist diesen auf dem RasPi laufen zu lassen, und dann über den seriellen Port daten von sensoren/Arduino/draussen einzulesen bzw. zu steuern.

    Wo ich ein bisschen unsicher bin ist: Der Webserver hat verschiedene Threads um die HTTP requests abzuarbeiten. Der Serielle Port ist allerdings ein eigener Prozess, der dann bei jedem GET request aufgemacht werden müsste. Passt das so, oder gibt es da was zu beachten?

    Wenn ich nun die Daten vom Port "live" im Browser anschauen möchte, reicht der GET request nicht mehr, und ich müsste sowas wie Sockets gebrauchen. Wie müsste ich dann das tntsetup anpassen (d.h. 2 Server? 1x HTML und 1x für Sockets?)



  • Gibt es einen bestimmten Grund, aus dem du das mit C++ machen möchtest? In Python, Ruby oä. wäre das nochmal um Größenordnungen simpler und mit Standardlibrary-Mitteln zu bewerkstelligen. (Für Websockets gibt es massig 3rd-Party-Libraries, das wird mit der Stdlib wohl eher mühsam.)



  • farsi schrieb:

    Vielen Dank! In der Tat habe ich mit dem tntnet gespielt. Die Idee ist diesen auf dem RasPi laufen zu lassen, und dann über den seriellen Port daten von sensoren/Arduino/draussen einzulesen bzw. zu steuern.

    Wo ich ein bisschen unsicher bin ist: Der Webserver hat verschiedene Threads um die HTTP requests abzuarbeiten. Der Serielle Port ist allerdings ein eigener Prozess, der dann bei jedem GET request aufgemacht werden müsste. Passt das so, oder gibt es da was zu beachten?

    Wenn ich nun die Daten vom Port "live" im Browser anschauen möchte, reicht der GET request nicht mehr, und ich müsste sowas wie Sockets gebrauchen. Wie müsste ich dann das tntsetup anpassen (d.h. 2 Server? 1x HTML und 1x für Sockets?)

    Warum brauchst Du einen separaten Prozess für die serielle Schnittstelle? Das brauchst Du nicht wirklich.

    Wobei die Syncronisation zwischen Lesen von der seriellen Schnittstelle und dem http request nicht ganz trivial ist. Das sind ja 2 asynchrone und voneinander unabhängige Sachen. Du kannst ja schliesslich nicht gewährleisten, dass Daten von der seriellen Schnittstelle genau dann ankommen, wenn ein http request erfolgt.

    Das sinnvollste erscheint mir, einen separaten Thread für die serielle Schnittstelle zu machen.

    Es ist natürlich die Frage, was Du mit den Daten von der seriellen Schnittstelle machen willst. Da müsstest Du ein wenig details über das zu verwendete Protokoll auf der seriellen Schnittstelle geben, um das zu beurteilen.

    Dass das mit Python, Ruby oä. um Größenordnungen simpler ist kann ich nicht zu stimmen. So schwer ist C++ nun auch wieder nicht.



  • nman schrieb:

    Gibt es einen bestimmten Grund, aus dem du das mit C++ machen möchtest? In Python, Ruby oä. wäre das nochmal um Größenordnungen simpler und mit Standardlibrary-Mitteln zu bewerkstelligen. (Für Websockets gibt es massig 3rd-Party-Libraries, das wird mit der Stdlib wohl eher mühsam.)

    Wie kommt es eigentlich, dass hier im C++-Forum so oft von C++ abgeraten wird 😕 .



  • Wie kommt es eigentlich, dass hier im C++-Forum so oft von C++ abgeraten wird 😕 .

    Genau. Spätestens wenn es mit knappen Resourcen (z.b. auf RasPi) gearbeitet wird, finde ich CPP sehr interessant.

    Das sinnvollste erscheint mir, einen separaten Thread für die serielle Schnittstelle zu machen.

    Ok, dann würde ich einen Thread für den seriellen Port machen. Mein erstes Ziel wäre einfach z.B. Daten von einen Temperatur Sensor über Arduino an den RasPi zu geben. Die Daten kämen z.B. mit 9600 Baud rein, was ja recht langsam ist.
    Im ersten Schritt müsste der tntnet die Daten aus dem File Deskriptor an das HTML übegeben, wenn immer ein GET request kommt. Im zweiten Schritt sollte der Web Server auf dem RasPi einfach eine HTML Seite ausliefern und dann die Temperatur automatisch updaten sobald die sich ändert. Dafür brauche ich dann einen Web socket.

    Ich muss dann heute abend mal recherchieren, evt. gibt es ja noch ein einfaches beispiel für Kommunikation zwischen in tntnet Threads. Und, wie würde mit tntnet Ausgabe über einen Web Socket gehen?

    Danke dir für dein interessantes Feedback!



  • tntnet schrieb:

    Wie kommt es eigentlich, dass hier im C++-Forum so oft von C++ abgeraten wird 😕 .

    In einem Hammer-Forum werden vmtl. auch oft Schraubenzieher empfohlen, weil Hämmer einfach nicht für jeden Einsatzzweck optimal sind.

    Der RasPi ist eindeutig kein Fall, wo man mit extrem knappen Ressourcen hantiert. Sobald ein Windowmanager und Browser auf einer Maschine laufen, gilt das "C++ der knappen Ressourcen wegen"-Argument nicht mehr.



  • farsi schrieb:

    Ich muss dann heute abend mal recherchieren, evt. gibt es ja noch ein einfaches beispiel für Kommunikation zwischen in tntnet Threads. Und, wie würde mit tntnet Ausgabe über einen Web Socket gehen?

    Danke dir für dein interessantes Feedback!

    Leider unterstützt tntnet keine Web sockets. Long poll wäre aber eine Möglichkeit. Bei tntnet ist eine Demo "chat" dabei, wo long poll verwendet wird.

    Für die Kommunikation zwischen dem Thread, der die serielle Schnittstelle liest und einem tntnet thread reicht eine globale Variable, die über ein Mutex geschützt ist. In diese globale Variablen schreibst Du einfach den aktuellen Temparaturwert rein. Wenn ein Request ankommt, dann liest die Webapplikation den Wert und schickt ihn in HTML verpackt (oder json) an den Client.

    Für long poll brauchst Du einen timed wait auf dem Mutex. Der Client (also Browser) schickt den letzten bekannten Temparaturwert und die Webapplikation wartet eine maximale Zeit auf einen veränderten Temparaturwert.

    Ich denke, das ist eine interessante Aufgabe. Mag sein, dass nman jetzt um die Ecke kommt und sagt: siehst Du - tntnet kann ja noch nicht mal Web Sockets. Und ich weiß auch nicht so recht, warum C++ dafür nicht optimal wäre. Inwiefern wäre Python oder Ruby besser geeignet? C++ ist doch eine tolle Programmiersprache, womit man das Problem wunderbar lösen kann. Also lieber nman: eine Sache ist es Behauptungen aufzustellen (Python oder Ruby ist besser geeignet) und eine andere ist, diese Behauptungen auch zu begründen.



  • tntnet schrieb:

    Mag sein, dass nman jetzt um die Ecke kommt und sagt: siehst Du - tntnet kann ja noch nicht mal Web Sockets.

    Bloedsinn, wenn man unbedingt C++ verwenden moechte, ist tntnet schon eine Option, auch wenn es andere C++-Web-Frameworks gibt, die Web Sockets mitbringen. Ich halte es nur nicht für sinnvoll, hier krampfhaft C++ verwenden zu wollen.

    Und ich weiß auch nicht so recht, warum C++ dafür nicht optimal wäre. Inwiefern wäre Python oder Ruby besser geeignet?

    In Python oder Ruby laesst sich das Problem vmtl. mit der Standardlibrary einfacher, schneller und in weniger Zeilen Code loesen. Insbesondere ist es so simpel, dass man den Code auch als blutiger Anfaenger schnell geschrieben hat.

    Klar kann man auch C++ verwenden; ich schreibe selbst immer wieder Software in C++. Aber typischerweise eher dann, wenn die Vorteile von C++ wirklich interessant sind.



  • In Python oder Ruby laesst sich das Problem vmtl. mit der Standardlibrary einfacher, schneller und in weniger Zeilen Code loesen.

    Zugegeben, den seriellen Port mit z.B. NodeJS auslesen geht z.B. mit:

    var serialport = require("serialport");
    var SerialPort = serialport.SerialPort;
    
    var serialPort = new SerialPort("/dev/cu.usbmodem14131", {
      baudrate: 9600,
      parser: serialport.parsers.readline("\n")
    });
    
    serialPort.on("open", function () {
      console.log('open');
      serialPort.on('data', function(data) {
        console.log(data);
      });
    });
    

    Nun, ein Blick in die serialport library zeigt aber lauter CPP code: https://github.com/voodootikigod/node-serialport/tree/master/src

    Warum dann nicht direkt in CPP bleiben, wenn auf meinem embedded device auch etwas ähnlich passiert.

    Aber stimmt, die erste Berührung mit Threads in CPP ist nicht ganz so einfach. Schaue mir gerade p_thread an, und das Anlegen/steuern einer Mutex (mutual exclusion).



  • farsi schrieb:

    Nun, ein Blick in die serialport library zeigt aber lauter CPP code: https://github.com/voodootikigod/node-serialport/tree/master/src

    Klar, aber den musst du weder selbst schreiben noch warten.

    Meine Shell ist auch in C geschrieben und ich verwende trotzdem Shellskripte statt C-Programme, um meine Backuptools anzuwerfen oder meinen Paketindex zu aktualisieren.

    Aber stimmt, die erste Berührung mit Threads in CPP ist nicht ganz so einfach. Schaue mir gerade p_thread an, und das Anlegen/steuern einer Mutex (mutual exclusion).

    Dass C++ seit C++11 auch Threads in der Standardlibrary hat, weißt du?

    http://en.cppreference.com/w/cpp/thread/mutex



  • Danke für den Link zur Mutex.

    Für andere die es mit CPP versuchen wollen den seriellen Port zu gebrauchen ist dieser Link zur Boost Library noch gut: http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/overview/serial_ports.html

    PS verwendet tntnet Boost? warum (nicht) ?



  • Ich verschieb dich mal nach Rund um die Programmierung, da passt der Thread vmtl. mittlerweile besser hin.



  • Dieser Thread wurde von Moderator/in nman aus dem Forum Linux/Unix in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • nman schrieb:

    tntnet schrieb:

    Mag sein, dass nman jetzt um die Ecke kommt und sagt: siehst Du - tntnet kann ja noch nicht mal Web Sockets.

    Bloedsinn, wenn man unbedingt C++ verwenden moechte, ist tntnet schon eine Option, auch wenn es andere C++-Web-Frameworks gibt, die Web Sockets mitbringen. Ich halte es nur nicht für sinnvoll, hier krampfhaft C++ verwenden zu wollen.

    Danke für die Information. Im prinzip sehe ich das ja auch genauso. Ich selbst habe ja die Frage gestellt, warum er das in C++ machen will. Ich habe den Eindruck, dass Farsi das als Lernprojekt sieht und man lernt natürlich kein C++ wenn man eine vorgefertigte Python-Library nimmt 😃 .

    Ich selbst verwende immer C++ wenn ich es kann. Für mich stellt sich eher die Frage, warum ich es in Python machen sollte, wenn es doch in C++ so einfach ist 🤡 .

    farsi schrieb:

    PS verwendet tntnet Boost? warum (nicht) ?

    Tntnet verwendet kein Boost. Es gibt keinen Grund dafür. Als ich Tntnet angefangen habe, war auch Boost lange nicht so weit verbreitet. Die ersten Tntnet-Versionen haben sogar Boost verwendet, aber die damals schwierige Installation von Boost hat viele davon abgehalten, Tntnet auch nur näher anzuschauen. Und es war leicht, die Abhängigkeit zu entfernen.

    Für den Anwender von Tntnet ist es kein Nachteil, dass Tntnet kein Boost verwendet. Es spricht nichts dagegen, in Tntnet-Applikationen Boost zu verwenden, obwohl Tntnet selbst es nicht nutzt. Der Vorteil ist dagegen, dass es eine Abhängigkeit weniger gibt.


Anmelden zum Antworten