Read Serial data in c++

I am trying to read serial data from a usb port on my computer, which connects to the brain in c++. I know it works it python from this topic however I cannot find a way to do in c++. How would I do this in c++?

1 Like

You just use stdio.

Here’s a hack that was originally part of some V5 code.

header
/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Copyright (c) Innovation First 2021, All rights reserved.               */
/*                                                                            */
/*    Module:     serial.h                                                    */
/*    Author:     James Pearman                                               */
/*    Created:    19 April 2021                                               */
/*                                                                            */
/*    Revisions:  V0.1                                                        */
/*                                                                            */
/*----------------------------------------------------------------------------*/

#ifndef DEMO_COMMS_H_
#define DEMO_COMMS_H_

#include "vex.h"

/*----------------------------------------------------------------------------*/
/** @file    serial.h
  * @brief   Header for serial communication class
*//*--------------------------------------------------------------------------*/

namespace demo {
    class comms  {
      public:
        comms();
        ~comms();

      private:
        vex::thread t1;

        bool          parse( uint8_t data );
        static int    receive_task( void *arg );
    };
};


#endif /* DEMO_COMMS_H_ */
code
/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Copyright (c) Innovation First 2021 All rights reserved.                */
/*                                                                            */
/*    Module:     serial.cpp                                                  */
/*    Author:     James Pearman                                               */
/*    Created:    19 April 2021                                               */
/*                                                                            */
/*    Revisions:  V0.1                                                        */
/*                                                                            */
/*----------------------------------------------------------------------------*/
#include "vex.h"
#include "serial.h"

/*----------------------------------------------------------------------------*/
/** @file    serial.cpp
  * @brief   class for serial communication
*//*--------------------------------------------------------------------------*/

using namespace vex;
using namespace demo;

extern brain Brain;

/*---------------------------------------------------------------------------*/
/** @brief  Constructor                                                      */
/*---------------------------------------------------------------------------*/
// Create higher than normal priority task to handle incomming data
//
comms::comms() {
    t1 = thread( receive_task, static_cast<void *>(this) );
    t1.setPriority(thread::threadPriorityNormal + 2);
}

comms::~comms() {
    t1.interrupt();
}

/*---------------------------------------------------------------------------*/
/** @brief  Parse a single received byte                                     */
/*---------------------------------------------------------------------------*/
bool
comms::parse( uint8_t data ) {
    bool  bRecall = false;

    //printf("%02X", data);
    if( data == 'a' || data == 'A')
        Brain.Screen.printAt(5, 20, "forward");
    if( data == 'p' || data == 'P')
         Brain.Screen.printAt(5, 20,"stop   ");
    if( data == 'd' || data == 'D')
         Brain.Screen.printAt(5, 20,"right  ");
    if( data == 'l' || data == 'L')
         Brain.Screen.printAt(5, 20,"left   ");

    // not used in this demo
    return bRecall;
}

/*---------------------------------------------------------------------------*/
/** @brief  Task to receive and process receive data from serial port        */
/*---------------------------------------------------------------------------*/
int
comms::receive_task( void *arg ) {
    if( arg == NULL)
      return(0);
      
    // get our comms instance
    // theoretically we could handle more than one channel on different
    // ports, but that's beyond the scope of this demo code
    //
    comms *instance = static_cast<comms *>(arg);

    // process one character at a time
    // getchar() is blocking and will call yield internally
    //
    while(1) {
      // this will block
      int rxchar = getchar();

      // process this byte
      if( rxchar >= 0 ) {    
        // parse returns true if there is more processing to do
        while( instance->parse( (uint8_t)rxchar ) )
          this_thread::yield();
      }

      // no need for sleep/yield as stdin is blocking
    }
}

used like this.

demo::comms comms;

int main() {
    while(1) {       
        // Allow other tasks to run
        this_thread::sleep_for(10);
    }
}

depending on what exactly you are doing it could be simpler, use scanf (or std::cin)

1 Like