Okay I am in need of some serious help here.
I have been working on this Arduino project (I am using the Visual Micro plugin for Visual Studio 2017) for a year or two on and off. So far I have been doing all my development and uploaded it to either an Uno, Mega, or Pro Mini.
Well today I did an upgrade, and switched over to using an Arduino Due, as I needed the processing power for one piece of code (I needed for instance, AnalogRead to be faster).
Anyway, after switching over, and fixing some code around "template" types, I have one issue left that I can't seem to figured out ... HardwareSerial.
Part of my code is I have build a wrapper class around Serial to make it easier to use, cleaner, ext. But, when I switch over to the Due, it seems HardwareSerial's base library changed on me, DRASTICALLY!
This is the error I get when trying to compile
26:20: error: invalid abstract return type for member function 'HardwareSerial SerialCommunication::SerialItem()
And this is a more detailed breakdown of the error (please note the project name is redacted, as I am keeping it hush hush for now)
SerialCommunication.h: 26:20: error: invalid abstract return type for member function 'HardwareSerial SerialCommunication::SerialItem()
HardwareSerial SerialItem()arduino.h:195: In file included from
x.ino: from
HardwareSerial.h:26: note because the following virtual functions are pure within HardwareSerial
class HardwareSerial *: public Stream
HardwareSerial.h:35: note virtual size_t HardwareSerial write(uint8_t)
virtual size_t write(uint8_t) = 0
HardwareSerial.h:31: note virtual int HardwareSerial available()
virtual int available(void) = 0
HardwareSerial.h:33: note virtual int HardwareSerial read()
virtual int read(void) = 0
HardwareSerial.h:32: note virtual int HardwareSerial peek()
virtual int peek(void) = 0
HardwareSerial.h:34: note virtual void HardwareSerial flush()
virtual void flush(void) = 0
HardwareSerial.h:37: note virtual HardwareSerial operator bool()
virtual operator bool() = 0
Error compiling project sources
When I go to the line in my header file that is throwing the error, and view the definition when set to upload to a due, this is what I see is the source code
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include "Stream.h"
class HardwareSerial : public Stream
{
public:
virtual void begin(unsigned long);
virtual void end();
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
virtual size_t write(uint8_t) = 0;
using Print::write; // pull in write(str) and write(buf, size) from Print
virtual operator bool() = 0;
};
extern void serialEventRun(void) __attribute__((weak));
#endif
HOWEVER, if I switch back to say the Mega, and view the definition, this is what the code looks like
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include "Stream.h"
#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
typedef uint16_t tx_buffer_index_t;
#else
typedef uint8_t tx_buffer_index_t;
#endif
#if (SERIAL_RX_BUFFER_SIZE>256)
typedef uint16_t rx_buffer_index_t;
#else
typedef uint8_t rx_buffer_index_t;
#endif
// Define config for Serial.begin(baud, config);
#define SERIAL_5N1 0x00
#define SERIAL_6N1 0x02
#define SERIAL_7N1 0x04
#define SERIAL_8N1 0x06
#define SERIAL_5N2 0x08
#define SERIAL_6N2 0x0A
#define SERIAL_7N2 0x0C
#define SERIAL_8N2 0x0E
#define SERIAL_5E1 0x20
#define SERIAL_6E1 0x22
#define SERIAL_7E1 0x24
#define SERIAL_8E1 0x26
#define SERIAL_5E2 0x28
#define SERIAL_6E2 0x2A
#define SERIAL_7E2 0x2C
#define SERIAL_8E2 0x2E
#define SERIAL_5O1 0x30
#define SERIAL_6O1 0x32
#define SERIAL_7O1 0x34
#define SERIAL_8O1 0x36
#define SERIAL_5O2 0x38
#define SERIAL_6O2 0x3A
#define SERIAL_7O2 0x3C
#define SERIAL_8O2 0x3E
class HardwareSerial : public Stream
{
protected:
volatile uint8_t * const _ubrrh;
volatile uint8_t * const _ubrrl;
volatile uint8_t * const _ucsra;
volatile uint8_t * const _ucsrb;
volatile uint8_t * const _ucsrc;
volatile uint8_t * const _udr;
// Has any byte been written to the UART since begin()
bool _written;
volatile rx_buffer_index_t _rx_buffer_head;
volatile rx_buffer_index_t _rx_buffer_tail;
volatile tx_buffer_index_t _tx_buffer_head;
volatile tx_buffer_index_t _tx_buffer_tail;
// Don't put any members after these buffers, since only the first
// 32 bytes of this struct can be accessed quickly using the ldd
// instruction.
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
public:
inline HardwareSerial(
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *ucsrc, volatile uint8_t *udr);
void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
void begin(unsigned long, uint8_t);
void end();
virtual int available(void);
virtual int peek(void);
virtual int read(void);
virtual int availableForWrite(void);
virtual void flush(void);
virtual size_t write(uint8_t);
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool() { return true; }
// Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void);
void _tx_udr_empty_irq(void);
};
#if defined(UBRRH) || defined(UBRR0H)
extern HardwareSerial Serial;
#define HAVE_HWSERIAL0
#endif
#if defined(UBRR1H)
extern HardwareSerial Serial1;
#define HAVE_HWSERIAL1
#endif
#if defined(UBRR2H)
extern HardwareSerial Serial2;
#define HAVE_HWSERIAL2
#endif
#if defined(UBRR3H)
extern HardwareSerial Serial3;
#define HAVE_HWSERIAL3
#endif
extern void serialEventRun(void) __attribute__((weak));
#endif
What the heck is going on here? Why would the HardwareSerial change so drastically between board architectures? Google isn't being the nicest to me right now, so I am at this point not sure what else to do. I need to keep this code in tact as I need it for part of this project, to communicate between boards (yes I know there is also SoftwareSerial, but that has a layer of code over it that will result in slower code all together)
Oh yes, this is the exact code causing the problem (it's just a snippet)
Header File
protected:
HardwareSerial SerialItem();
CPP File
HardwareSerial SerialCommunication::SerialItem()
{
switch (_SerialPins)
{
case SerialCommunication::S0:
return Serial;
case SerialCommunication::S1:
return Serial1;
case SerialCommunication::S2:
return Serial2;
case SerialCommunication::S3:
return Serial3;
default:
return Serial;
}
}