Serial.write Only Works When the Serial monitor is open.

Im having an issue with my Arduino mega 2560. It seems to stop Sending message through the Serial.write after a few messages have been sent. I need to physically open the Serial monitor for it to continue sending and it would stop sending soon after the monitor is closed. How do I fix this issue?

You need to post your program so we can see what might be causing it to crash.

Opening the Serial Monitor causes the Mega to reset and recover from the crash.

...R

its Code for blue tooth communication between An Uno and an Arduino Mega 2560. The serial port sends signal from potentiometer readings to the Uno. The message is then used to set a brushless motor though ESC. The receiver end (The Uno) seems to work fine but the Mega just crashes within 20 seconds of sending messages.

The Mega Code-Master.

#include <Servo.h>
int LedPin=5;
int LedPin2=4;
int ButtonPin3=12;
int Anlg4=A4;
int Anlg5=A5;
int CurrentPotState=0;
char state3[6]="0000-";
String content = "";
bool SignalEnd=false;
int MessTime=70;
int HoldTime=70;
int potValue;
int CurrentPower=0;
//Servo ESC;
void setup() {
  // put your setup code here, to run once:
  pinMode(LedPin,OUTPUT);pinMode(LedPin2,OUTPUT);
  pinMode(ButtonPin3,INPUT);
  Serial.begin(9600);
  digitalWrite(LedPin,LOW);
ESC.attach(10,1000,2000);
}

void loop() {
  char character;
  while(Serial.available()) {
      SignalEnd=false;
      character = Serial.read();
      //Serial.println(character);
      if(character=='-'){SignalEnd=true;break;}
      content.concat(character);
  }
  if (SignalEnd==true) {
      if(content[1]=='5'){
          if(digitalRead(LedPin)==HIGH){digitalWrite(LedPin,LOW);}
          else{digitalWrite(LedPin,HIGH);}
      }
      if(content[1]=='9'){
        if(digitalRead(LedPin2)==HIGH){digitalWrite(LedPin2,LOW);}
        else{digitalWrite(LedPin2,HIGH);}
      }
      content = "";
   }
  if(millis()>MessTime){
      MessTime+=HoldTime;
      potValue = analogRead(Anlg5);
      potValue = map(potValue, 0, 1023, 0, 180); 
      if(CurrentPower==potValue){}
      else{
        CurrentPower=potValue;
        itoa(potValue,state3,10);
        state3[5]='-';//
        Serial.write(state3,5);//
      }
  }
    // reads the value of the potentiometer (value between 0 and 1023)
   // scale it to use it with the servo library (value between 0 and 180)
    // Send the signal to the ESC

}

Uno Code-Slave :

#include <Servo.h>
int LedPin=12;
int ButtonPin=7;
int ButtonPin2=4;
Servo ESC;
char Signal[6]="15941-";
char Signal2[6]="79483-";
bool SignalEnd=false;
String content = "";
long Data;
int MessTime=0;
int HoldTime=500;
int potValue;
void setup() {
  // put your setup code here, to run once:
  pinMode(LedPin,OUTPUT);
  pinMode(ButtonPin,INPUT);
  pinMode(ButtonPin2,INPUT);
  Serial.begin(9600);
  digitalWrite(LedPin,LOW);
  ESC.attach(10,1000,2000);
}

void loop() {
  char character;
  while(Serial.available()) {
     SignalEnd=false;
     character = Serial.read();
     if(character=='-'){SignalEnd=true;break;}
     content.concat(character);
  }
  if (SignalEnd==true) {
      Data=content.toInt();
      content = "";
  }
  if(Data>1){
      ESC.write(Data);  
      Data=0;
  }
  else{ 
      Data=0;
  }
  if(digitalRead(ButtonPin)==HIGH){
       Serial.write(Signal,6);
  }
  else{ }
  if(digitalRead(ButtonPin2)==HIGH){
    Serial.write(Signal2,6);
 }
  else{}
  // put your main code here, to run repeatedly:
}

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

...R

Thank you, it helps a lot But the issue seems to still exist. it seems to mainly occur when the Mega is Sending rather than receiving.

#include <Servo.h>
int LedPin=5;
int LedPin2=4;
int ButtonPin3=12;
int Anlg4=A4;
int Anlg5=A5;
int CurrentPotState=0;
char state3[6];
int MessagePosition=0;
String content = "";
const byte Size=6;
char RecievedMessage[Size];
bool SignalEnd=false;
int MessTime=70;
int HoldTime=70;
int potValue;
int CurrentPower=0;
//Servo ESC;
void setup() {
  // put your setup code here, to run once:
  pinMode(LedPin,OUTPUT);pinMode(LedPin2,OUTPUT);
  pinMode(ButtonPin3,INPUT);
  Serial.begin(9600);
  digitalWrite(LedPin,LOW);
//ESC.attach(10,1000,2000);
}

void loop() {
  ReadMessage();
  if (SignalEnd==true) {
     HandleData();
   }
  if(millis()>MessTime){
      MessTime+=HoldTime;
      potValue = analogRead(Anlg5);
      potValue = map(potValue, 0, 1023, 0, 180); 
      if(CurrentPower==potValue){}
      else{
        CurrentPower=potValue;
        itoa(potValue,state3,10);
        state3[4]='-';//WARNING THIS COULD CAUSE AN ISSUE LATER! KEEP IN MIND!!!!!!!!
       state3[5]='\0';
        Serial.write(state3,6);//TIHS IS COMMENTED OUT,PUT IT BACK.
      }
  }
    // reads the value of the potentiometer (value between 0 and 1023)
   // scale it to use it with the servo library (value between 0 and 180)
    // Send the signal to the ESC

}


void HandleData(){
 if(RecievedMessage[1]=='5'){
         //Serial.println("here");
          if(digitalRead(LedPin)==HIGH){digitalWrite(LedPin,LOW);}
          else{digitalWrite(LedPin,HIGH);}
      }
      if(RecievedMessage[1]=='9'){
        if(digitalRead(LedPin2)==HIGH){digitalWrite(LedPin2,LOW);}
        else{digitalWrite(LedPin2,HIGH);}
      }  
  }

  void ReadMessage(){
      char character;
  if(Serial.available()>0){
      SignalEnd=false;
      character = Serial.read();
      //Serial.println(character);
      if(character=='-'){SignalEnd=true;MessagePosition=0; RecievedMessage[MessagePosition]='\0';}
      else{RecievedMessage[MessagePosition]=character;
      MessagePosition++;}
      //content.concat(character);
  }
    
    }

The Mega was working for long hours with no issues before I added this section right here.

 if(millis()>MessTime){
      MessTime+=HoldTime;
      potValue = analogRead(Anlg5);
      potValue = map(potValue, 0, 1023, 0, 180); 
      if(CurrentPower==potValue){}
      else{
        CurrentPower=potValue;
        itoa(potValue,state3,10);
        state3[4]='-';//
       state3[5]='\0';
        Serial.write(state3,6);//
      }
  }

This is not the correct way to use millis()

if(millis()>MessTime){

See how it is done in Several Things at a Time

...R

Thank you, I made a few adjustments and now it works but the time it takes to send a signal and process it started to drift. It starts with the Signal being processed really quickly and the process time gets slower and slower with time. Do you know anything that could cause such issue?

Slave:

#include <Servo.h>
const byte Size=4;
char RecievedMessage[Size];
int MessagePosition=0;
int LedPin=12;
int ButtonPin=7;
int ButtonPin2=4;
int Button1Bool=false;
int Button2Bool=false;
Servo ESC;
char Signal[4]="200-";
char Signal2[4]="300-";
bool SignalEnd=false;
//String content = "";
int Data;
int MessTime=0;
int HoldTime=500;
int potValue;
void setup() {
  // put your setup code here, to run once:
  pinMode(LedPin,OUTPUT);
  pinMode(ButtonPin,INPUT);
  pinMode(ButtonPin2,INPUT);
  Serial.begin(9600);
  digitalWrite(LedPin,LOW);
  ESC.attach(10,1000,2000);
}

void loop() {
ReadMessage();

  if(Data>1){
    
    digitalWrite(LedPin,HIGH);
      ESC.write(Data);  
      Data=0;
  }
  else{ 
      digitalWrite(LedPin,LOW);
      Data=0;
  }
  if(digitalRead(ButtonPin)==HIGH && Button1Bool==false){
       Serial.write(Signal,4);
  Button1Bool=true;
  }
  else if(digitalRead(ButtonPin)==LOW) {Button1Bool=false; 
  }
  
  if(digitalRead(ButtonPin2)==HIGH && Button2Bool==false){
    Serial.write(Signal2,4);
 Button2Bool=true;
 }
  else if(digitalRead(ButtonPin2)==LOW){
    Button2Bool=false;
    }
 SignalEnd=true;
  // put your main code here, to run repeatedly:
}


 void ReadMessage(){
      char character;
  if(Serial.available()>0){
      SignalEnd=false;
      character = Serial.read();
      //Serial.println(character);
     
      if(character=='-'){
        SignalEnd=true;
        
        RecievedMessage[MessagePosition]='\0';
        MessagePosition=0;
      // strncpy(Buff,RecievedMessage,4);
       Data=atoi(RecievedMessage);
      // Serial.write(Data);
        }
      else{RecievedMessage[MessagePosition]=character;
      
      MessagePosition++;
      
      }
      //content.concat(character);
      
  }
    
    }

Master:

#include <Servo.h>
int LedPin=5;
int LedPin2=4;
int ButtonPin3=12;
int Anlg4=A4;
int Anlg5=A5;
int CurrentPotState=0;
char state3[4];
int MessagePosition=0;
String content = "";
const byte Size=4;
char RecievedMessage[Size];
char Buff[Size];
bool SignalEnd=false;
long  MessTime=0;;
int HoldTime=0;
int interval=130;
int potValue;
int CurrentPower=0;
int Data;
//Servo ESC;
void setup() {
  // put your setup code here, to run once:
  pinMode(LedPin,OUTPUT);pinMode(LedPin2,OUTPUT);
  pinMode(ButtonPin3,INPUT);
  Serial.begin(9600);
  digitalWrite(LedPin,LOW);
//ESC.attach(10,1000,2000);
}

void loop() {
  ReadMessage();
  if (SignalEnd==true) {
     //
    //Serial.print(RecievedMessage[0]);
   // Serial.print(RecievedMessage[1]);
    //Serial.print(RecievedMessage[2]);
    //Serial.print(RecievedMessag[4]);
   // Serial.print(RecievedMessage[5]);
   // Serial.print(RecievedMessage[6]);
     //ConvertDataToInt();
     
    
     HandleData();
   }
  MessTime=millis();
  if(MessTime-HoldTime>interval){
      
      HoldTime=MessTime;
      potValue = analogRead(Anlg5);
      potValue = map(potValue, 0, 1023, 0, 180); 
      if(CurrentPower==potValue){}
      else{
        CurrentPower=potValue;
        itoa(potValue,state3,10);
        state3[4]='-';//WARNING THIS COULD CAUSE AN ISSUE LATER! KEEP IN MIND!!!!!!!!
       //state3[5]='\0';
        Serial.write(state3,5);//TIHS IS COMMENTED OUT,PUT IT BACK.
      }
  }
    // reads the value of the potentiometer (value between 0 and 1023)
   // scale it to use it with the servo library (value between 0 and 180)
    // Send the signal to the ESC

}


void HandleData(){
 
 if(Data>190 && Data<280){
         //Serial.println("here");
          if(digitalRead(LedPin)==HIGH){digitalWrite(LedPin,LOW);}
          else{digitalWrite(LedPin,HIGH);}
      }
      if(Data>280 && Data<320){
        if(digitalRead(LedPin2)==HIGH){digitalWrite(LedPin2,LOW);}
        else{digitalWrite(LedPin2,HIGH);}
      }  
  SignalEnd=false;
  }

  void ReadMessage(){
      char character;
  if(Serial.available()){
      SignalEnd=false;
      character = Serial.read();
      //Serial.println(character);
     
      if(character=='-'){
        SignalEnd=true;
        
        RecievedMessage[MessagePosition]='\0';
        MessagePosition=0;
      // strncpy(Buff,RecievedMessage,4);
       Data=atoi(RecievedMessage);
       //Serial.print(Data);
        }
      else{RecievedMessage[MessagePosition]=character;
      
      MessagePosition++;
      
      }
      //content.concat(character);
      
  }
    
    }

You seem to have created something that is a bit like one of the examples in my Serial Input Basics

If you just use the function from my example completely unchanged it will make it much easier to help as then I can focus my attention on the code you have written.

Also I don't understand what you mean by "the process time gets slower and slower". Do you mean that interval between messages increases or do you mean that after a message is received it takes longer to deal with the received data?

...R

Im not sure. the Serial monitor's Serial.write remains the same speed when it comes to writing messages but the Led (and motor) response to that message becomes highly delayed with time. But if I reset the Mega(which is the one writing messages), then it goes back to normal and slows down with time again.

I'll look into your suggestion and see if it works then. you have been a huge help, I appreciate it, thank you.