Go Down

Topic: Possibilty of serial interrupt? (Read 356 times) previous topic - next topic

dan007

Is it possible to attach some sort of interrupt to a serial connection?

I.e the main program carries out various processes taking various time, but then on a serial input it can stop what it's doing at the oresent moment like an interrupt and reads the incoming serial data.

Regards
Dan
Never Assume;
As it makes an ASS out of U & ME

pylon

The hardware is generating an interrupt when a complete byte is received on the serial interface but usually the Arduino core code handles that interrupt. If you don't use the Arduino HardwareSerial class (e.g. the Serial object) you can do exactly what you want but you have to handle all the hardware specific stuff yourself.

If you structured your program the Arduino way you can define a routine serialEvent() which will be called if a new byte was received on the serial interface (handled by Arduino classes) but that won't be in interrupt context, it will be the next time your program leaves the loop() routine.

dan007

Firstly thank you for the promt response.
I have recently (very briefly) looked at use of Serialevent, so let me get this straight;
With use of the Serialevent, it can be used to capture information received via the defined serial port, whilst the main programming loop is running allowing analog temperature readings be taken, LCD screen updates. However it is then up to the main processing loop to access the information received?

Regards Dan
Never Assume;
As it makes an ASS out of U & ME

pylon

Quote
With use of the Serialevent, it can be used to capture information received via the defined serial port, whilst the main programming loop is running allowing analog temperature readings be taken, LCD screen updates. However it is then up to the main processing loop to access the information received?


If I understood you right, it's not exactly like that.
The Arduino core code calls your setup() routine at start and then it calls your loop() routine in an endless loop. If some bytes were received during execution of the loop() routine, they were stored in an internal buffer. As soon as your loop() routine ends, the core code will call serialEvent() if it's defined and if there are bytes waiting in that internal buffer, before it will call your loop() routine again.
I hope that make this clear for you.

dan007

Hi, that has made clear how the operation of the Arduino works. So with the inclusion of Serialevent, it is possible to have processes running in the loop, whilst never missing the data received as this will be stored in a buffer.

From this logic I think I need to do away with the following

Code: [Select]

void readTC35i()
{
  static char input_line [MAX_INPUT];    //static unsigned int input_pos = 0;
  if (gsmSerial.available () > 0) //
  {
    while (gsmSerial.available () > 0)
    {
      char inByte = gsmSerial.read ();
      switch (inByte)
      {

      case '\n':   // end of text
        input_line [input_pos] = 0;  // terminating null byte

        // terminator reached! process input_line here ...
        process_data (input_line);

        // reset buffer for next time
        input_pos = 0; 
        break;

      case '\r':   // discard carriage return
        break;

      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch
    }  // end of while incoming data
  }  // end of if incoming data
}  /
    {


And implement it using serialEvent()

Regards
Never Assume;
As it makes an ASS out of U & ME

pylon

Hmmh, that's just a snippet of code so I must guess. gsmSerial doesn't look like it's a HardwareSerial object. If it's a SoftwareSerial object it's something completely different. Although this object also has some buffers, the whole sending and reading is done in software and with interrupts deactivated. There is also no equivalent to the serialEvent() routine the HardwareSerial-Object offers. Don't mix these two things up. If ever possible use the HardwareSerial class (the Serial object) and take into account the SoftwareSerial class if you have no other option.

dan007

Hardware serial? Sorry, but I am lost :-/ my programming knowledge isn't vast, I'm self teaching myself whilst doing my final year at uni and this is small part of my project design, the rest control theory.

However, my full code is posted in the following thread.   http://forum.arduino.cc/index.php?topic=142660.15

Kind regards
Never Assume;
As it makes an ASS out of U & ME

pylon

In that sketch you're using the SoftwareSerial class with pins 9 and 10. You cannot use the serialEvent() functionality with that class, that works only with the serial interface in hardware (on pin 0 and 1) which you're using for debugging. If you want to use that functionality you have to swap the two interfaces, use SoftwareSerial for debugging and the hardware serial interface to connect to your GSM.

For the posted sketch you don't need that because you can easily implement a comparable functionality in your sketch without using an interrupt. You just have to get rid of all delay() calls. Take a look at the BlinkWithoutDelay example in your IDE to get an idea of how this can be done. Then you just have to check the serial buffer once in every loop run (by calling gsmSerial.available()) and react it there are some bytes to be read.

dan007

Ah that sounds great, replace LED side code (from Blink no delay), with that of updateing the LCD. Remove a other delays, and the code I have now should work as it's the current delays which cause it to miss data.

Regards Dan
Never Assume;
As it makes an ASS out of U & ME

dan007

HI Pylon,

Thank you very much, you have solved my problem. Sometimes we as engineers think too much out of the box at actually the solution is very simple. I can't believe I missed this  :smiley-red:

Here is how I implemented it;

Code: [Select]

//------ Main loop -------
void loop()   
{
  readTC35i();                //Step 04 :- Run through TC35i for incomming message
  TempSetting();              //Step 05 :- Run temperature function to get temperatures
  TempFunction();             //Step 06 :- Run temperature function to get temperatures


unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
  {
    previousMillis = currentMillis;   

  selectLineOne();
  Serial.write("Temp = ");
  Serial.print(TempDisplay);
  Serial.write("c  ");

  selectLineTwo(); 
  Serial.write("Setting = ");
  Serial.print(Setting);
  Serial.write("c  ");
  } 
}
//------ End loop --------


All I need to do now is tidy it up  :D 8) :D .....oh and work on the PID control theory eeek.

Cheers
Dan
Never Assume;
As it makes an ASS out of U & ME

Go Up