Stream and prinln() within an own class

Hello, I have the following code and its TestClass:

#include "TestClass.h"

TestClass tc;

const uint8_t testarray[] =   { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                                0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };

void setup() {
  Serial.begin(115200);
  while(!Serial);
  tc.begin(Serial, testarray);
}

void loop() {
  delay(100);
  Serial.println("Test");
}

TestClass.h:

#ifndef TESTCLASS_H_
#define TESTCLASS_H_

#include "Stream.h"

class TestClass {
  public:
    TestClass();
    virtual ~TestClass();
    begin(Stream & stream, uint8_t testarray[]);
  private:
    Stream & m_stream;
    uint8_t m_array[];
};

#endif

And its TestClass.cpp:

#include "TestClass.h"

#include "Stream.h"

TestClass::TestClass() {
  // Constructor - Do not run any code here! Use begin() instead!
};

TestClass::~TestClass() {
  // Destructor - this should never be called!
};

TestClass::begin(Stream & stream, uint8_t testarray[]) {
  
  this -> m_stream = stream;
  
  memcpy(this -> m_array, testarray, 16);
  
  m_stream.println("Hello World!");
}

This does not work. When I upload my compiled sketch it does nothing (no printout to my serial port). When commenting out the m_stream.println() it does work.

Can someone explain me that behavoir and give me a better solution? :slight_smile:

Thank you!

First, you don't need the 'this->' construct.

Second:
'this -> m_stream = stream;' isn't what you need. I don't know what the Stream object's overload of the assignment operator is, but I don't think it's useful in this case. I'd use a pointer: 'streamPtr = &stream'.

for print only functions use the Print class instead of Stream.

you can assign &stream in constructor

TestClass::TestClass(Stream& stream) : m_stream(stream) {
}

Thank you very much, this solved my problem.

But I have another question.

Is it possible that after programming the controller and leaving the Arduino IDE open its screwing up the serial connection sometimes? Sometimes the controller seems not to start correctly even after pressing the reset button for many times. After disconnecting it from USB and reconnecting it just works fine as intended.

Some experiances? :slight_smile:

Thank you very much!


My code for other users to test:

#include "TestClass.h"

TestClass tc;

const uint8_t testarray[] =   { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                                0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };

void setup() {
  Serial.begin(115200);
  while(!Serial);
  tc.begin(& Serial, testarray);
}

void loop() {
  delay(500);
  Serial.println("Test");
}

TestClass.h:

#ifndef TESTCLASS_H_
#define TESTCLASS_H_

#include "Stream.h"

class TestClass {
  public:
    TestClass();
    virtual ~TestClass();
    void begin(Stream * stream, const uint8_t testarray[16]);
  private:
    Stream * m_stream;
    uint8_t m_array[16];
};

#endif

TestClass.cpp:

#include "TestClass.h"

#include "Stream.h"

TestClass::TestClass() {
  // Constructor - Do not run any code here! Use begin() instead!
};

TestClass::~TestClass() {
  // Destructor - this should never be called!
};

void TestClass::begin(Stream * stream, const uint8_t testarray[16]) {
  
  m_stream = stream;
  
  memcpy(m_array, testarray, 16);
  
  m_stream -> println("Hello world!");
}
void TestClass::begin(Stream * stream, const uint8_t testarray[]) {
 
  m_stream = stream;
 
  memcpy(m_array, testarray, 16);

You should NEVER assume that there are 16 bytes in the array passed in. You are copying the data to an array that you have sized to hold 0 elements. You are crapping all over memory you do not own.

Thanks, fixed it to 16 byte size :o