Problems with multiple serial ports on arduino mega board

Hi there,

I'm working on a project where I need 2 Serial ports: 1 to communicate with my laptop and a second one to send information to a small 16x2 LCD display. I can get serial communication working with each device individually, but as soon as I try a sketch with both serial ports (Serial0 for the laptop, Serial2 for the LCD) only one will ever work. The Serial0 baud rate is 115200 and the LCD baud rate is 9600. I was of the understanding that this should not be a problem, but I just can't get them both to work in one sketch!

The functions setupLCD(), clearDisplay(), setLCDCursor(0) are helper functions defined else where in the file, and are known to work.

Any help/advice is appreciated! As a new user I can't upload my .ino file, so here is my test code:

void setup() {
  Serial.begin(115200);
  Serial2.begin(9600);
  setupLCD();
  clearDisplay();
  setLCDCursor(0);

  pinMode(STAGE_BUTTON, INPUT_PULLUP);
  pinMode(STAGE_LED, OUTPUT);
}

void loop() {
  clearDisplay();
  if (digitalRead(STAGE_BUTTON) == LOW) {
    digitalWrite(STAGE_LED, HIGH);
    
    Serial.print("LOW");
    
    setLCDCursor(0);
    Serial2.print("Stage set!");
    
  } else {
    digitalWrite(STAGE_LED, LOW);
    
    Serial.print("HIGH");
    
    setLCDCursor(0);
    Serial2.print("Nothing 2 report");
  }
  delay(100); 
}

Hello armorealm

Post your schematic to see how we can help.

1 Like

Welcome to the forum.

The four serial ports of the Arduino Mega are working independent in hardware and software. They all work together.

It could have to do with a missing GND wire.
Instead of a schematic, you can draw the wiring on a piece of paper and make a photo of it.

Can you show the full sketch ? My best guess is that there is a bug with an array somewhere.

which serial will work, which will fail?
What will not work exactly?

Someone could help you if you would provide a full compileable sketch.

Perhaps you meant Serial1.begin(9600);?
What pins are you using?

Hi, here's my schematic, drawn in Paint so I apologise haha.

Please post a link to the specs of this display. Most 16x2 LCD that have a "serial" interface use i²c, not UART.

Both i²c and UART are serial protocols. In Arduino projects the word "serial" is assumed to mean UART, but perhaps this is the cause of confusion here?

I initially used Serial1 but had the same problem. I then tried Serial2 thinking it might be a problem with Serial1, re-wiring to pin 16(TX) to the LCD's RX pin. Both setups have the same issue.

Hello armorealm

Post the datasheet and picture of this unknown device:

grafik

Hi noiasca,

Here is the full sketch:

#define STAGE_BUTTON 32
#define STAGE_LED 33

void setup() {
  Serial.begin(115200);
  //delay(500);
  Serial2.begin(9600);
  //delay(500);
  setupLCD();
  clearDisplay();
  setLCDCursor(0);

  pinMode(STAGE_BUTTON, INPUT_PULLUP);
  pinMode(STAGE_LED, OUTPUT);
}

void loop() {
  clearDisplay();
  if (digitalRead(STAGE_BUTTON) == LOW) {
    digitalWrite(STAGE_LED, HIGH);
    
    Serial.print("LOW");
    
    setLCDCursor(0);
    Serial2.print("Stage set!");
    
  } else {
    digitalWrite(STAGE_LED, LOW);
    
    Serial.print("HIGH");
    
    setLCDCursor(0);
    Serial2.print("Nothing 2 report");
  }

  delay(100); 
}

void setupLCD()
{
  Serial2.write(0x7C);  // send the special command
  Serial2.write(0x04);  // Set the screen to 16 characters long

  Serial2.write(0x7C);
  Serial2.write(0x06);  // Set LCD to 2 lines
}

void clearDisplay()
{
  Serial2.write(0xFE);  
  Serial2.write(0x01);  // send the clear screen command
}

void setLCDCursor(byte cursor_position)
{
  Serial2.write(0xFE);  // send the special command
  Serial2.write(0x80 + cursor_position);  // send the set cursor command
}

Which serial works seems to depend on the order they're started. Firstly the LCD works fine, but when I bring up the serial monitor on the laptop, the monitor works but the LCD stops working.

Hi @PaulRB, @paulpaulson

Ah I hadn't thought of the difference between UART and I^2C...

Here's a link to the datasheet:

Only 100mA limit on your laptop's USB port?
Got a spare USB hub with power adapter (to ensure at least 500mA per port)?

Ok, that really is a UART interface.

Reviewing your code and schematic, I can't see any reason for the problem. I think there must be something we are not considering.

1 Like

to be honest I think you miss interprete your visual result.
You are deleting to fast.

slow down the output of your loop.
only print if you have something to print.

try this - untested:

#define STAGE_BUTTON 32
#define STAGE_LED 33

void setup() {
  Serial.begin(115200);
  //delay(500);
  Serial2.begin(9600);
  //delay(500);
  setupLCD();
  clearDisplay();
  setLCDCursor(0);

  pinMode(STAGE_BUTTON, INPUT_PULLUP);
  pinMode(STAGE_LED, OUTPUT);
}

void loop() {
  clearDisplay();
  Serial2.print(millis());
  static int previousButtonState = HIGH;
  int currentButtonState = digitalRead(STAGE_BUTTON);
  if (currentButtonState != previousButtonState) {
    if (currentButtonState  == LOW) {
      digitalWrite(STAGE_LED, HIGH);
      Serial.print("LOW");
      setLCDCursor(8);
      Serial2.print("Stage set!");
      Serial2.flush();
    } else {
      digitalWrite(STAGE_LED, LOW);
      Serial.print("HIGH");
      setLCDCursor(8);
      Serial2.print("Nothing 2 report");
      Serial2.flush();
    }
  }
  previousButtonState = currentButtonState;
  delay(500); // dirty delay - slow down
}

void setupLCD()
{
  Serial2.write(0x7C);  // send the special command
  Serial2.write(0x04);  // Set the screen to 16 characters long

  Serial2.write(0x7C);
  Serial2.write(0x06);  // Set LCD to 2 lines
}

void clearDisplay()
{
  Serial2.write(0xFE);  
  Serial2.write(0x01);  // send the clear screen command
}

void setLCDCursor(byte cursor_position)
{
  Serial2.write(0xFE);  // send the special command
  Serial2.write(0x80 + cursor_position);  // send the set cursor command
}

it should print the millis over and over again.
if you change you the button - the text should change - but 500ms (!) later it will be deleted again.

describe clearly what you see.
describe what happens, when you open the serial monitor.

nice device, thanks for the link.

So when I upload the code then cycle power, the LCD counts in 500s, incrementing every 500 ms. When i bring the serial monitor up, the counting on the LCD stops straight away. But the monitor will show the button state. If I cycle power, but leave the serial monitor up, the LCD starts as per normal, but nothing on the serial when the button is pressed. If I then close and re-open the monitor, same problem. LCD stops but monitor works fine.

now please show me pictures of your setup - each wire connection must be visible.

That's going to be very hard - this project is a Kerbal Space Program controller with over 100 wires. I can assure you each wire is correctly wired, and most of the switches/buttons etc aren't doing anything at the moment as I'm testing each part separately, but have tested their functions previously.

It is almost midnight so I'm off to bed. I'll reply to anything tomorrow. Good night / have a good day :slight_smile:

The Arduino board resets when the Serial Monitor is opened. The display is not reset, so it could be in a certain state.

Is there a command to reset the display ?

void setup()
 {
  Serial.begin(115200);
  Serial.println("The sketch has started");  // Tell yourself that the board has reset

  Serial2.begin(9600);
  Serial2.write(0x ? ? some kind of reset command
  delay(500);     // maybe the display needs some time after the reset command

You could have saved a lot of time if you posted a proper annotated schematic with links to technical information on the hardware items. One good schematic will convey more information then is in this entire post.