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.h
file 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:
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.
1 Answer 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.
- Adopting the
Adafruit_Thermal
library into my codebase so that I could edit the source code without worrying about those changes polluting the orginal. - Removing the
&Serial
reference pass in the constructor declaration ofAdafruit_Thermal.h
- using the
src
directory name to include things from a subfolder.
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:
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:.
= &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.lib
in the compilation`?