Go Down

Topic: Issues interfacing serial with C++ code on Linux (Read 631 times) previous topic - next topic

Fulluphigh

Hi guys,

I'm having some issues interfacing with an executable in linux through serial communication. It only works... when I've already got the Serial Monitor from the Arduino IDE up and running.

What I mean is, if I reset my arduino/ upload the sketch, wait a few seconds, and then run the executable, it won't work unless the Serial Monitor is running somewhere in the background. Otherwise it just flashes the LED and RX leds a few times, like when you upload a sketch to it. I'm using the libSerial library in my C++ code to interface with the serial port. Here is the relevant code from that:

Code: [Select]

int Sensor::startSerial()
{
        talk.Open("/dev/ttyACM0");
        talk.SetBaudRate(baudrate);
        talk.SetCharSize(SerialStreamBuf::CHAR_SIZE_8);
        talk.SetFlowControl(SerialStreamBuf::FLOW_CONTROL_NONE);
}


Then, the actual communication is in the following snippet, which is continues through the life of the program:
Code: [Select]

talk << SensorSpace::pingArduino;
std::string reply;
talk >> reply;


Any help would be incredibly appreciated.

billroy

It is necessary to delay a short while after opening the serial port in order to let the arduino bootloader time out.  Something like 1500 ms usually seems to work.  Otherwise your first transmission gets lost and it seems like the arduino is deaf.  Unless you already have the serial port open, which prevents this problem. 

(Alternatively you can wait for some specific output from the arduino program to let you know it's ready.)

-br

Fulluphigh

Ah! Excellent, thank you very much!

This brings up a few more issues though... Hmm. Does opening the USB serial port reset the sketch on the arduino? It looked like that's what it was doing to begin with, but now, when the arduino is sending out information across Serial waiting for a handshake, it doesn't seem to reset. And while my handshake is now functional, it still stalls trying to read from the Arduino when it gets to the updateState() function call in my c++ code.

The code basically goes like this:

Code: [Select]

int Sensor::startSerial()
{
        talk.Open("/dev/ttyACM0");
        talk.SetBaudRate(baudrate);
        talk.SetCharSize(SerialStreamBuf::CHAR_SIZE_8);
        talk.SetFlowControl(SerialStreamBuf::FLOW_CONTROL_NONE);

        //Handshake
        std::string handshake;
        talk >> handshake;
        //This will delay until the arduino sends something,
        //which will let us know it's ready to communicate
        if (handshake.compare("hello") == 0)
        {
                //Checking to see if it says what we think, and how
                //newlines affect it when reading to string, if at all
                std::cerr << "Contents of handshake: "<< handshake << '\n';
                talk << "hi";
        }

        //Sync will discard all of the unread characters in the buffer,
        //since it's likely the Arduino transmitted the handshake multiple
        //times before server was started
        if (talk.sync() != 0)
        {
                //error handling
        }

        return 0;
}


Which is then followed by:

Code: [Select]

int Sensor::queryState()
{
        std::cerr << "Alright, pinging arduino...\n";
        talk << "ping";
        std::cerr << "And now fetching reply...\n";
        std::string reply;
        talk >> reply;
        std::cerr << "Reply fetched...?\n";
       
        for(int i = 0; i < reply.length(); i++)
        {
                std::cerr << "Replay["<<i<<"]: " << reply.c_str()[i];
                std::cerr << "\n";
        }
        std::cerr << "Length of reply: " << reply.length() << "\n";

        //...And so on.....
}


The problem is now that I never get past the reply fetching part of the second function. The thing is, the Arduino is seeing the ping, but it seems that it is consistently only receiving
Code: [Select]
"ing". I'm calling sync on the buffer because I thought the Arduino didn't reset when I opened the Serial connection on the computer, so it may have sent several handshakes to the buffer before I run ./server after resetting the board. This would (I think) empty the buffer, so the next the the computer read wouldn't be more "hello"s. If the Arduino does reset when the port is opened in the program, it wouldn't make a difference, and doesn't seem to. Never the less, I have no idea where the "p" is going D=

Go Up