[SOLVED] Serial interrupt service for Arduino ( not poling ! )

Hi there, I've been looking for a solution here on this forum and I've been amazed to see from the answers how much the theme has not yet been well understood. The fact is that all the solutions presented so far are nothing more than mere variants of the polling implementation if (Serial.available ()> 0) which in many cases does not solve the problem as to whether a program is already overloaded with other heavy tasks.

so here I go and to ask is if anyone knows if it is being implemented or planned for the Arduino next releases interrrupt service for serial commnication. Considering that the interrupt feature is available for ALL microcontrollers for which Arduino supporsts, it sounds strange that this has not yet been made available for this language platform, at least as far as I know.

Thanks in advance.

andre_teprom:
I've been amazed to see from the answers how much the theme has not yet been well understood.

You are polling the buffer, which is filled via interrupts,
so it is you that has a misunderstanding here.

You are polling the buffer, which is filled via interrupts,

What you are referring to is not interruption, the UART buffer is populated and has its value superposed for each new byte received by the serial. Interruption means to have in the program another vector besides the loop() that would be instantiated immediately in the occurrence of any event in the UART, instead of having to be checked at the loop().

That is exactly what happens.
A byte arrives, the resulting interrupt reads the UART and places the received byte in the reception buffer.
That is all that should be done in interrupt context, as it is the unavoidable work that has to be done to be prepared for the next reception.

It seems to me that you don’t want to hear the naked truth, but I will repeat it again:

Serial communication already is interrupt driven, no reason to complain about.

Have a look at the implementation for normal Arduinos:
\Arduino\hardware\arduino\avr\cores\arduino, files HardwareSerial*.*.

Serial communication already is interrupt driven, no reason to complain about.

The above folder just confirms that serial interrupt was not implemented, at least for AVR cores. The only implementation there is for data sent, not for data received. I was expecting here some insight from someone who might was aware of some modified library or whom have been successful in handling that library to be able to add a handler for the reception as well, but I was not lucky this time, unfortunately...thanks.

You did not look close enough.

There are seven files that build the serial system.

HardwareSerial0.cpp holds the interrupt routines for transmission and reception (for Serial).

andre_teprom:
I was expecting here some insight from someone who might was aware of some modified library or whom have been successful in handling that library to be able to add a handler for the reception as well, but I was not lucky this time, unfortunately...thanks.

You stll don't believe me, obviously.

Serial communication is already interrupt driven.

andre_teprom:
What you are referring to is not interruption, the UART buffer is populated and has its value superposed for each new byte received by the serial. Interruption means…

Think about the “is populated” part, how does it get populated?

It is the work of the interrupt routine you somehow seem to miss.

Can you write a better version for that work? (Hardware to buffer) What do you miss?

You could change the core code, but you would have to do it for every update of the IDE.

If your solution works better and on the same Arduinos,
it could find its way into the Arduino source.

You are insisting to say that serial interrupt is already implemented, but it is not available any handler at the sketch which allow users to code their interrupt service routines there ( I mean, not the same as the already available for IO and Timers), therefore back to the original question: I'm asking for news on this regard. If there is not workaround, the question remains unsolved, thanks...

I agree 100% with @Whandall.

@andre_teprom, if you explain what you want to happen and which you cannot do in what we would consider the “normal” way we might be better able to understand and help. At the moment this is an XY problem

What is the project that you are trying to create?

…R
Serial Input Basics

NeoHWSerial

-dev:
NeoHWSerial

Your marketing skills are very poor :slight_smile: You should have posted a link!

...R

Sorry, it was a quick post from my cell phone. Try this. :smiley:

-dev:
Sorry, it was a quick post from my cell phone. Try this. :smiley:

Is there a “status byte” associated with the current character? Ie. parity error, etc. The old USARTS I used to program had all kinds of status bits.

Paul

Is there a "status byte" associated with the current character?

Yes, but it's the actual hardware register, not something that is stored in the NeoSerial instance. The NeoHWSerial class is the original HardwareSerial class, with one addition: attachInterrupt.

Because the Arduino HardwareSerial class simply drops the character when the overrun or parity error bits are set, NeoHWSerial does the same thing. You do not need to test these flags in your function -- the character passed to the function is always a good character.

I can't think of a reason to actually pass a bad character (i.e., with a parity error), but you could save the UCSRnA register (flags) before reading the UDR register (the character), and look at it in your registered function. The error flags are cleared after reading UDR. This part would have to change.

There is no other information for overrun, only that a character was dropped (NeoGPS has a similar flag for when a complete fix was dropped).

-dev:
Yes, but it’s the actual hardware register, not something that is stored in the NeoSerial instance. The NeoHWSerial class is the original HardwareSerial class, with one addition: attachInterrupt.

Because the Arduino HardwareSerial class simply drops the character when the overrun or parity error bits are set, NeoHWSerial does the same thing. You do not need to test these flags in your function – the character passed to the function is always a good character.

I can’t think of a reason to actually pass a bad character (i.e., with a parity error), but you could save the UCSRnA register (flags) before reading the UDR register (the character), and look at it in your registered function. The error flags are cleared after reading UDR. This part would have to change.

There is no other information for overrun, only that a character was dropped (NeoGPS has a similar flag for when a complete fix was dropped).

Thanks, will keep that in mind. My background is data communications in banking. Different protocols from different mfg. NCR, Burroughs, IBM, and others. Many years ago!

Paul

andre_teprom:
You are insisting to say that serial interrupt is already implemented, but it is not available any handler at the sketch which allow users to code their interrupt service routines there ( I mean, not the same as the already available for IO and Timers), therefore back to the original question: I'm asking for news on this regard. If there is not workaround, the question remains unsolved, thanks...

The question is, what would you have that interrupt routine do. If you really think through that question and consider it in the real world example of any real program, you'll find that all it really can do is read the character and buffer it for some line of code later to act upon. I mean really think all the way through what you would have it to do. How would you write such a routine so as to keep it fast enough to be an interrupt? ANd you have to worry about the concurrency with other things in your code. So how would you really really write such a handler.

Once you have a real answer for that, you'll realize that the interrupt that is already handling serial is doing just what you would have it to do. It's buffering that data to be used when needed. How fast do you need to respond to serial data? A few microseconds? Well, keep your loop tight and non-blocking and that's no problem.

andre_teprom:
You are insisting to say that serial interrupt is already implemented, but it is not available any handler at the sketch which allow users to code their interrupt service routines there

The code is all open source. You are welcome to rewrite the existing serial interrupt handlers to do anything you like.

Robin2:
if you explain what you want to happen and which you cannot do in what we would consider the "normal" way we might be better able to understand and help

Perhaps the problem in the lack of clarity of my explanation (though I think I posed exactly my intent) has been the fact that the feature that I am looking to implement in Arduino is somewhat usual in dealing with UART's with C language for quick serial reception in microcontrollers; I presume the idea behind this was not caught by many people here, but I'll rephrase: I was searching for a way to manage by myself actions in the happening of serial interrupts, as it is possible to do in C programs; Interrupt-driven receiving in the optic of a programmer person, is an event that interrupts any execution - including delays! - and as a rule should have an immediate treatment (it is up to the programmer to follow this good practice), such as parsing a frame on the fly, that is, treat the incomming bytes from Serial as they arrive. Neither the SerialEvent() nor the EventManager library don't do this.

Just to share with those who as me are still in the same search I found something promising, an alternative library for the standard Arduino Serial that I will make tests:

arduino-buffered-serial

jremington:
The code is all open source. You are welcome to rewrite the existing serial interrupt handlers to do anything you like.

Thanks for the attempt, but it was not useful, because if you reread the original post I just asked if anyone knew any functional implementation, never said that I would do it myself. If you do not have this information, you do not have to participate criticizing my search, which apparently seems to have been successful, and I hope others will take advantage of the information posted above, thanks.

Interrupt-driven receiving in the optic of a programmer person, is an event that interrupts any execution - including delays! - and as a rule should have an immediate treatment

Which is the case with standard interrupt-driven serial on the Arduino.

andre_teprom:
I found something promising, an alternative library for the standard Arduino Serial

Did you look at NeoHWSerial? It does exactly what you want by extending the current Serial interface.

I use this class in my NeoGPS examples to show how to parse characters during the RX interrupt. And because the interface is the same as HardwareSerial, it's easy to switch between polling and interrupt styles.