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