My .ino looks roughly like this
#include "command.h"
Command command;
void setup() {
}
void loop() {
}
command.h
class Command
{
public:
Command();
};
command.cpp
#include <Arduino.h>
#include "command.h"
Command::Command() {
Serial.begin(9600);
}
void serialEvent() {
while (Serial.available() > 0) {
char inChar = (char)Serial.read();
Serial.print(inChar);
}
}
The serial events don't seem to be happening. It works normally if I move the code out of the class.
-
Does it work when you move serialEvent() back to the sketch? This might be a build/link issue.Mikael Patel– Mikael Patel2015年12月22日 13:02:13 +00:00Commented Dec 22, 2015 at 13:02
2 Answers 2
When you put the Serial.begin
in the constructor and declare the Command
object at file scope, the Serial.begin
will occur before setup()
. Not recommended, perhaps not allowed.
If you do that, the compiler has to figure out that the Serial
instance must be constructed before the Command
instance is constructed. It can't always figure out the correct order.
In general, this is why you see many classes with a begin
or init
method. This allows the construction of file-scope instances to take place in any order, before setup
. Then setup
does the Command.begin()
, which finally calls Serial.begin
, long after Serial
has been constructed.
Also, using SerialEvent
is no better than doing the polling in loop()
. If you're busy doing something else, SerialEvent
does not get called. If you need to handle characters in the background, in the RX interrupt, you might want to take a look at a modified version for the Serial
object(s) I posted, NeoHWSerial. You can attach a routine to be called whenever a character is received.
-
Yes by putting an init method in the Command class and calling it from setup() the problem was fixed.CarbonMan– CarbonMan2015年12月22日 23:00:39 +00:00Commented Dec 22, 2015 at 23:00
-
@user316182, Yes, I am sure that
SerialEvent
is not called from the RX char interrupt. It is called frommain
, which just callsloop
and thenserialEventRun
in the never-ending for loop. You may as well just call yourserialEvent
code fromloop
. Sadly enough, there was a time whenSerialEvent
was dispatched from the IRQ, but it was later moved tomain
. See this commit. :-(slash-dev– slash-dev2016年07月11日 00:47:14 +00:00Commented Jul 11, 2016 at 0:47
@slash-dev "...Also, using SerialEvent is no better than doing the polling in loop()." Are you sure about that? SerialEvent (and especially the ones on Teensy3) use hardware interrupts which can be handled in the midst of other operations; even delay() does not block interrupts (http://playground.arduino.cc/Code/AvoidDelay). It's hard to imagine multiple serial streams running at 100 kbaud or better (test reported in PJRC forum) and handling each character in the main loop even if that was all your program did. And why would you want to? There are good reasons interrupts exist.
Update: I'm not allowed to "comment" without 50 reputation. Thanks for the commit link... I can't imagine why HardwareSerial would not use interrupts... that is the default on all other platforms we've used for years.
-
Uhh... did you notice you were pressing the "Add Another Answer" button? There is an "add a comment" button below my answer that you should have used. I have replied above, in a comment to my answer.slash-dev– slash-dev2016年07月11日 00:47:07 +00:00Commented Jul 11, 2016 at 0:47