PlatformIO Community

How to make serial.read work in the serial monitor?

Hi,

I can’t make serial.read work in the serial montor, as in:

  if ( Serial.available() > 0) {
    char c = Serial.read();

    if ( c == 'i') { mode = INSERT; printMenu();}
    if ( c == 'd') { mode = DELETE; printMenu();}
    if ( c == 'n') { mode = NORMAL; printMenu();}
  }

This works in the Aduino IDE monitor as expected. In the PlatformIO monitor all keyboard input seems to be ignored.

Am I overlooking something here?

Dennis

I know you need some patience here, but two weeks is a long time… There must be someone with a little more experience here.

Do you use correct baudrate?

Yes, of course. Otherwise the other print statements would not come true, like printing the menu.

So you’re stating this normally should work as designed.

Tried another simple example piece of code:

#include <Arduino.h>

void setup()
{
  Serial.begin( 9600);
  Serial.println( "Ready for input");
}

void loop()
{
  char c;

  if ( Serial.available() > 0) {
    c = Serial.read();

    Serial.print  ( "Char = ");
    Serial.println( c, DEC);
  }
}

First println is shown correctly, nothing happens after that, no matter what key I press.

Am I the only one again?

What is your operation system?

Currently Windows 10 x64

Just found out that ctrl-C to stop the serial monitor stream does not work as well. I think it is connected to my other problem.

Any new thoughts (apart from re-installing everything)?

Three years later …

Were you able to sort this out? I’m running into the same issue. I don’t know how to input to Serial monitor.

Alright, so I just learned from this post Advanced Standalone Serial Monitor that every character that is written into terminal is transmitted to serial. To verify that, I wrote the following short code:

#include <Arduino.h>

void setup() {
  // initiate Serial
  Serial.begin(115200); 
  // wait for serial to come online
  while(!Serial); 
  Serial.println("Serial is ready to accept input");
}

void loop() {
  // put your main code here, to run repeatedly:
}

void serialEvent(){
  while(Serial.available()){
    Serial.print("Serial received > ");
    Serial.println((char)Serial.read());
  }
}

And it behaves as expect. Now I’m going to go research how to transmit only when pressing enter of something like that. I would like to send a character array instead of single characters.

There’s some info on this thread that might help. It covers coolterm, which can be configured to send a complete line of text similar to the Arduino serial monitor.

Also, how to configure the PlatformIO default monitor to send complete lines instead of character by character.

HTH

Cheers,
Norm.

2 Likes

I was at that time running platformio on Atom, later switched to VSCode and the issue disappeared with that.

1 Like

Sorry @DennisB66, I was intending my reply to go to @OmarAlamoudi - I’ve obviously hit the wrong “reply” button. My apologies.

Cheers,
Norm.

I read it, bit it got complicated a bit. But i’ll spend more time in the next few days and will post an update.

Surprising though, I found out that Serial.read() needs a delay(2) to operate properly. Without the delay, not even the Arduino IDE serial input work as I want it to.

Thank you guys for an engaging conversation.

Cheers,
Omar

Thank you all for your help. @NormanDunbar, I read that post, and I tried to type fast, but I was never fast enough lol.

Anyway, I finally utilized a 2 msec delay after Serial.read() and it is working as expected now. I tried using 1 msec, but that wasn’t sufficient.

Working solution

I tried the following two codes using PIO on VSCode and Arduino IDE and the results are identical. The only difference between the codes below is one utilizes the serialEvent() function while the other one includes a while(Serial.available()) inside the main loop().

Code 1: serialEvent() implementation

char input[64];
bool inputReadingCompleted = false;

void setup() {
  // initiate Serial
  Serial.begin(115200); 
  // wait for serial to come online
  while(!Serial); 
  Serial.println("Serial is ready to accept input");
}

void loop() {
}

void flushInput(){
  for (int i = 0; i < 64; i++){
    input[i] = {};
  }
}

void serialEvent(){
  int i = 0;
  while(Serial.available()){
    input[i] = Serial.read();
    delay(2);
    i++;
    inputReadingCompleted = !(Serial.available());
  }

  // printing the input
  if (inputReadingCompleted){ // if input
    Serial.print("Serial input = ");
    Serial.println(input);
    inputReadingCompleted = false;
    flushInput();
  }
}

Code 2: main loop() implementation

char input[64];
bool inputReadingCompleted = false;

void setup() {
  // initiate Serial
  Serial.begin(115200); 
  // wait for serial to come online
  while(!Serial); 
  Serial.println("Serial is ready to accept input");
}

void loop() {
  int i = 0;
  while(Serial.available()){
    input[i] = Serial.read();
    delay(2);
    i++;
    inputReadingCompleted = !(Serial.available());
  }

  // printing the input
  if (inputReadingCompleted){ // if input
    Serial.print("Serial input = ");
    Serial.println(input);
    inputReadingCompleted = false;
    flushInput();
  }
}

void flushInput(){
  for (int i = 0; i < 64; i++){
    input[i] = {};
  }
}

Hi @OmarAlamoudi,

I’m glad to hear that youhave it working now.

I wonder. I’ve written an interrupt driven USART tool, similar to the SerialnMonitor. It works perfectly at all speeds up to, and over 115200.

At that one speed/baud, it is total garbage. Almost nothing looks right. I checked the data sheet and calculated that the error rate is about 3.5% which is well out of the approved range of +/- 0.5%.

Does your code work fine, without the delay, at other speeds? Just interested. Thanks.

Cheers,
Norm.

So I’ve only needed to get as technical as a solution I need to implement requires. So I didn’t bother yet learning the details of what and how different baud rates affect my implementation. I was once told that 115200 is what I need, and I never bother looking into the details lol. So forgive me if my following answer isn’t adequate.

What I can tell you is, when I remove the delay(2) statement after Serial.read(), the only way I would get the monitor to accept more than a single character at a time is to send a long array of character (e.g. “how is is this not working as expected?”). This works but it is not predictable. Meaning, it works sometimes and sometimes it doesn’t.

work = more than one character is received and printed back

not work = a single character at time.

The only two baud rates I usually use are: 9600, and 115200

If you have any further questions, I would be happy to help.

By the way, I remember reading about your USART tool somewhere, but I don’t recall where that was. Do you mind sharing a link to it? Thanks

Omar

Thanks @OmarAlamoudi for the feedback.

Not mine I’m afraid. Mine was written specifically for a new book I’m writing for Apress. It’s not finished yet, but when it (the book) is the code will be available on the Apress github.

It works as a much smaller replacement for the Serial interface on Arduinos, and works in plain AVR code, under PlatformIO too.

Cheers,
Norm.

Great!

Thank you.

Omar