-1

I'm trying to write to an Arduino serial from a c++ program. How do I set the baudrate in the C++ program? The communication seems to work, when the arduino is set to 9600, but fails when I change it, as expected.(so 9600 is the default?) Using the command to see output: screen /dev/ttyUSBx 115200 Using an example program to echo everything, on the Arduino:

* serial_echo.pde
* ----------------- 
* Echoes what is sent back through the serial port.
*
* http://spacetinkerer.blogspot.com
*/

int incomingByte = 0;    // for incoming serial data

void setup() {
  Serial.begin(115200);    // opens serial port, sets data rate to 9600 bps
}
void loop() {
  // send data only when you receive data:
  if (Serial.available() > 0) ;
  // read the incoming byte:
  incomingByte = Serial.read();
  // say what you got:
  Serial.print((char)incomingByte);
}

and the C++ code is:

#include <iostream>
#include <stdio.h>
#include <string>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

using namespace std;

string comArduino(string outmsg = " hello"){

  #define comports_size 3

  static int fd_ard;
  static bool init = false;
  //char buffer[256];

  if(!init){
      string comports[] = { "/dev/ttyUSB0","/dev/ttyUSB1","/dev/ttyUSB2" };
      for(int i = 0; i < comports_size; i++){

          fd_ard = open(comports[i].c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
          if (fd_ard != -1) {
              cout<<"connected to "<<comports[i]<<endl;
              init = true;
              break;
          }
          else{
              perror ("open");
          }
          if(i == (comports_size - 1)){
              cout<<"can't connect to arduino [ ER ]\n"<<endl;
              return "";
          }
      }
  }
  int Er = write(fd_ard,outmsg.c_str(),strlen(outmsg.c_str()));
  if(Er < strlen(outmsg.c_str())){
      perror ("write ");
      init = false;
  }
  else
      cout<<"write ok"<<endl;
  return "";
}
int main(){
  while(1){
      comArduino();
      sleep(1);
  }
}

Edit: needed to add the following lines after open() to configure the serial properly:

    struct termios PortConf;
    // write port configuration, as ' stty -F /dev/ttyUSB0 -a ' returned after opening the port with the arduino IDE.
    tcgetattr(fd_ard, &PortConf);                           // Get the current attributes of the Serial port
    PortConf.c_cflag = 0;                                 //set cflag
    PortConf.c_cflag |= (CS8 | HUPCL | CREAD | CLOCAL);

    PortConf.c_iflag = 0;                                 //set iflag
    //PortConf.c_iflag &= ~(ISIG | ICANON | IEXTEN);

    PortConf.c_oflag = 0;                                 //set oflag
    PortConf.c_oflag |= (ONLCR | CR0 | TAB0 | BS0 | VT0 | FF0); //NR0 is supposed to be set, but won't compile
    //PortConf.c_oflag &= ~(OPOST);

    PortConf.c_lflag = 0;                                 //set lflag
    //PortConf.c_lflag &= ~(ECHO | ECHOE);

    PortConf.c_cc[VMIN]  = 0;
    PortConf.c_cc[VTIME] = 0;

    cfsetispeed(&PortConf,B115200);                       // Set Read  Speed as 115200                       
    cfsetospeed(&PortConf,B115200);                       // Set Write Speed as 115200 

    if((tcsetattr(fd_ard,TCSANOW,&PortConf)) != 0){       // Set the attributes to the termios structure
        printf("Error while setting attributes \n");
        return "";
    }
ffoska
  • 41
  • 1
  • 8
  • Try `/dev/ttyS0`, `/dev/ttyS1`, `/dev/ttyS2` instead of USB... – Havenard Sep 23 '18 at 22:27
  • checked, it's the right dev, but the baud-rate is not right.As I said it works for 9600. – ffoska Sep 23 '18 at 22:32
  • Pretty sure USB and traditional serial com ports aren't the same thing. – Havenard Sep 23 '18 at 22:35
  • So to clarify, the PC is connected to the arduino nano board via USB (the cable used for programing), not with a traditional serial cable.I should've been more clear on that. – ffoska Sep 23 '18 at 23:14
  • It's more complicated than that. It's a Serial controller connected via USB, once this controller is installed in your system it makes a Serial port available to communicate with the Arduino Microcontroller. You can't just talk Serial through a USB channel, it's not how it works. Install the Serial controller that you just connected via USB and then you can talk to the Arduino through a Serial port. If the Arduino IDE can do it my guess is that it's already installed, just use the Serial port. – Havenard Sep 23 '18 at 23:39
  • `if (Serial.available() > 0) ;` does nothing. – gre_gor Sep 24 '18 at 13:51

1 Answers1

1

You need to set the baudrate of whatever port you are using by using the termios structure.

Use "man termios" to get more info about termios structure

So for a start to need to add

#include <termios.h> 

To the top of your code.

later on when you open you port:

fd_ard = open(comports[i].c_str(), O_RDWR | O_NOCTTY | O_NDELAY);

You need to the access the termios structure and modify it to suit your needs

struct termios SerialPortSettings;  // Create the structure                          
tcgetattr(fd_ard, &SerialPortSettings); // Get the current attributes of the Serial port

Then, set the baudrate

cfsetispeed(&SerialPortSettings,B115200); // Set Read  Speed as 115200                       
cfsetospeed(&SerialPortSettings,B115200); // Set Write Speed as 115200                       

Then commit the changes

if((tcsetattr(fd_ard,TCSANOW,&SerialPortSettings)) != 0) // Set the attributes to the termios structure
  printf("Error while setting attributes \n");

There are a bunch of other things that can be set for flow control, cannonical mode etc which may affect how data gets sent and received. Refer to the man page, or refer to This description of the General Terminal Interface

darrob
  • 135
  • 8