0

This has been a hard problem to diagnose, so I hope I'm giving enough info here. I'm trying to write a program for the Arduino (a lighting controller) using a bit of OO. There are several classes in my library, and some extend others. I'm a long-time programmer (mostly Java) but this is my first big Arduino project.

I'm using the Logging library at various points in the main program, as well as the objects, and that's where it get complicated. Depending on where I put calls to the logging library, or even Serial.print(), it either all works, or what gets sent to the serial port is a bit garbled, and the board never enters loop() (I'm not sure if that means that it's crashing in setup() or not). This library hasn't been touched in 4 years and there are pending merge requests, so I don't think I'll get answers from the developer.

I have a sneaking suspicion that the root of the problem is that Logging.h ends with instantiating the logger ("Logging Log = Logging();") so multiple instances of the logger may be created and the serial port is being reset several times, possibly at different port speeds. I thought it was bad form to initialize object, or even have any running code, in a .h file. Is this a possibility, and do I have any options to fix this?

Are there any good alternatives for printing outputs at different debug levels?

I would hate to have to pass the logger instance in as a parameter to my classes, or have to write setLogger() methods for all my classes.

Thanks.

0

Logging.h ends with instantiating the logger ("Logging Log = Logging();") so multiple instances of the logger may be created and the serial port is being reset several times, possibly at different port speeds.

I think you are mistaken, or have done something wrong with the library files. Logging.cpp ends with the instantiation, not Logging.h. Logging.h only has an extern reference to the instantiated object.

So some guesswork:

If you try and do anything with logging or serial access (or indeed anything more than just setting a few variables) within the constructors of your objects, and you instantiate those in the global scope, you won't have full access to the serial port - if any access at all. You can only use the serial port once Serial.begin(...) has been executed in setup, and global constructors are executed before setup() is run.

It is for this precise reason that 99% of Arduino libraries have a .begin() method which does all the work a constructor would normally do. The constructor is only used (if at all) for storing some default settings (pin numbers, etc) that are used later on. That way you have full control over what gets executed and when.

  • Yup, I see that extern is used in Logging.h. My bad, thanks. I DO have a constructor that calls a setter method on another class, and I have a Log line in the setter method of that second class. Maybe that's the problem. Not sure how to get around that, since I do want debugging. Maybe the answer is to create a .begin() method that does the same thing without the debugging. Thanks again @Majenko – dj_segfault May 31 '16 at 0:47
1

The constructor (called in a rather weird way) doesn't do anything, so I don't think that is the issue.

Logging.h:

    /*! 
     * default Constructor
     */
    Logging(){} ;

Logging.cpp:

 Logging Log = Logging();

You should be calling Log.init(whatever) once in your code (as in the example). Are you doing that?

Please post a Minimal, Complete, and Verifiable example.

Without any posted code, we can only guess at what you are doing.


I thought it was bad form to initialize object, or even have any running code, in a .h file. Is this a possibility, and do I have any options to fix this?

That is not done in the library you linked to.

  • Any logging libraries that you recommend @nick-gammon? Asking because this one hasn't been updated in ~5 years. (looking for debug/info etc levels of logging to serial output) – pherris Dec 11 '16 at 15:00
  • Well, I did a bit of work on debugging using a second Arduino using SPI or I2C. That (fairly quickly) lets you output debug messages via another processor, which has minimal impact on the board under test (it depends a bit on whether you have I2C or SPI free). You could modify the function calls to take a log level conceivably. You might want to post this as a new question to get comments and suggestions from others. – Nick Gammon Dec 11 '16 at 20:31

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.