8 years, 10 months ago.

about serial communication between pc and device

Hi there, I setup the NUCLEO F446Re to connect to PC via the USB (JLink). I am developing a code to send 10 characters from PC to NUCLEO via serial ports. Once I get the string, I light up one of the led and then send the first 3 characters from the received string back to the PC via the serial port. I have my code as follows

#include "mbed.h"
 
 Serial micro(USBTX, USBRX);
 Serial pc(SERIAL_TX, SERIAL_RX);
 DigitalOut myled(LED1);
 int err;
 char data[256];
 
 
int main() 
{ micro.format(8, Serial::None, 1);
  micro.baud(9600);
  char s[100];

  myled = 0;  
  while(1) 
  { 
   if (micro.readable()) 
   {
    err = micro.scanf("%s", data);
    break;
   }
  }
    
  myled = 1;
  strncpy(s, data, 3);
  while(1)
  {
    if (pc.writeable())
    {
      pc.printf("%s\n", s);
      //break;            
    }
  }
  myled = 0;
}

In the second serial communication from the board to pc, I want to break the loop once the data sent. But if I add the break command, the code doesn't work, pc never receive the data. But if I remove the last 'break', the pc can receive the data without any problem.

Both pc and board are setup to use the same protocol, baud 9600, data bits=8 and etc.

---------------------- Update of my question: I modify my code as follows:

#include "mbed.h"
 
 Serial micro(USBTX, USBRX);
 Serial pc(USBTX, USBRX);
 DigitalOut myled(LED1);
 int err;
 char data[256];

int main() 
{ micro.format(8, Serial::None, 1);
  micro.baud(9600);
    
  myled = 1;
  while(1) 
  { 
    if (micro.readable()) 
    {
      err = micro.scanf("%s", data);
      break;
    }
  }
  myled = 0;
   
  while(1)
  {
    if (pc.writeable())
    {
      pc.printf("%s\n", data);
      break;            
    }
  }
 
  while (1) {myled = !myled; wait(0.5);};
}

I break the code into two parts. First part is micro's reading from a pc serial. Second part is pc's reading from a micro serial.

In the first part, the code wait in the while until pc send the data. After the data received, The led will be turned off. In the second while, I expect the device wait until the pc is ready to receive the data. But it is not, it directly pass the while and go into the very last while (for led blinking).

I think the pc.writable doesn't work.

1 Answer

8 years, 10 months ago.

Try adding a while(1); at completley the end of your code. I don't know exactly what happens when the end of code is reached, it might stop sending due to that.

I try to add the while (1) at the very end of the main and put the 'break' back to the while. This makes the code work for some times. I don't understand why. I turn on the led before the second while (1), that is it will wait until the pc is writable, and I turn off the led after writing to pc. But I just find that some times it seems like it does not wait the pc is writeabe (or always writable?) so it will jump out the while once I run the code or reset the board.

I am thinking if the communication got messed up because both pc and micro use the same USB link for serial communication?

posted by kim jone 31 Jan 2016

No that is no problem, it is designed to handle that. But what happens exactly with which code?

posted by Erik - 31 Jan 2016

The problem is the second serial operation doesnt work. I updated my question and code for my concern.

posted by kim jone 31 Jan 2016

The PC is almost always available for writing, so that should happen immediatly indeed. However you do not receive anything on your PC? And the LED starts blinking at the end?

posted by Erik - 01 Feb 2016

Yes, The PC doesn't receive anything and it simply skip it and run all the way to the end. I use labview's virtual com library to send/receive data to/from the device. I set the timeout to be very long and I still get error on that. But if I separate the send and receive code in the device, that is, test only send something to PC. I didn't get any problem at all.

posted by kim jone 01 Feb 2016

What if you change your send code into for example: pc.printf("Hello: %s\n", data);

posted by Erik - 01 Feb 2016

Hi Erik, I added the "Hello:" ahead the data to be sent. I may find the reason causing the issue. Do you know what writeable() really do? I think it will keep checking the buffer is ready to write or not, right? So what happens if the PC program is not yet started but the device is trying to send data over? Shall writeable return true or false in that case? I found that if I don't run the PC program before the device's writeable() being called, it will skip the writeable (that is returns true always) and will send the "Hello:" anyway. But if I run the PC program at right time ahead the device's printf, the PC get the data sometimes. The PC program will poll if there is data from serial port ready to ready or not. It has a timeout option to set so it will wait until the timeout. I expect the mbed serial function has timeout as well but it seems that it doesn't or it should wait the PC ready before it return from writeable()?

posted by kim jone 01 Feb 2016

Writable only checks if the Serial link is free (which is connected to the USB interface chip). There is no flow control, so it does not care at all if someone is actually listening to it.

posted by Erik - 01 Feb 2016

it makes sense. So how do we guarantee the correct hand shaking built up between the pc and the micro. Is it any way that the device or pc wait until the other is listening?

posted by kim jone 02 Feb 2016

Something like you are already doing, where you only transmit data after your micro received something specifically from your labview, indicating it is ready to receive.

posted by Erik - 02 Feb 2016