Serielle Schnittstellen Ansteuerung von C in C++ ändern



  • Hallo,

    ich bin E-Technik Student und habe gerade ein Projekt zu beweltigen.

    Dabei sollen zwei Roboterarme programmiert werden. Jedenfalls gehts hauptsächlich um das senden der Befehle an die Roboter über eine serielle Schnittstelle.

    Mit normalem C klappt das herforangend und der Roboter führt den Befehl "NT" aus:

    #define SERIAL_DEVICE "/dev/ttyS0"

    FILE* openSerialDevice() {
    FILE* interface;
    interface = fopen(SERIAL_DEVICE, "w");
    return interface;
    }

    int main(void){
    FILE* interface;
    interface = openSerialDevice();
    fprintf(interface,"NT\n");
    return 0;
    }

    Nun muss der Code in C++ geändert werden und das gleiche erfüllen. Allerdings funktioniert mein Code nicht:

    #define SERIAL_DEVICE "/dev/ttyS0"

    ofstream *openSerialDevice() {
    ofstream *interface;
    interface = new ofstream(NULL);
    interface->open(SERIAL_DEVICE, ios::out);
    return interface;
    }

    int main(void){
    ofstream *interface;
    interface = openSerialDevice();
    string commando("NT");
    (*interface) << commando;
    return 0;
    }

    Selbstverständlich sind alle nötigen libs hinzugefügt.

    Hab ich den Code falsch übersetzt? Etwas vergessen? Der Befehl geht einfach nicht durch. Es gibt auch keine Fehlermeldung.

    Wenn es noch Fragen zur Situation gibt, gebe ich gern noch genauere Infos.

    Hoffe mir kann jemand helfen.

    Viele Grüße



  • Du programmierst nicht C++, indem du einfach FILE* durch std::ofstream* ersetzt. In C++ wird zum Beispiel viel weniger dynamisch angelegt, #define ist auch recht selten. Eine Lösung, bei der du nicht ans Freigeben denken musst (die Funktion openSerialDevice ist unnötig):

    const char* SERIAL_DEVICE = "/dev/ttyS0";
    
    int main() // kein void
    {
        std::ofstream interface(SERIAL_DEVICE);
        interface << "NT"; // kein std::string
        // kein return 0;
    }
    

    Das fehlerverursachende Problem bei deinem Code ist, dass du dem std::ofstream -Konstruktor einen Nullzeiger übergibst. Wie kommst du auf so eine Idee? Normalerweise liest man die Dokumentation, bevor man etwas Neues benutzt.

    Übrigens bin ich mir nicht sicher, ob du mit std::ofstream direkt serielle Schnittstellen ansprechen kannst. Unter Umständen musst du binär schreiben (mit std::ios::binary ).



  • Desweiteren ist "NT\n" (in deinem C Code) was anderes als "NT" (in deinem C++ Code).



  • ja, stimmt. Es ist was anderes. Gab aber mit und ohne das gleiche Ergebnis.
    Aber danke für die Tipps. Ich werd es morgen ausprobieren.

    Bye Bye


  • Administrator

    Nexus schrieb:

    Übrigens bin ich mir nicht sicher, ob du mit std::ofstream direkt serielle Schnittstellen ansprechen kannst. Unter Umständen musst du binär schreiben (mit std::ios::binary ).

    1. Wieso sollte es nicht gehen? Unter Unix ist alles ein File. Unter C verwendet man fopen und co, in C++ eben std::fstream und co.
    2. Du solltest doch das wirklich wissen, dass std::ios::binary nicht dazu da ist, etwas binär zu schreiben oder lesen. std::ios::binary gibt nur vor, ob der Stream etwas verändern darf an den übergebenen Daten. Zum Beispiel wird auf Windows aus einem <LF> automatisch ein <CRLF> beim Schreiben. Mit der Angabe von std::ios::binary erhält man die Garantie, dass nichts an den Daten verändert wird. Auf Unix ähnlichen Betriebsysteme hat das aber meistens keinen Effekt, bzw. es gibt keinen wirklichen Unterschied zwischen den beiden Modi. Zur Sicherheit sollte man es aber trotzdem angeben, wenn man wirklich 1:1 schreiben oder lesen möchte.

    Zudem:
    Dein "// kein return 0;" ist ein wenig heftig formuliert. Klingt fast so als wenn in C++ kein return 0 am Ende der Main-Funktion erlaubt wäre. Besser wäre gewesen: "In der Main Funktion freiwillig: return 0;"
    Und wenn ich mich recht erinnere, ist es sogar in C erlaubt, dass return 0 am Ende der Main-Funktion wegzulassen. Hat also wirklich gar nichts mit C++ oder nicht zu tun 😉

    Grüssli



  • Dravere schrieb:

    1. Wieso sollte es nicht gehen?

    Weiss ich das? Ich schreibe "ich bin mir nicht sicher" normalerweise nicht einfach so aus Spass hin.

    Dravere schrieb:

    2. Du solltest doch das wirklich wissen, dass std::ios::binary nicht dazu da ist, etwas binär zu schreiben oder lesen. std::ios::binary gibt nur vor, ob der Stream etwas verändern darf an den übergebenen Daten. Zum Beispiel wird auf Windows aus einem <LF> automatisch ein <CRLF> beim Schreiben. Mit der Angabe von std::ios::binary erhält man die Garantie, dass nichts an den Daten verändert wird. Auf Unix ähnlichen Betriebsysteme hat das aber meistens keinen Effekt, bzw. es gibt keinen wirklichen Unterschied zwischen den beiden Modi. Zur Sicherheit sollte man es aber trotzdem angeben, wenn man wirklich 1:1 schreiben oder lesen möchte.

    Es ist mir schon bewusst, dass binäres oder semantisches Schreiben von operator<< bzw. write() abhängt. Aber schlussendlich sind die von dir aufgezählten Faktoren eben auch zu berücksichtigen, wenn ein binäres 1:1-Format erwünscht ist. Insofern trägt ios::binary auch zum binären Schreiben bei, oder ist der Name des Flags Zufall?

    Dravere schrieb:

    Dein "// kein return 0;" ist ein wenig heftig formuliert.

    Ich wollte ihm lediglich ein paar Wege zeigen, wie er den Code verkürzen und verbessern konnte. Da ist gar nichts formuliert, sondern nur der Unterschied zu seinem Code aufgezeigt.

    Okay, ich hätte etwas ausführlicher antworten können, wenn ich nicht noch was Anderes vorgehabt hätte. Aber ist ja nicht so, dass mein Post komplett falsch wäre und dem Threadersteller überhaupt nicht helfen würde. 😉


  • Administrator

    Nexus schrieb:

    Dravere schrieb:

    1. Wieso sollte es nicht gehen?

    Weiss ich das? Ich schreibe "ich bin mir nicht sicher" normalerweise nicht einfach so aus Spass hin.

    Nicht? 🤡

    Nexus schrieb:

    Es ist mir schon bewusst, dass binäres oder semantisches Schreiben von operator<< bzw. write() abhängt. Aber schlussendlich sind die von dir aufgezählten Faktoren eben auch zu berücksichtigen, wenn ein binäres 1:1-Format erwünscht ist. Insofern trägt ios::binary auch zum binären Schreiben bei, oder ist der Name des Flags Zufall?

    Der Name ist etwas unglücklich gewählt. Er soll eigentlich aussagen, dass das File als Binär-File und nicht als Text-File geöffnet werden soll. Ein Text-File ist aber genauso binär gespeichert und es wird ebenfalls binär geschrieben und gelesen. Man wollte einfach nur eine Unterscheidung zwischen rohen und textuellen Daten erreichen. Ich persönlich hätte daher lieber sowas wie std::ios::raw bevorzugt.

    Nexus schrieb:

    Dravere schrieb:

    Dein "// kein return 0;" ist ein wenig heftig formuliert.

    Ich wollte ihm lediglich ein paar Wege zeigen, wie er den Code verkürzen und verbessern konnte. Da ist gar nichts formuliert, sondern nur der Unterschied zu seinem Code aufgezeigt.

    Naja, du redest eben gleich zuvor davon, dass er so kein C++ programmiere und kritisierst seinen C++ Programmierstil. Da kam bei mir das Gefühl auf, dass der Code auch eine Kritik an seinem C++ Stil ist. Was grundsätzlich auf alles vor dem return 0 auch zutrifft 😉

    Nexus schrieb:

    Aber ist ja nicht so, dass mein Post komplett falsch wäre und dem Threadersteller überhaupt nicht helfen würde. 😉

    Das habe ich ja auch nicht behauptet. Ich habe den Beitrag nur etwas kritisiert, weil ich ihn zu ungenau und nicht ausführlich genug empfand. 😉

    Grüssli


Anmelden zum Antworten