Disable Serial (hardwareserial.cpp)

Hardwareserial.cpp by default grabs control of the UART(s) and instantiates Serial objects. I'd like to be able to write my own version using 9 bit protocol and implement my own ISRs.

Short of commenting out hardwareserial.cpp (I hate to mess with core files knowing that future upgrades will likely make it necessary to do it again - If I remember to.)

Is there any good way to prevent hardwareserial from doing its thing?

In WProgram.h

#ifdef __cplusplus
//#include "HardwareSerial.h"

In sketches that will need Serial object:

#include <HardwareSerial.h>

Thanks - that works. Still have to modify a core file but at least that's minor.

What I wound up doing was modifying Wprogram.h to read:

ifdef __cplusplus

ifndef NOHARDWARESERIAL

include "HardwareSerial.h"

endif

Then at the beginning of my sketch I put:

define NOHARDWARESERIAL

That left the default to Serial but gives an easy way to not use it when necessary.

Roy, does that work? I think that your modification only makes Serial inaccessible from your sketch; it won't remove the Serial object, will it? I mean the hardwareserial.cpp is still being compiled and linked to your program.

Mikal

Well, yes and no (I think). Yes hardwareserial.cpp IS still being compiled - I tested that by temporarily adding a statement:
#error Hardwareserial is here” to hardwareserial.cpp and it does show the error.

However I’m not sure its being linked.

I reached that conclusion by doing the following:

I wrote a simple sketch as follows:

void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13,HIGH);

}
void loop(){}

That sketch took 846 bytes.

Then I added Serial.begin(57600); to setup().
The program size changed to 1594 bytes.

Then I made copies of hardwareserial.cpp and hardwareserial.h which I renamed to lkhardwareserial.cpp and lkhardwareserial.h. I modified them (work in process) with an eye to adding support for all frame sizes, startbits, parity etc. (probably using other version(s) of begin(). I also renamed the class, buffers, and buffer struct. I did NOT however rename the instantiated object(s) - Serial, Serial1, etc.

I also added another file “options.h” with the following contents:

#ifndef OPTIONS_H
#define OPTIONS_H

#define NOHARDWARESERIAL
#ifdef NOHARDWARESERIAL
#define LKHWSERIAL
#endif

#endif

WProgram.h was changed per my previous post;
#ifdef __cplusplus

#ifndef NOHARDWARESERIAL //addedLJK
#include “HardwareSerial.h”
#endif //addedLJK

Finally I changed the sketch pde to look like this:

#include “options.h”
#include “lkhardwareserial.h”
void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13,HIGH);
Serial.begin(57600);
}
void loop(){}

This version’s program size is 1670 bytes - just 76 bytes larger than the one which used hardwareserial - about right considering the additions I made.

Further I tested which version of Serial was really running by changing (temporarily) the ISR to store the received character followed by a ‘_’ character in my version. I added Serial.read() and Serial.print() statements in loop(). It clearly shows that my version is the one actually executing.

Personally I wish that hardwareserial had to be explicitly declared in sketches by including the header file and instancing an object in the user code. The constructor could easily have been written to take the various flavors of chips into account requiring only the baud rate and perhaps number of bits, stop bits, and parity to be declared when instancing the Serial object. begin() would simply enable receive and transmit. I understand, however, the thinking behind the way it is now - a bit simpler for inexperienced users.

OK, I gave up. Thought things were working but Serial kept popping up. I just #ifndef-ed out all of hardwareserial.cpp & hardwareserial.h

Does the IDE create a makefile or what?

I take it back - I didn’t give up. I finally RTFM (which isn’t easy since it isn’t all in one place) and figured out how the compiler/linker works.

The solution to my problem was to create 2 new boards in arduino-0015\hardware\boards.txt that are copies of the Arduino Duemilanove w/ ATmega328 & Arduino Mega ( the two boards I have)

I changed the base of the new boards from atmega328 to atmega328nhs and from mega to meganhs (for all the parameters for the board), appended “(no hardware serial)” to the .name parameter.

Then in 0015\hardware\cores I made a copy of the arduino subdirectory and named it arduino_wo_hardwareserial. In that folder I deleted hardwareserial.cpp, hardwareserial.h, and removed the #include <hardwareserial.h> line from WPrograms.h.

Finally back in the boards.txt file I changed the build.core parameters for the newly created boards from “arduino” to “arduino_wo_hardwareserial”.

Now all I have to do is select one of my newly created boards if I want hardwareserial out of the way so I can do my own thing with the UART(s) or select the usual boards if I want Serial as usual.

Did you try just using different names for your own serial functions? The way I thought things were set up in recent versions of Arduino, if you don't reference the functions, the linker will leave them out of your final sketch...

Yes indeed I did. But I kept getting error messages referring to vector_18 interrupts. Also I want to be able to use the Serial variable name for compatability with existing code and hardwareserial.cpp pre-instances Serial and hardwareserial.h declares it as #extern.

Just a whole lot simpler to get it out of the way altogether.

My preference would have been to put hardwareserial.cpp and hardwareserial.h in the libraries folder. I don’t think one #include <hardwareserial.h> at the top of the sketch would be asking too much.

I don’t think one #include <hardwareserial.h> at the top of the sketch would be asking too much.

Let’s rephrase that a bit: Is breaking every single arduino sketch ever written that uses serial asking too much? 'Cause that’s the result of what you ask.

I think there probably should be some what to disable (or never enable) hardware serial, but this particular solution is not reasonable.

-j

Nice to meet you, OM. I’m WB4DQZ

Actually it breaks nothing = WProgram.h is automatically included in all sketches and it contains exactly that #include statement
.
If hardwareserial.h & hardwareserial.cpp were in the libraries folder instead of the cores folder then

Changing WProgram.h to read something like:

#ifndef NOHARDWARESERIAL
#include <hardwareserial.h>
#endif

instead of merely
#include <hardwareserial.h>

would allow an author who didn’t want to use the iibrary an easy way not to while existing code and examples should work just fine – unless I’m missing something.

The reason I didn’t take that approach is that I don’t want future versions of the IDE to put things back where I don’t want them. By creating my own board versions and cores I’m pretty sure they won’t be overwritten by upgrades. At least the cores wont. I have boards.txt backed up.

The problem with #define solutions is that core/library code doesn't get recompiled when changing sketches. I don't know exactly what triggers a recompile (pretty sure a board change does), but the current compilation method leaves preprocessor directive control a hit or miss (mostly miss) proposition.

-j

(the reason I bought my first arduino was to do a frequency agile 2m DDS transmitter with the AD9954 for APRS and DF beacons. I've done probably a couple of dozen Arduino projects, but still haven't gotten around to that one. I should add a 3.3V arduino to my next order for electronics goodies.)

Keep me posted on your ham projects.

Roy -

I also need to create my own serial interrupt routine. Thank you for sharing you solution. Do you think there's a chance of implementing your WProgram.h idea in the next version of the IDE?

-RB

Rather than modifying the core I add the following to the top of my skecth:

#define HardwareSerial_h

This prevents hardware serial from being included and you’re free to use the USART for your own code.

If you want to replace hardware serial with your own serial library, you can add this #define to your replacement header file as follows:

#ifndef MySerial_h
#define MySerial_h
// Define HardwareSerial_h to suppress loading of the Arduino standard Serial class
#define HardwareSerial_h
// Your serial defines go here
#endif

Any sketch where “MySerial.h” is added will now suppress hardware serial and enable the substitute.