ARDUINO MEGA Serial Interrupt

Hi i am trying to run arduino mega interrupts .

I just want to send Serial port 0 rx data to Serial port1 tx and Serial port1 rx data to Serial port 0 tx USING INTERRUPT

when i try to disable serialEvent() code and active without interrupt loop it works great . but it is not working in interrupt. Please Help me

HERE IS CODE

//////////////////////// void setup() { Serial.begin(9600); Serial1.begin(9600); } /////////////////////////////////////////

void serialEvent() { char x=Serial.read(); Serial1.write(x); } void serialEvent1() { char y=Serial1.read(); Serial.write(y); }

//////////////////////////////////////////////////////// void loop() { Serial.println("1111111111"); Serial1.println("0000000000"); /* while(1)///////////WITHOUT INTERRUPT LOOP { if (Serial1.available()) Serial.write(Serial1.read()); else delay(1); } */ while(1);

}

Why would you want to use interrupts? Nothing to do with serial data transmission is fast or fleeting.

You should not use Serial calls in a ISR - partly because they need interrupts and interrupts are offf in an ISR and partly because they are slow and the code in an ISR should complete as fast as possible.

And please use the code button </>so your code looks like thisand is easy to copy to a text editor

Have a look at Serial Input Basics - simple reliable non-blocking ways to receive data,

…R

The Arduino runtime is already handling those interrupts for you - you probably need to study what it does before tinkering so as to play well with the Arduino runtime.

Well i just want to use hardware interrupt of serial communication.

Same like External interrupt.

I want to get serial byte as it is received in rx buffer.

when i try to disable serialEvent() code and active without interrupt loop
it works great .
but it is not working in interrupt.

serialEvent() does not interrupt running code. Rather it waits patiently until the end of the loop() function and then, if serial data is available, the serialEvent() function runs if it exists.

You may well ask “why don’t I just check whether serial data is available in my program ?”
Good question !

The serial interrupt is already doing what you want, pulling a character from serial and putting it in a buffer. You don't need to or want to rewrite it.

Ok, I'll throw this out there: NeoHWSerial is a modified version of HardwareSerial that lets you attach a function to the RX interrupt. You must change all uses of SerialX to NeoSerialX to avoid linking in both HardwareSerial and NeoHWSerial in the same executable.

I don't really recommend it in this case, because you are trying to do something (write a char) that depends on interrupts during the RX interrupt. Small timing difference between receiving and sending can cause the write to block... during the RX interrupt. Bad.

If you need to do something with the char that doesn't involve interrupts (e.g., a calculation or parsing), it's an ok thing to use. This can be handy if something else is blocking for too long, and you're losing chars because of input buffer overflow. But anything that might depend on interrupts, like serial.write or millis, cannot be performed in the interrupt function. Just set a flag or value and watch for it in loop. We're all wondering why you don't do this:

void loop()
{
  while (Serial.available())
    Serial1.write( Serial.read() );
  while (Serial1.available())
    Serial.write( Serial1.read() );
}

Cheers, /dev

Thanks /Dev for you kind reply.
basically i am microchip pic programmer . and i have a big library for PICS.
I want to modify that libraries for arduino.
i have run one serial event using timer interrupt using.
my timer checks serial event and generates flag to indicate if any interrupt is generated.

you can see the code below.

#include <TimerOne.h>
String     cell="               ";
String     ready_string="        ";
int     serial_flag=0;
int     voters=0;
int pti_voters=0;
int pmln_voters=0;
int ppp_voters=0;
int ji_voters=0;
////////////////////////
  void setup() {
   Serial.begin(9600);
   Timer1.initialize(500000);
   Timer1.attachInterrupt(timerOne_iterrupt);
   Serial.println("1111111111");
   serial_flag=1;
}
 
////////////////////////////////////////
  void timerOne_iterrupt()
  {
  serialEvent(); 
  }
////////////////////////////////////////////////////////
void loop()
{

if(serial_flag!=0)
{
      if(serial_flag==1)  Serial.print( cell);
 else if(serial_flag==2)  Serial.print( ready_string);
 else if(serial_flag==3)  Serial.println(voters);
 else if(serial_flag==4)  Serial.println(pti_voters);
 else if(serial_flag==5)  Serial.println(pmln_voters);
 else if(serial_flag==6)  Serial.println(ppp_voters);
 else if(serial_flag==7)  Serial.println(ji_voters);
 serial_flag=0;
}
}
///////////////////////////////

void serialEvent() {
  if(Serial.available()) 
  {
    char x=Serial.read();
         if(x=='#' ){        cell=Serial.readString();serial_flag=1;}
    else if(x=='

){ready_string=Serial.readString();serial_flag=2;}
    else if(x==’*’ ){voters=Serial.parseInt();        serial_flag=3;}
    else if(x==’!’ ){ pti_voters=Serial.parseInt();  serial_flag=4;}
    else if(x==’@’ ){pmln_voters=Serial.parseInt();  serial_flag=5;}
    else if(x==’<’ ){ppp_voters=Serial.parseInt();    serial_flag=6;}
    else if(x==’>’ ){ji_voters=Serial.parseInt();    serial_flag=7;}
    else            {String abc=Serial.readString();serial_flag=0;  }                     
  }   
  }

irfan3000: and i have a big library for PICS. I want to modify that libraries for arduino. i have run one serial event using timer interrupt using.

That is a bit like changing from a Ford car to a Volkswagen and wanting to discard the perfectly good Volkswagen engine and put a Ford engine in it.

Use the Arduino libraries for the Arduino.

...R

That is a bit like changing from a Ford car to a Volkswagen and wanting to discard the perfectly good Volkswagen engine and put a Ford engine in it.

It's more like dumping the Volkswagen engine and putting in a set of pedals and a chain drive.

o_O

  • Indentation.
  • Calling a blocking function from an ISR.
  • Using the String class.
    Some would call that three strikes. I call that a “learning opportunity”. :slight_smile: If you’d be interested, here are some things I would suggest. For the first two issues:
String cell         = "               ";
String ready_string = "        ";
int    serial_flag  = 1;
int    voters       = 0;
int    pti_voters   = 0;
int    pmln_voters  = 0;
int    ppp_voters   = 0;
int    ji_voters    = 0;

////////////////////////
void setup()
{
   Serial.begin(9600);
   Serial.println("1111111111");
}

////////////////////////////////////////////////////////
void loop()
{
  if (Serial.available()) {
    char x=Serial.read();
         if (x=='#') { cell        = Serial.readString(); serial_flag=1;}
    else if (x=='

Notice that the timer interrupt is not required. loop just runsrunsruns until the user types something. And you’re not blocking inside the timer ISR.

Also notice the readability. Proper indentation makes it very easy to read. When you want help, or when you are looking for a bug, nothing is more important than READABILITY.

Next, try using a switch statement instead of a mess o’ ifs:

String cell         = "               ";
String ready_string = "        ";
int    serial_flag  = 1;
int    voters       = 0;
int    pti_voters   = 0;
int    pmln_voters  = 0;
int    ppp_voters   = 0;
int    ji_voters    = 0;

////////////////////////
void setup()
{
   Serial.begin(9600);
   Serial.println("1111111111");
}

////////////////////////////////////////////////////////
void loop()
{
  if (Serial.available()) {
    char x=Serial.read();
    switch (x) {
      case '#': cell        = Serial.readString(); serial_flag=1; break;
      case '

And finally, quit using the String class, for a multitude of reasons:

char cell[16];
char ready_string[10];
int  serial_flag  = 1;
int  voters       = 0;
int  pti_voters   = 0;
int  pmln_voters  = 0;
int  ppp_voters   = 0;
int  ji_voters    = 0;

////////////////////////
void readStr( char str[], size_t maxchars )
{
  size_t length = Serial.readBytes( str, maxchars-1 );
  str[ length ] = '\0'; // NUL-terminate the char array
}

////////////////////////
void skipCommand()
{
  unsigned long startTime = millis();
  do {
    while (Serial.available())
      Serial.read();
  } while (millis() - startTime < 1000);
}

////////////////////////
void setup()
{
   Serial.begin(9600);
   Serial.println("1111111111");
}

////////////////////////
void loop()
{
  if (Serial.available()) {
    char x=Serial.read();
    switch (x) {
      case '#':
        readStr( cell, sizeof(cell) );
        serial_flag=1;
        break;
      case '

Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. :wink:

The next thing you should look at is Robin2’s Serial Input Basics, reachable from the very Useful Links page. Your current program “blocks” to read a command. Until the entire line is received, nothing else in your sketch will be executed.

Serial Input Basics has several examples that show how you can keep loop runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the “same” time.

Cheers,
/dev) { ready_string= Serial.readString(); serial_flag=2;}
   else if (x==’*’) { voters      = Serial.parseInt  (); serial_flag=3;}
   else if (x==’!’) { pti_voters  = Serial.parseInt  (); serial_flag=4;}
   else if (x==’@’) { pmln_voters = Serial.parseInt  (); serial_flag=5;}
   else if (x==’<’) { ppp_voters  = Serial.parseInt  (); serial_flag=6;}
   else if (x==’>’) { ji_voters   = Serial.parseInt  (); serial_flag=7;}
   else             { String abc  = Serial.readString(); serial_flag=0;}
 }

if (serial_flag!=0) {
       if (serial_flag==1) Serial.print  ( cell         );
  else if (serial_flag==2) Serial.print  ( ready_string );
  else if (serial_flag==3) Serial.println( voters       );
  else if (serial_flag==4) Serial.println( pti_voters   );
  else if (serial_flag==5) Serial.println( pmln_voters  );
  else if (serial_flag==6) Serial.println( ppp_voters   );
  else if (serial_flag==7) Serial.println( ji_voters    );
  serial_flag=0;
 }
}


Notice that the timer interrupt is not required. **loop** just runsrunsruns until the user types something. And you're not blocking inside the timer ISR.

Also notice the readability. Proper indentation makes it very easy to read. When you want help, or when you are looking for a bug, nothing is more important than READABILITY.

Next, try using a **switch** statement instead of a mess o' **if**s:

§DISCOURSE_HOISTED_CODE_1§


And finally, quit using the **String** class, for a [multitude](http://forum.arduino.cc/index.php?topic=382944.msg2640860#msg2640860) [of](http://forum.arduino.cc/index.php?topic=396099.msg2726746#msg2726746) [reasons](http://forum.arduino.cc/index.php?topic=385867.msg2661171#msg2661171):

§DISCOURSE_HOISTED_CODE_2§


Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. ;)

The next thing you should look at is Robin2's **Serial Input Basics**, reachable from the very [Useful Links](http://forum.arduino.cc/index.php?topic=384198.0) page. Your current program "blocks" to read a command. Until the entire line is received, nothing else in your sketch will be executed.

**Serial Input Basics** has several examples that show how you can keep **loop** runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the "same" time.

Cheers,
/dev: ready_string= Serial.readString(); serial_flag=2; break;
      case '*': voters      = Serial.parseInt  (); serial_flag=3; break;
      case '!': pti_voters  = Serial.parseInt  (); serial_flag=4; break;
      case '@': pmln_voters = Serial.parseInt  (); serial_flag=5; break;
      case '<': ppp_voters  = Serial.parseInt  (); serial_flag=6; break;
      case '>': ji_voters   = Serial.parseInt  (); serial_flag=7; break;
      default :               Serial.readString(); serial_flag=0; break;
    }
  }

  if (serial_flag!=0) {
    switch (serial_flag) {
      case 1: Serial.print  ( cell         ); break;
      case 2: Serial.print  ( ready_string ); break;
      case 3: Serial.println( voters       ); break;
      case 4: Serial.println( pti_voters   ); break;
      case 5: Serial.println( pmln_voters  ); break;
      case 6: Serial.println( ppp_voters   ); break;
      case 7: Serial.println( ji_voters    ); break;
    }
    serial_flag=0;
  }
}

And finally, quit using the String class, for a multitude of reasons:

§_DISCOURSE_HOISTED_CODE_2_§

Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. :wink:

The next thing you should look at is Robin2’s Serial Input Basics, reachable from the very Useful Links page. Your current program “blocks” to read a command. Until the entire line is received, nothing else in your sketch will be executed.

Serial Input Basics has several examples that show how you can keep loop runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the “same” time.

Cheers,
/dev) { ready_string= Serial.readString(); serial_flag=2;}
   else if (x==’*’) { voters      = Serial.parseInt  (); serial_flag=3;}
   else if (x==’!’) { pti_voters  = Serial.parseInt  (); serial_flag=4;}
   else if (x==’@’) { pmln_voters = Serial.parseInt  (); serial_flag=5;}
   else if (x==’<’) { ppp_voters  = Serial.parseInt  (); serial_flag=6;}
   else if (x==’>’) { ji_voters   = Serial.parseInt  (); serial_flag=7;}
   else             { String abc  = Serial.readString(); serial_flag=0;}
 }

if (serial_flag!=0) {
       if (serial_flag==1) Serial.print  ( cell         );
  else if (serial_flag==2) Serial.print  ( ready_string );
  else if (serial_flag==3) Serial.println( voters       );
  else if (serial_flag==4) Serial.println( pti_voters   );
  else if (serial_flag==5) Serial.println( pmln_voters  );
  else if (serial_flag==6) Serial.println( ppp_voters   );
  else if (serial_flag==7) Serial.println( ji_voters    );
  serial_flag=0;
 }
}


Notice that the timer interrupt is not required. **loop** just runsrunsruns until the user types something. And you're not blocking inside the timer ISR.

Also notice the readability. Proper indentation makes it very easy to read. When you want help, or when you are looking for a bug, nothing is more important than READABILITY.

Next, try using a **switch** statement instead of a mess o' **if**s:

§DISCOURSE_HOISTED_CODE_1§


And finally, quit using the **String** class, for a [multitude](http://forum.arduino.cc/index.php?topic=382944.msg2640860#msg2640860) [of](http://forum.arduino.cc/index.php?topic=396099.msg2726746#msg2726746) [reasons](http://forum.arduino.cc/index.php?topic=385867.msg2661171#msg2661171):

§DISCOURSE_HOISTED_CODE_2§


Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. ;)

The next thing you should look at is Robin2's **Serial Input Basics**, reachable from the very [Useful Links](http://forum.arduino.cc/index.php?topic=384198.0) page. Your current program "blocks" to read a command. Until the entire line is received, nothing else in your sketch will be executed.

**Serial Input Basics** has several examples that show how you can keep **loop** runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the "same" time.

Cheers,
/dev:
        readStr( ready_string, sizeof(ready_string) );
        serial_flag=2;
        break;
      case '*': voters      = Serial.parseInt(); serial_flag=3; break;
      case '!': pti_voters  = Serial.parseInt(); serial_flag=4; break;
      case '@': pmln_voters = Serial.parseInt(); serial_flag=5; break;
      case '<': ppp_voters  = Serial.parseInt(); serial_flag=6; break;
      case '>': ji_voters   = Serial.parseInt(); serial_flag=7; break;
      default :               skipCommand    (); serial_flag=0; break;
    }
  }

  if (serial_flag!=0) {
    switch (serial_flag) {
      case 1: Serial.print  ( cell         ); break;
      case 2: Serial.print  ( ready_string ); break;
      case 3: Serial.println( voters       ); break;
      case 4: Serial.println( pti_voters   ); break;
      case 5: Serial.println( pmln_voters  ); break;
      case 6: Serial.println( ppp_voters   ); break;
      case 7: Serial.println( ji_voters    ); break;
    }
    serial_flag=0;
  }
}

Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. :wink:

The next thing you should look at is Robin2’s Serial Input Basics, reachable from the very Useful Links page. Your current program “blocks” to read a command. Until the entire line is received, nothing else in your sketch will be executed.

Serial Input Basics has several examples that show how you can keep loop runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the “same” time.

Cheers,
/dev) { ready_string= Serial.readString(); serial_flag=2;}
   else if (x==’*’) { voters      = Serial.parseInt  (); serial_flag=3;}
   else if (x==’!’) { pti_voters  = Serial.parseInt  (); serial_flag=4;}
   else if (x==’@’) { pmln_voters = Serial.parseInt  (); serial_flag=5;}
   else if (x==’<’) { ppp_voters  = Serial.parseInt  (); serial_flag=6;}
   else if (x==’>’) { ji_voters   = Serial.parseInt  (); serial_flag=7;}
   else             { String abc  = Serial.readString(); serial_flag=0;}
 }

if (serial_flag!=0) {
       if (serial_flag==1) Serial.print  ( cell         );
  else if (serial_flag==2) Serial.print  ( ready_string );
  else if (serial_flag==3) Serial.println( voters       );
  else if (serial_flag==4) Serial.println( pti_voters   );
  else if (serial_flag==5) Serial.println( pmln_voters  );
  else if (serial_flag==6) Serial.println( ppp_voters   );
  else if (serial_flag==7) Serial.println( ji_voters    );
  serial_flag=0;
 }
}


Notice that the timer interrupt is not required. **loop** just runsrunsruns until the user types something. And you're not blocking inside the timer ISR.

Also notice the readability. Proper indentation makes it very easy to read. When you want help, or when you are looking for a bug, nothing is more important than READABILITY.

Next, try using a **switch** statement instead of a mess o' **if**s:

§DISCOURSE_HOISTED_CODE_1§


And finally, quit using the **String** class, for a [multitude](http://forum.arduino.cc/index.php?topic=382944.msg2640860#msg2640860) [of](http://forum.arduino.cc/index.php?topic=396099.msg2726746#msg2726746) [reasons](http://forum.arduino.cc/index.php?topic=385867.msg2661171#msg2661171):

§DISCOURSE_HOISTED_CODE_2§


Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. ;)

The next thing you should look at is Robin2's **Serial Input Basics**, reachable from the very [Useful Links](http://forum.arduino.cc/index.php?topic=384198.0) page. Your current program "blocks" to read a command. Until the entire line is received, nothing else in your sketch will be executed.

**Serial Input Basics** has several examples that show how you can keep **loop** runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the "same" time.

Cheers,
/dev: ready_string= Serial.readString(); serial_flag=2; break;
      case '*': voters      = Serial.parseInt  (); serial_flag=3; break;
      case '!': pti_voters  = Serial.parseInt  (); serial_flag=4; break;
      case '@': pmln_voters = Serial.parseInt  (); serial_flag=5; break;
      case '<': ppp_voters  = Serial.parseInt  (); serial_flag=6; break;
      case '>': ji_voters   = Serial.parseInt  (); serial_flag=7; break;
      default :               Serial.readString(); serial_flag=0; break;
    }
  }

  if (serial_flag!=0) {
    switch (serial_flag) {
      case 1: Serial.print  ( cell         ); break;
      case 2: Serial.print  ( ready_string ); break;
      case 3: Serial.println( voters       ); break;
      case 4: Serial.println( pti_voters   ); break;
      case 5: Serial.println( pmln_voters  ); break;
      case 6: Serial.println( ppp_voters   ); break;
      case 7: Serial.println( ji_voters    ); break;
    }
    serial_flag=0;
  }
}

And finally, quit using the String class, for a multitude of reasons:

§_DISCOURSE_HOISTED_CODE_2_§

Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. :wink:

The next thing you should look at is Robin2’s Serial Input Basics, reachable from the very Useful Links page. Your current program “blocks” to read a command. Until the entire line is received, nothing else in your sketch will be executed.

Serial Input Basics has several examples that show how you can keep loop runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the “same” time.

Cheers,
/dev) { ready_string= Serial.readString(); serial_flag=2;}
   else if (x==’*’) { voters      = Serial.parseInt  (); serial_flag=3;}
   else if (x==’!’) { pti_voters  = Serial.parseInt  (); serial_flag=4;}
   else if (x==’@’) { pmln_voters = Serial.parseInt  (); serial_flag=5;}
   else if (x==’<’) { ppp_voters  = Serial.parseInt  (); serial_flag=6;}
   else if (x==’>’) { ji_voters   = Serial.parseInt  (); serial_flag=7;}
   else             { String abc  = Serial.readString(); serial_flag=0;}
 }

if (serial_flag!=0) {
       if (serial_flag==1) Serial.print  ( cell         );
  else if (serial_flag==2) Serial.print  ( ready_string );
  else if (serial_flag==3) Serial.println( voters       );
  else if (serial_flag==4) Serial.println( pti_voters   );
  else if (serial_flag==5) Serial.println( pmln_voters  );
  else if (serial_flag==6) Serial.println( ppp_voters   );
  else if (serial_flag==7) Serial.println( ji_voters    );
  serial_flag=0;
 }
}


Notice that the timer interrupt is not required. **loop** just runsrunsruns until the user types something. And you're not blocking inside the timer ISR.

Also notice the readability. Proper indentation makes it very easy to read. When you want help, or when you are looking for a bug, nothing is more important than READABILITY.

Next, try using a **switch** statement instead of a mess o' **if**s:

§DISCOURSE_HOISTED_CODE_1§


And finally, quit using the **String** class, for a [multitude](http://forum.arduino.cc/index.php?topic=382944.msg2640860#msg2640860) [of](http://forum.arduino.cc/index.php?topic=396099.msg2726746#msg2726746) [reasons](http://forum.arduino.cc/index.php?topic=385867.msg2661171#msg2661171):

§DISCOURSE_HOISTED_CODE_2§


Notice that the program size has dropped to 3354 bytes from 5088 bytes, a savings of 1734 bytes. And your street cred has gone up, too. ;)

The next thing you should look at is Robin2's **Serial Input Basics**, reachable from the very [Useful Links](http://forum.arduino.cc/index.php?topic=384198.0) page. Your current program "blocks" to read a command. Until the entire line is received, nothing else in your sketch will be executed.

**Serial Input Basics** has several examples that show how you can keep **loop** runrunrunning while the command is being accumulated. When the newline finally shows up, milliseconds later, you can parse the command all at once. Then your program will be able to execute all the other things it needs to do at the "same" time.

Cheers,
/dev