简体   繁体   中英

Linux read, write Arduino serial

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 "";
    }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM