0

TL;DR - I am attempting serial communication with Arduino with code that I found here and nothing gets sent over (Arduino programmed to respond, and I checked that it does with its serial monitor)

Hi there, I was looking for a way to send information over to an Arduino Mega (2560) unit over linux serial port by C++.

I came across the following solution: Solution I'm using this guy's code for write (I'm able to read data from the arduino) and use the same parameters (they work, as I'm able to receive data from the Ardunio). I programmed my Arduino to send "Hi" over serial whenever it sees at least 1 bit of information, and checked it worked through the Arduino IDE Serial Monitor.

Yet when running the C++ code, the arduino doesn't respond. Do anyone might have idea why?

Full disclosure - I inserted @Lunatic999's code to a class so I can make an instance of it for my needs of the code.

fd = open(portNameC, O_RDWR | O_NOCTTY | O_SYNC); //open port ("opens file")

Serial Parameters:

struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);

/* Error Handling */
if ( tcgetattr ( fd, &tty ) != 0 ) {
   std::cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << std::endl;
}

/* Save old tty parameters */
tty_old = tty;

/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);

/* Setting other Port Stuff */
tty.c_cflag     &=  ~PARENB;            // Make 8n1
tty.c_cflag     &=  ~CSTOPB;
tty.c_cflag     &=  ~CSIZE;
tty.c_cflag     |=  CS8;

tty.c_cflag     &=  ~CRTSCTS;           // no flow control
tty.c_cc[VMIN]   =  1;                  // read doesn't block
tty.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines

/* Make raw */
cfmakeraw(&tty);

/* Flush Port, then applies attributes */
tcflush( fd, TCIFLUSH );
if ( tcsetattr ( fd, TCSANOW, &tty ) != 0) {
   std::cout << "Error " << errno << " from tcsetattr" << std::endl;
}

Write (this code I put inside a function which I call)

unsigned char cmd[] = "INIT \r";
int n_written = 0,
    spot = 0;

do {
    n_written = write( fd, &cmd[spot], 1 );
    spot += n_written;
} while (cmd[spot-1] != '\r' && n_written > 0);

Arduino code:

bool dataRecieved = false;
int ledpin = 13;

void setup() {
pinMode(ledpin, OUTPUT);
digitalWrite(ledpin, HIGH);
Serial.begin(19200);
}

void loop() {  
  while(!dataRecieved)
  {
   digitalWrite(ledpin,HIGH);
   if (Serial.available() > 0) 
   {
     dataRecieved = true;
   }
  }
  digitalWrite(ledpin,LOW);
  delay(1000);
  digitalWrite(ledpin,HIGH);
  delay(1000);
  Serial.println("hi");
}
  • @Juraj sorry, didn't post the correct version with the correct baudrate. now it is fixed. thanks! – Jordan Oct 9 '18 at 9:35
  • remove the blinking and only turn the LED off – Juraj Oct 9 '18 at 9:37
  • @Juraj nothing changed – Jordan Oct 9 '18 at 9:39
  • then the problem is on linux side and off topic here – Juraj Oct 9 '18 at 9:41
  • 1
    You are aware that the Arduino resets itself the moment you open the serial port and spends a second or so in the bootloader? During that time anything you send will be ignored completely. – Majenko Oct 9 '18 at 10:20
0

The Arduino resets the moment you open the serial port. Once reset the bootloader executes, which consumes (and discards since it's invalid) any serial data for a second or so before your sketch runs.

Because of this anything you send immediately after opening the serial port is ignored.

There are two commonly accepted "fixes" for this:

  1. Delay for a pre-defined period after opening the serial port, and
  2. Have the Arduino send a "READY" signal before doing anything else which your program waits for before sending.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.