Serial interrupt routine

Guys can you help me out on how to enable serial interrupt routine. when i receive a data from the Serial buffer that would be Serial.available() != 0. will go to a function to handle the receive data. and this should be an interrupt routine. the code bellow does not do the job. i just migrated from PIC to arduino so some i'm new to arduino.

thanks

  if (Serial.available() > 0)
      {
        pcreceivedata();              // if data is receive on the serial buffer check it
        if (stopreceive == true)
           {
               portswitch();
               i = 0;
               stopreceive = false;
           }
      }

There's serialEvent with 1.0
Not an interrupt, and can stall if "loop" stalls, but useful.

if they will not implement a good interrupt handling this could defeat the purpose of the MCU. its not giving much flexibility like access to SFR.

if they will not implement a good interrupt handling this could defeat the purpose of the MCU

I'm not sure who "they" are, but serial reception already is interrupt-driven, and buffered.

i just migrated from PIC

All that Microchip stuff'll just seem like a bad dream in no time.

Rolandchok:
if they will not implement a good interrupt handling this could defeat the purpose of the MCU. its not giving much flexibility like access to SFR.

As AWOL says there is already an interrupt handler. You can replace it if you want to. What is the problem you are really trying to solve?

this could defeat the purpose of the MCU

Maybe, but they've sold a lot of them. It can't have fundamental design flaws like, no interrupt handling.

Looking at your recent posts they are about how you can't do "this" or "that" that you used to do on the PIC.

But how about describing your project? What do you want to do? What are you building? It's like saying "I migrated from Pascal to C and feature X seems to be missing". Well, maybe. But if you concentrate on what you want to achieve I am sure people here will help you achieve it.

my project is using 3 Serial communication. 2 of those are connected to an ultrasonic sensor Which is the Sparkfun MAXSONAR WR1 and the data RX is sent to PC. now the arduino also takes commands from the PC to control switches. what happens is when the arduino start sending the data once i send data from the PC it will not handle the data. put if the two Sonars are off it take care perfectly the RX data. i need to have an interput handling once the serial port connected to PC receive the data it will stop reading of the two max sonar data and handle the receive data.

How is all this wired up?
Is it Mega?
What does your code look like?

what happens is when the arduino start sending the data once i send data from the PC it will not handle the data. put if the two Sonars are off it take care perfectly the RX data.

This needs some clarification, please.

Do you have a link to the sensor?

here is the code im still figuring out what to do with the ultrasonic

byte TWVDC1 = 35;        // 12VDC 1
byte TWVDC2 = 36;        // 12VDC 2
byte TWVDC3 = 37;        // 12VDC 3 
byte TFVDC1 = 38;        // 24VDC 1
byte TFVDC2 = 39;        // 24VDC 2
byte TFVDC3 = 40;        // 24VDC 3
byte TFVDC4 = 41;        // 24VDC 4
int pcbuffer[5];               // data receive from PC
boolean stopreceive = false;
int i = 0;
int S1index = 0;
int sonarbuffer1[4];
int sonardata1available;
boolean sonar1ready = false;

void setup()
{
    pinMode(radar, OUTPUT);
    pinMode(pc, OUTPUT);
    pinMode(TWVDC1, OUTPUT);
    pinMode(TWVDC2, OUTPUT);
    pinMode(TWVDC3, OUTPUT);
    pinMode(TFVDC1, OUTPUT);
    pinMode(TFVDC2, OUTPUT);
    pinMode(TFVDC3, OUTPUT);
    pinMode(TFVDC4, OUTPUT);
    pinMode(cooler1, OUTPUT);
    pinMode(cooler2, OUTPUT);
    pinMode(cooler3, OUTPUT);
    pinMode(51,OUTPUT);
    digitalWrite(51,LOW);
    Serial.begin(9600);
    Serial1.begin(9600);
    //digitalWrite(51,HIGH);
    //delay(1000);
    //digitalWrite(51,LOW);
    Serial.write("USART initiallize");
}
  
void loop()
{
  
  if (Serial.available() > 0)
      {
        pcreceivedata();              // if data is receive on the serial buffer check it
        if (stopreceive == true)
           {
               portswitch();
               i = 0;
               stopreceive = false;
           }
      }
  
   if (Serial1.available() > 0)
     {        
        ultrasonic1();
     }
   
   if (sonar1ready == true)
      {
        int n = 0;
        while(n < S1index)
        { 
         Serial.write(sonarbuffer1[n]);   // print ultrasonic value
         n++;
        }
        sonar1ready =false;
        S1index = 0;
      }
}

void pcreceivedata()
{
   int tempbuffer;
   int startrx = Serial.read();
   if (startrx == 0x24)                // check for $ in the serial buffer
     {
           do 
             {
                 pcbuffer[0] = 0x24;
                 tempbuffer = Serial.read();
                 pcbuffer[i] = tempbuffer;
                 i++;
                 delay(10);
              }while (tempbuffer != 0x2A);
            stopreceive = true;  
      }       
}

void portswitch()
{
   switch (pcbuffer[1])
     {      
        case 0xA0:
           digitalWrite(pc,!digitalRead(pc));
           break;
        case 0xA1:
           digitalWrite(radar,!digitalRead(radar));
           break; 
        case 0xB0:
           digitalWrite(TWVDC1,!digitalRead(TWVDC1));
           break;
        case 0xB1:
           digitalWrite(TWVDC2,!digitalRead(TWVDC2));
           break;        
        case 0xB2:
           digitalWrite(TWVDC3,!digitalRead(TWVDC3));
           break;
        case 0xB6:
           digitalWrite(TFVDC1,!digitalRead(TFVDC1));
           break;
        case 0xB7:
           digitalWrite(TFVDC2,!digitalRead(TFVDC2));
           break;
        case 0xB8:
           digitalWrite(TFVDC3,!digitalRead(TFVDC3));
           break;
        case 0xB9:
           digitalWrite(TFVDC4,!digitalRead(TFVDC4));
           break;
     }
} 

void ultrasonic1()
{    
       byte sonarcheck;
       int sonar1;
   sonarcheck = Serial1.read();
   if (sonarcheck != 0x52)
      {   
         do 
           {
               sonarcheck = Serial1.read();
               delay(10);
           }while(sonarcheck != 'R');
      }
   if (sonarcheck == 'R')
      {
       if (S1index < 5) 
          {
            sonar1 = Serial1.read();
            sonarbuffer1[S1index] = sonar1;
            S1index++;
            delay(10);
          }
      }
       // if(Serial1.available() == 0)
       //   {
       //      digitalWrite(51,HIGH);
       //      delay(1000);
       //      digitalWrite(51,LOW);
       //    }
        sonar1ready = true;
}
delay(10);

BZZZZZT!
Please, don't lecture on interrupts when you're wasting 9 character periods.
Or, given that you've got 'n' serial inputs, 9n character periods.

if (startrx == 0x24)

betterif (startrx == '

}while (tempbuffer != 0x2A);

better}while (tempbuffer != '*');)    `

§_DISCOURSE_HOISTED_CODE_3_§

better§_DISCOURSE_HOISTED_CODE_4_§

not to mention im attaching like 10 sensors on this board. so what are your suggestions in the interrupt handling.

its wired up like this at the moment.

Serial 0 - connected to PC
serial 1 - connected to ultrasonic 1
serial 2 - connected to ultrasonic 2

data from serial 1 and serial to needs to be put in a buffer so i could put them in an array for all the 10 sensor readings before transmission.

thanks AWOL. i forgot to change the hex codes. XD

so what are your suggestions in the interrupt handling.

My suggestion is to ignore it.
It is done for you.

All you have to do is stop wasting processor cycles using "delay()".

the delay actually helps a bit. when im sending all the data if dont put the delay it sends me lots of garbage. like data not in correct order. i have to use analog in instead of the serial i guess. =(

the delay actually helps a bit.

It doesn't help at all.
Get rid of it.
Your code will have to be restructured, but you do not need delays

ok..let me reconstruct it again. :sweat_smile:

ok..let me reconstruct it again.

What you need to do is add start and end packet markers, then read and store data as fast as possible, after the start marker arrives, stopping when there is no more data or the end marker has arrived.

Only use the data when both the start and end markers have arrived.

Like so:

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}
#define SOP '<'
#define EOP '>'

Or, in your case (as far as I can tell)

#define SOP '

#define EOP '*'

PaulS:

ok..let me reconstruct it again.

What you need to do is add start and end packet markers, then read and store data as fast as possible, after the start marker arrives, stopping when there is no more data or the end marker has arrived.

Only use the data when both the start and end markers have arrived.

the data actually has a header and its 'R' and a stop byte of 0x0D followed by '/n' what i did is look for 'R' and start reading the serial buffer and end reading when the buffer is full. it does the job actually no issues. but the problem arises when i send data coming from the PC it does not carry out the command and you have to send it like 10 times or more to be able to execute the command coming from the PC.

Your code is wrong. It is nothing to do with needing to add interrupt handlers to "put data in a buffer". There are already interrupt handlers for serial and they already do that.

... it does the job actually no issues. but the problem arises ...

It works with no issues, but problems arise, eh? Make up your mind.

Here is one problem:

  if (Serial.available() > 0)
      {
        pcreceivedata();              // if data is receive on the serial buffer check it
      ...
      }

...

void pcreceivedata()
{
...
   if (startrx == 0x24)                // check for $ in the serial buffer
     {
           do 
             {
                 pcbuffer[0] = 0x24;
                 tempbuffer = Serial.read();
                 pcbuffer[i] = tempbuffer;
                 i++;
                 delay(10);
              }while (tempbuffer != 0x2A);
            stopreceive = true;  
      }       
}

Your "if available" guarantees you have a single byte. But then you do Serial.read() inside a loop, until you get 0x2A. You then add in a delay to try to give it time to arrive. Read this, restructure to not do it this way:

PaulS was saying the same thing. Listen to him.

... you have to send it like 10 times or more to be able to execute the command coming from the PC.

Doesn't sound like "no issues" to me.