'HardwareSerial' was not declared in this scope.

EDIT: SOLVED! There was a workaround in Marlin (for reasons only known to year 2011) that prevents the inclusion of HardwareSerial in core.

Hello, I’m writing a stepper driver library for TMC2208 that’s used in Marlin firmware.

Recently we got a bug report that when multiple software serials are used only the last one can successfully read data. This limitation is documented in the SoftwareSerial reference page and the solution for this would be to call listen() before each read operation.

However since the stepper library needs to work with both Hardware and Software serial objects, the passing constructor parameter type is the parent class Stream. This is current implementation in the library but the Stream class does not have the listen method that I need.

My solution to this was to convert the library class to a template to allow both SW and HW serial objects to be passed as parameters and to give the library direct access to the serial objects and not just their common parent. This works outside of Marlin!

In Marlin there is an external declaration (stepper_indirection.h) of the stepper objects and on the library header file there’s an explicit instance (TMC2208Stepper.h) of the two possible versions. The compiler gives me the following error message:

In file included from C:\arduino_builds\sketch\stepper_indirection.h:62:0,

                 from C:\arduino_builds\sketch\stepper.h:48,

                 from C:\arduino_builds\sketch\Marlin_main.cpp:254:

C:\Users\teemu\BTSync\Arduino\libraries\TMC2208Stepper\src/TMC2208Stepper.h:213:31: error: 'HardwareSerial' was not declared in this scope

 template class TMC2208Stepper<HardwareSerial>;

                               ^

C:\Users\teemu\BTSync\Arduino\libraries\TMC2208Stepper\src/TMC2208Stepper.h:213:45: error: template argument 1 is invalid

 template class TMC2208Stepper<HardwareSerial>;

                                             ^

In file included from C:\arduino_builds\sketch\stepper.h:48:0,

                 from C:\arduino_builds\sketch\Marlin_main.cpp:254:

stepper_indirection.h:95: error: 'HardwareSerial' was not declared in this scope

       extern TMC2208Stepper<HardwareSerial> stepperX; // HWSerial not declared in scope

                             ^

stepper_indirection.h:95: error: template argument 1 is invalid

       extern TMC2208Stepper<HardwareSerial> stepperX; // HWSerial not declared in scope

                                           ^

stepper_indirection.h:95: error: invalid type in declaration before ';' token

       extern TMC2208Stepper<HardwareSerial> stepperX; // HWSerial not declared in scope

                                                     ^

In file included from C:\arduino_builds\sketch\Marlin_main.cpp:313:0:

C:\arduino_builds\sketch\tmc_util.h: In instantiation of 'void tmc_set_current(TMC&, const char*, int) [with TMC = int]':

C:\arduino_builds\sketch\Marlin_main.cpp:10484:7:   required from here

tmc_util.h:54: error: request for member 'setCurrent' in 'st', which is of non-class type 'int'

   st.setCurrent(mA, R_SENSE, HOLD_MULTIPLIER);

   ^

C:\arduino_builds\sketch\tmc_util.h: In instantiation of 'void tmc_get_current(TMC&, const char*) [with TMC = int]':

C:\arduino_builds\sketch\Marlin_main.cpp:10484:7:   required from here

tmc_util.h:50: error: request for member 'getCurrent' in 'st', which is of non-class type 'int'

   _tmc_say_current(name, st.getCurrent());

                                         ^

C:\arduino_builds\sketch\tmc_util.h: In instantiation of 'void tmc_report_otpw(TMC&, const char*) [with TMC = int]':

C:\arduino_builds\sketch\Marlin_main.cpp:10524:59:   required from here

tmc_util.h:59: error: request for member 'getOTPW' in 'st', which is of non-class type 'int'

   _tmc_say_otpw(name, st.getOTPW());

                                   ^

C:\arduino_builds\sketch\tmc_util.h: In instantiation of 'void tmc_clear_otpw(TMC&, const char*) [with TMC = int]':

C:\arduino_builds\sketch\Marlin_main.cpp:10544:82:   required from here

tmc_util.h:63: error: request for member 'clear_otpw' in 'st', which is of non-class type 'int'

   st.clear_otpw();

   ^

Using library TMC2208Stepper at version 0.0.3 in folder: C:\Users\teemu\BTSync\Arduino\libraries\TMC2208Stepper 
Using library SoftwareSerial at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial 
Using library TMC2130Stepper at version 2.1.4 in folder: C:\Users\teemu\BTSync\Arduino\libraries\TMC2130Stepper 
Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI 
exit status 1
'HardwareSerial' was not declared in this scope

I believe only the first and third are important here and the rest are sorted when they are fixed.

If the HardwareSerial data type is replaced with SoftwareSerial it compiles OK.
If I change the board, and thus the core, to Teensy++ 2.0 it compiles with both HW and SW data types.

The header files where the errors occur, have Arduino.h included.

The test compile, the dev branch of the library is needed, along with the bf1_new_tmc2208_constructor branch of Marlin.

I’m also open to alternative solutions on how to achieve the communication options for the library.

Here’s a cut-down version of the TMC2208Stepper.h file:

// TMC2208Stepper.h
#pragma once
#include <Arduino.h>
#include <SoftwareSerial.h>

template<class SERIAL_TYPE>
class TMC2208Stepper {
 public:
 TMC2208Stepper(SERIAL_TYPE * serial, bool has_rx=true);
 private:
 SERIAL_TYPE * tmc_serial;
};

template class TMC2208Stepper<SoftwareSerial>;
template class TMC2208Stepper<HardwareSerial>;

Board: Arduino Mega 2560
IDE: Arduino IDE 1.8.5

Thank you for any assistance anyone might be able to give me.

EDIT: SOLVED! There was a workaround in Marlin (for reasons only known to year 2011) that prevents the inclusion of HardwareSerial in core.