How to use serial interrupt in arduino

Hi,

I have seen some example for serial interrupt. That too uses serialEvent() function in loop. So it almost similar like polling only.

I dont know how to handle serial interrupt in arduino.(like how we enable GIE,PEIE in PIC, and write ISR)

Thanks in Advance

Pon

serialEvent() behaves exactly like

if (Serial.available > 0) {
    mySerialCode();
}

I don't understand what you are trying to achieve. The Arduino HardwareSerial code handles the actual USART interrupts so you don't need to.

...R
Serial Input Basics

my sample code:

void serialEvent() {
while (Serial1.available()) {
inChar[k] = Serial1.read();
switch (inChar[k])
{
case 'O':
{
Serial1.print("OkC");
break;
}
case 'Y':
{
outValue=0xf0;
digitalWrite(led1,LOW);
digitalWrite(led2,HIGH);
break;
}
case 'N':
{
outValue=0xff;
digitalWrite(led2,LOW);
digitalWrite(led1,HIGH);
break;
}
//....
//...
//...
}

/// here for every serial request i need to respond faster. That mean i try to achieve to reduce response time as much as possible. I receive serial data from separate GUI. I need to avoid this polling kind of process. So that i could improve response time

my sample code:

void serialEvent() {
while (Serial1.available()) {
inChar[k] = Serial1.read();
switch (inChar[k])
{
case 'O':
{
Serial1.print("OkC");
break;
}
case 'Y':
{
outValue=0xf0;
digitalWrite(led1,LOW);
digitalWrite(led2,HIGH);
break;
}
case 'N':
{
outValue=0xff;
digitalWrite(led2,LOW);
digitalWrite(led1,HIGH);
break;
}
//....
//...
//...
}

/// here for every serial request i need to respond faster. That mean i try to achieve to reduce response time as much as possible. I receive serial data from separate GUI. I need to avoid this polling kind of process. So that i could improve response time

i mean like

attachInterrupt(pin_no,ISR_func,Condition) //
say attachInterrupt(2,routine,HIGH)
detachInterrupt(2);
i have seen codes uses these method. But those checked for digital HIGH/LOW pin. But here i need to receive a complete char. i am not getting how to do

Show the rest of your code. This isn't something you should need to do unless you've written blocking code in your loop function. In that case it would be a lot easier to fix the code there than to rewrite the serial receive interrupts in the Arduino core.

void serialEvent() {
  while (Serial1.available()) {
    inChar[k] = Serial1.read();
    switch (inChar[k])
    {
      case 'O':
      {
        Serial1.print("OkC");
        break;
      }
      case 'Y':
      {
        outValue=0xf0;
        digitalWrite(led1,LOW);
        digitalWrite(led2,HIGH);
        break;
      }
      case 'N':
      {
        outValue=0xff;
        digitalWrite(led2,LOW);
        digitalWrite(led1,HIGH);
        break;
      }
      case 'I':
      {
        if(k<=5)
        {
        inputString += inChar[k];
        k++;
        }
        if(inputString.length()==4)
         {
          
            int i;
                         int len=inputString.length();
                         for(i=0;i<len;i++)
                         {
                         if (isDigit(inputString[i]))
                         {
                         char m=inputString[i];
                         newString += m;
                         }
                         }
                         integerValue= newString.toInt();
                         integerValue11=integerValue;
                          integerValue1=(float) (integerValue)*0.1;
                           integerValue2=(float) (integerValue1)*40;
                                   inputString= "";
                                   newString="" ;
                adc0 = ads1115.readADC_SingleEnded(0);
              volt0 = adc0*0.000190;
              volt0= (volt0)/2;
              volt0=volt0/2800;
              volt1=(volt0)*1000000;   
              conv(volt1);
            k=0;
         }
        break;
      }
      case 'V':
      {
        Serial1.print('V');
        Serial1.println("3.0");
        break;
      }
      case 'M':
      {
        adc0 = ads1115.readADC_SingleEnded(0);
        volt0 = adc0*0.000190;
        volt0= (volt0)/2;
        volt0=volt0/2800;
        volt1=(volt0)*1000000;   
        conv(volt1);
        break;
      }
      case 'L':
      {
        rea(integerValue);
        break;
      }
      case 'P':
      {
        iadc0 = ads2224.readADC_SingleEnded1(0);
        ivolt0= iadc0*0.000190; 
        ivolt1=(float) (ivolt0)*1000;
        if(ivolt1>=80)
        {
        ivolt1=ivolt1-offset1;
        pdconv( ivolt1);                  
        }else 
        {
        ivolt1=ivolt1-offset2;
        pdconv( ivolt1);
        }              
        break;
      }
      default:
      {
        dac(disk1, address,integerValue2);
        relay(relayadd, cont, outValue);
      }
    }
  }
}

void loop() {
  serialEvent(); 
  }

Well, nothing about that code seems slow. You say in reply #3 that you need to be able to reply to serial data faster. How fast do you need? What do you mean when you say this is slow? How long is it taking? You're not going to be able to do anything that will allow you to respond to serial data much faster than you already are.

You still haven't shown the whole sketch? Where is setup()? What baud rate are you using?

Don't use serialEvent().

Use one of the examples in Serial Input Basics. They take in all the data and then you can act on it.

The slow part of the process is the serial transmission of data.

This Python GUI demo demo may be of interest.

...R

  while (Serial1.available()) {

Why are you calling serialEvent anyway?

void loop() {
  serialEvent();
  }

See: serialEvent() - Arduino Reference

Don't you mean serialEvent1?

And what do all the other functions do?

http://snippets-r-us.com/

Hi all,
Thanks for reply

hi Delta, I am using 1152000 baud rate.

Hi Robin,

Can i use like,...digital I/O interrupt

attachInterrupt(Serial_pin,ISR_routine(),CHANGE);

I will try with link you replied in post #8. but that too seems like calling recOnechar() function from loop

Thanks

Pon

Delta_G:
You say in reply #3 that you need to be able to reply to serial data faster. How fast do you need? What do you mean when you say this is slow? How long is it taking? You're not going to be able to do anything that will allow you to respond to serial data much faster than you already are.

alagappan:
Can i use like,...digital I/O interrupt

attachInterrupt(Serial_pin,ISR_routine(),CHANGE);

I don't believe that will work because receiving a single character involves a lot of HIGHs and LOWs. There is no pin that goes HIGH when a complete character is received.

I will try with link you replied in post #8. but that too seems like calling recOnechar() function from loop

That is true - but loop() repeats very much faster than characters arrive in the serial input buffer.

I think you need to write a complete (short) demo program that illustrates the problem you are trying to deal with.

...R

I dont know how to handle serial interrupt in arduino.(like how we enable GIE,PEIE in PIC, and write ISR)

The Arduino "core" code handles the actual serial interrupts, and there isn't really any good way for you to intercept them in sketch code.

serialEvent() provides a sort of pseudo-interrupt, but only if loop() runs fairly quickly. Essentially, there is a code segment like:

   if (Serial.available())
      serialEvent();

that happens before each call to loop()

Hi on receiving a Serial request char = 'P' i need to reply adc output value with in 2 or 3 ms. but it takes 9,10 ms.

Almost i found where the delay occurs.

when i comment reading adc IC it responds in less than 1 ms
code:

if(inChar[0]=='P')
                     {

                      req_time = millis();
                       z=1;
                       // iadc0 = ads115.readADC_SingleEnded1(0); // when i uncomment this reply time takes 9 ms, but when commented it was only 1ms
                        ivolt0= iadc0*0.000190; 
                       ivolt1=(float) (ivolt0)*1000;
                       ivolt1 = 374.0;
                      res_time = millis();
                      rep_time = res_time - req_time;
                      Serial1.println(rep_time);
                      }

so reading ada fruit library ads1115.readADC.SingleEnded1 might takes that time.
So any one suggest me any idea to ressolve. it is very mandatory for me, Please,..

So it seems there was no problem with Serial data after all ?

Two ideas occur to me.

Could you read the ADC before the request so the data is waiting to be sent immediately. I use that system with my model trains.

Is it possible to initiate a read but not wait for it to complete. Then check back later to see if the reading has completed. But that depends on how the ads115 device (and its library) works.

...R

The Adafruit library has a built-in conversion delay for the ads1115 of 8ms. I don't know why (the chip is configured for 1600 samp/s), but I have now asked:
https://forums.adafruit.com/viewtopic.php?f=19&t=80633
(Hmm. The datasheet actually says that the 1115 has a max sample rate of 860 samp/s)

Perhaps you can just change the constant in your copy of the library...

Hi robin,

Thanks for reply.
Actually this ads1115 gets analog input from a photo detector. Photo detector receives the signal from Laser beam. So continuously laser light intensity changes, i need to see the equivalent variation in ads1115.

So on every request i need to read ads1115 ic data and despatch.

i receive one request for every 50 ms. that mean for every 50ms i need to respond with updated data

alagappan:
So on every request i need to read ads1115 ic data and despatch.

i receive one request for every 50 ms. that mean for every 50ms i need to respond with updated data

You can't make things happen faster than they happen.

If it takes time to get a reading ......

So continuously laser light intensity changes, i need to see the equivalent variation in ads1115.
So on every request i need to read ads1115 ic data and despatch.

Why not take the readings regularly in anticipation of a request - not just when the request is received. That way when a request arrives you just send the latest reading immediately.

...R

As Robin says you cannot just make it happen quicker but if you can live with the 50ms delay then when a reading is requested send the previous reading then take a fresh reading ready for the next request.
If the requests are coming in every 50ms then the result sent will be about 50 ms old.