Search code examples
c++arduinonodemcuarduino-esp8266

Arduino: overriding Print class problems


I am trying to make a library for redirection of data printed to Print class. I am unfortunately stuck on error that reads

error: cannot declare variable 'diagData' to be of abstract type 'PrintToString'

note: because the following virtual functions are pure within 'PrintToString'

note: virtual size_t PrintToString::write(uint8_t)

I tried several variations of how to implement this but with no luck. (Sourced from the internet)


Links

Print class: github.com/ Print.h and Print.cpp

My code

PrintToString.h

#ifndef PRINT_TO_STRING_H

    #define PRINT_TO_STRING_H

    #include <Arduino.h>


    class PrintToString : public Print
    {
        private:
            String* data;

        public:
            PrintToString();
            ~PrintToString();

            String* results();
            void clear();

            size_t write(uint8_t) = 0;
            size_t write(const uint8_t* buffer, size_t size);
    };

#endif

PrintToString.cpp

#include "PrintToString.h"



PrintToString::PrintToString()
{
    data = new String();
}

PrintToString::~PrintToString()
{
    delete data;
    data = NULL;
}


String* PrintToString::results()
{
    return data;
}

void PrintToString::clear()
{
    delete data;
    data = new String();
}


size_t PrintToString::write(const uint8_t* buffer, size_t size)
{
    size_t n = 0;

    while (size--)
    {
        if (data->concat(*buffer++))
            n++;
        else
            break;
    }

    return n;
}

TestSketch.ino (I have left out content of all the constants)

#include <ESP8266WiFi.h>
#include <PrintToString.h>

const char*    WIFI_SSID
const char*    WIFI_PASS

const char*    API_HOST
const uint16_t API_PORT
const uint16_t LOCAL_UDP_PORT

WiFiUDP UDPClint;
PrintToString diagData;
uint64_t packetNumber = 0;

void setup()
{
    WiFi.begin(WIFI_SSID, WIFI_PASS);
    UDPClint.begin(LOCAL_UDP_PORT);

    while (WiFi.status() != WL_CONNECTED)
        delay(500);

    WiFi.printDiag(diagData);
    sendStringPacket(diagData.result());
    diagData.clear();
}

void loop()
{
    delay(1000);
}

void sendStringPacket(String payload)
{
    UDPClint.beginPacket(API_HOST, API_PORT);


    uint64_t thisPNumber = packetNumber++;
    String thisPNumberStr;

    while (thisPNumber > 0)
    {
        uint8_t digit = thisPNumber % 10;
        thisPNumberStr.concat(digit);

        thisPNumber /= 10;
    }

    UDPClint.write(';');

    for (uint64_t i = 0; i < payload.length(); i++)
        UDPClint.write(payload.charAt(i));

    UDPClint.endPacket();
}

Solution

  • This is because this class has a pure virtual function here:

    size_t write(uint8_t) = 0;

    A class with a pure virtual function cannot be instantiated. So method write(uint8_t) must be somehow implemented in your code.

    EDIT: Consider making use of the code you used in sendStringPacket() for write(uint8_t). You may be able to redirect output without using sendStringPacket(diagData.result()); statement.