1

I'm working on a proof of concept for using the Adafruit_Thermal printer library with an ATTiny85.

The ATTiny85 does not come with hardware serial capability, so I started looking into using SoftwareSerial to create the serial port necessary. I started down this path and ran into an error in the thermal library's constructor:

// thermal-printer.ino example file

#include "SoftwareSerial.h"
#define TX_PIN 3
#define RX_PIN 4 


SoftwareSerial mySerial(RX_PIN, TX_PIN);


#include "Adafruit_Thermal.h"

Adafruit_Thermal printer(&mySerial); // Pass addr to printer constructor  

// Adafruit_Thermal.h

class Adafruit_Thermal : public Print
{

public:
    // IMPORTANT: constructor syntax has changed from prior versions
    // of this library.  Please see notes in the example code!

    Adafruit_Thermal(Stream *s = &Serial, uint8_t dtr = 255);

Documents/Arduino/libraries/Adafruit_Thermal_Printer_Library/Adafruit_Thermal.h:125:33: error: 'Serial' was not declared in this scope Adafruit_Thermal(Stream *s = &Serial, uint8_t dtr = 255);

If I understand correctly, the verification process is failing because the compiler is looking for a global Serial value in the Adafruit_Thermal.hfile that doesn't exist because the ATTiny85 does not have HardwareSerial.

But, going by the Adafruit_Thermal class' constructor signature the reference passing of Serial is just a default value (right?) so I should be able to remove it and pass in my software serial reference. The SoftwareSerial class inherits from Stream, so it should still be a valid reference pass:

// this:
Adafruit_Thermal(Stream *s = &Serial, uint8_t dtr = 255);

// changes to this:
Adafruit_Thermal(Stream *s, uint8_t dtr = 255);

But when I do that, I start getting verification errors that make it look like the thermal instance wasn't constructed, like:

undefined reference to `Adafruit_Thermal::begin(unsigned char)'

and

undefined reference to `Adafruit_Thermal::Adafruit_Thermal(Stream*, unsigned char)'

Does this mean the class isn't getting constructed?

I looked at the underlying constructor definition to see if something was blowing up in there, but there doesn't seem to be anything fancy at the constructor level:

// Constructor
Adafruit_Thermal::Adafruit_Thermal(Stream *s, uint8_t dtr) :
  stream(s), dtrPin(dtr) {
  dtrEnabled = false;
}

This should still work with the software serial reference pass, right?

I'm a bit lost on how to debug this now. Any ideas?

Update

After a reply from Majenko I pulled up the cpp file and looked at the header reference:

header reference

So this means the cpp file was still referring to the include path header file instead of the lib version?

I updated my cpp file to use:

#include "lib/Adafruit_Thermal.h"

and I still get undefined reference errors, so it may still be something else, but I wanted to share this additional info.

  • On the face of it, removing = &Serial is exactly what you want to do, and behaves exactly as you expect. I suspect the other errors you are now getting are unrelated. – Majenko Aug 13 at 15:43
  • Ah ok. I'll keep digging then. If I figure out exactly what was happening I'll post back. Thanks for the confirmation! – Chris Schmitz Aug 13 at 17:16
  • It looks like the IDE might not be compiling the .cpp file from the library. – Majenko Aug 13 at 17:17
  • OH! Holy cow I totally didn't think of that! I'm adding an update to show a screen shot. – Chris Schmitz Aug 13 at 19:21
  • 1
    Ah. So is there something you have to do in that IDE to say "Include the files in lib in the compilation`? – Majenko Aug 14 at 13:11
1

:'( it's a bitter sweet solution.

After @majenko's last comment:

Ah. So is there something you have to do in that IDE to say "Include the files in lib in the compilation`?

I remembered that this issue has bitten me before. Specifically, the issue of including subfolders into a sketch.

Normally in programming languages (at least all of the ones I work in normally), you can use relative paths or namespaces to include files from subfolders, but for some reason with Arduino if you want to include files from subfolders you have to put the files in a directory named src.

And it specifically needs to be src. You can't use lib or libs or source or whatevernameyouwant, it needs to be src.

I can't find a spot in the arduino reference docs or the IDE's github repository that explains that you need to use src for the subfolder name, but you can find various mentions in the forums. E.g.

https://arduino.stackexchange.com/a/54655/35534

So yeah, the solution to my problem was three parts.

  1. Adopting the Adafruit_Thermal library into my codebase so that I could edit the source code without worrying about those changes polluting the orginal.
  2. Removing the &Serial reference pass in the constructor declaration of Adafruit_Thermal.h
  3. using the src directory name to include things from a subfolder.

solution structure

After doing this, the sketch passes verification.

But here's the bittersweet part. After getting past all of this and seeing the compiler get past the sketch verification the bombshell dropped; the sketch is too big for the attiny:

heartbreak

I guess it was not meant to be :'(

Well, at least I know what was causing the linker/compiler errors and I'll be able to sleep at night :P

Thanks for your help Majenko :bows:.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.