Reading Arduino data with C++ program

Hi,

I am working on creating [eventually] a nice graphical GUI to interface with my arduino board through the serial port created by the board. The program is for my linux platform, and the goal is to be able to read messages printed by the board, and be able to run the C++ program and input data that will be sent to and stored on the arduino board.

In the beginning of my setup() function on the board I have:

  Serial.println("Press leftSwitch to begin!");
  Serial.println("READY");

And when I run my GUI, it receives the information (I believe), however it is sent back to the GUI from the board in weird unreadable characters and I'm not entirely sure why. This is the program I am working with for my GUI right now.

Thanks in advance for any input.

#include <termios.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

main(){

      int pid, serial_fd; //process ID info for forking and file descriptor for serial stream
      struct termios port_config; //sets up termios configuration structure for the serial port
      char c; //charater for printing from serial port
      char input[10];

      const char *device = "/dev/ttyACM0"; //sets where the serial port is plugged in
      serial_fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); //opens serial port in device slot
      if(serial_fd == -1)
    { //-1 is the error message for failed open port
            fprintf(stdout, "failed to open port\n");
      }

      tcgetattr(serial_fd, &port_config);

      cfsetispeed(&port_config, B9600); //set baud input to 9600 (might be wrong?)
      cfsetospeed(&port_config, B9600); //set baud output to 9600 (might be wrong?)


      port_config.c_iflag = 0; //input flags
      port_config.c_iflag &= (IXON | IXOFF |INLCR); //input flags (XON/XOFF software flow control, no NL to CR translation)
      port_config.c_oflag = 0; //output flags
      port_config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); //local flags (no line processing, echo off, echo newline off, canonical mode off, extended input processing off, signal chars off)
      port_config.c_cflag = 0; //control flags
      port_config.c_cflag &= (CLOCAL | CREAD | CS8); //control flags (local connection, enable receivingt characters, force 8 bit input)



      port_config.c_cc[VMIN]  = 1;
      port_config.c_cc[VTIME] = 0;

      tcsetattr(serial_fd, TCSAFLUSH, &port_config); //Sets the termios struct of the file handle fd from the options defined in options. TCSAFLUSH performs the change as soon as possible.

      pid = fork(); //splits process for recieving and sending

      if(pid == 0)
    { //should continually receive
            fprintf(stdout, "Receiving Process Started\n");
            while(1){
                  if (read(serial_fd, &c, 1)>0)
                        { //if there's something to be read from the serial port
                        fprintf(stdout, "%c", c);
                  }
            }
      }
      else{
            fprintf(stdout, "Sending Process Started\n");
            while(1){
                  scanf("%s", input);
                  input[strlen(input)] = '\r';
                  send(serial_fd, input, strlen(input), 0);
                  fprintf(stdout, "%s\n", input);
            }
      }


      close(serial_fd); //close serial stream

      fprintf(stdout, "complete");

return 0;
}

Are you making sure to setup the serial to 9600 in the setup function?

Serial.begin(9600);

Yes, the baud rate is set to 9600 in the setup function already. Should this be changed to something different in both programs? This is my setup function, or the relevant part anyway.

Everything after the code I posted here that is in the setup() function is for inputting data into the GUI and storing it on the board, which I will get to once I figure out why it can't read data correctly.

void setup() { 
  pinMode(redLed, OUTPUT);     
  pinMode(greenLed, OUTPUT); 
  pinMode(rightSwitch, INPUT);     
  pinMode(leftSwitch, INPUT); 
  xbee.begin(9600);
  Serial.begin(9600);
  Serial.flush();
  
  digitalWrite(redLed,HIGH);
  
  // Startup delay to wait for XBee radio to initialize.
  // you may need to increase this value if you are not getting a response
  delay(5000);
  
  digitalWrite(greenLed,LOW);
  digitalWrite(redLed,LOW);
  
  // Wait until leftSwitch is pressed to start the Nudge program
  // This helps with programming and debugging
  Serial.println("Press leftSwitch to begin!");
  Serial.println("READY");
  digitalWrite(greenLed,HIGH);
    
  counter = 0;
  counter2 = 0;
  
  while (digitalRead(leftSwitch) == LOW) {
    if (Serial.available() && (counter < sizeof(serialInput)) && (counter2 < 4)) {
      serialInput[counter] = Serial.read();
        if (serialInput[counter] == '\r') { // Every complete programming string ends in '\r'
          counter2++; // This keeps track of the total number of complete programming strings received
          if (counter2 == 4) { // Four programming strings are expected (Status, Gender, Age, Contact)
            Serial.println("OK"); // Let the GUI know we got all four programming strings
...
...

The easiest way to get the C++ application and the Arduino talking to each other is the get the Arduino working first. The input to the Arduino can come from the Serial Monitor. The output from the Arduino goes to the Serial Monitor. When the input to the Arduino causes the proper behavior, and the output from the Arduino is reasonable in the Serial Monitor, then it is time to develop the C++ application to be used in place of the Serial Monitor.

So, does the data look reasonable in the Serial Monitor?

Yes it does. Using the minicom serial monitor, my arduino program works flawlessly. It outputs the data in a readable format, and allows me to input and store the variables needed for the rest of the program to function properly.

Can you post a sample of the (incorrect) data received by your C++ program?

Well this is what I'm getting for the moment when I run the program.

It is going down like 5 lines in my terminal for some reason, indicating that the board is saying something and my program is receiving it, but is not displaying? Maybe I'm just off base here and have no clue what it's doing I'm not really sure. But the board SHOULD be saying this:

Serial.println("Press leftSwitch to begin!");
Serial.println("READY");

      cfsetispeed(&port_config, B9600); //set baud input to 9600 (might be wrong?)
      cfsetospeed(&port_config, B9600); //set baud output to 9600 (might be wrong?)


      port_config.c_iflag = 0; //input flags
      port_config.c_iflag &= (IXON | IXOFF |INLCR); //input flags (XON/XOFF software flow control, no NL to CR translation)
      port_config.c_oflag = 0; //output flags
      port_config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); //local flags (no line processing, echo off, echo newline off, canonical mode off, extended input processing off, signal chars off)
      port_config.c_cflag = 0; //control flags
      port_config.c_cflag &= (CLOCAL | CREAD | CS8); //control flags (local connection, enable receivingt characters, force 8 bit input)

Surely some of this section should be using "|=" , not "&=" , where you are setting rather than clearing flags?

In my own code I don't use cfsetispeed/cfsetospeed to set the baud rate. Instead it gets set in c_cflag, ie
port_config.c_cflag |= (B9600 | CLOCAL | CREAD | CS8);

The sender code you posted got cut off before it was complete, it looks like.

In the portion that is posted, the Arduino is reading from the serial port, and doing something only if there is data to read.

Nothing in the sending program is sending anything to the serial port.

Is there more code that the sender executes that you want to post?