Arduino Sampling library, able to recognize if other libraries are included.

Hi everyone, I would really appriciate your help.
I am a student working on an Ball on Beam shield project with arduino, but I am stucked right now.

I have a sampling library that is fully functional in meaning of code (interrupts and so on..), it also can recognize architecture and therefore change the timmer used.

But I need to adjust it, - WHENEVER THE LIBRARY FINDS OUT THAT Servo LIBRARY IS INCLUDED with AVR arch., it recoginzes it and sets itself to timer 2, because Servo is using timer 1.

For further understanding of topic, here are some infos on how does compilation works (let me know if I am wrong):

-The headers (.h) are compiled all together and exchange informations if included in one another, than they are compiled into an object - so the header knows that another header is included.
-All .cpp files in library folder are compiled separately, and all are compiled into functional objects!!!
See pic.1 - I added into 3 of .cpps in Servo library warning sentences (warnings are in slovak language) - all of them are compiled:

IDE has developed preprocessor macros (ARDUINO_ARCH_XXX). Those are different from tokens and are possible to recognize even from .cpp files.
That is how Servo library is able to activate only one .cpp file, out of many included in the folder.
thanks to ifdef condition (see pic.2)

I tried to use the same logic, working with tokens only.
Here is my library folders : (pics 4 5 6)
and the code of main header:

#include "Arduino.h"
#ifndef SAMPLING3_H_
#define SAMPLING3_H_



#if defined(ARDUINO_ARCH_AVR) && defined(Servo_h)
#include "avr_servo3/SamplingTimers3.h"
#elif defined(ARDUINO_ARCH_AVR) && !defined(Servo_h)
#include "avr3/SamplingTimers3.h"
#else
#error "This library only supports boards with an AVR, SAM or SAMD processor."
#endif


typedef void (*p_to_void_func)(); /*define a term p_to_void_func for pointer to function, which 
								  has a return type void and has no input parameters*/
class SamplingClass{

  public:

    SamplingClass();
    void period(unsigned long microseconds); 
    void interrupt(p_to_void_func interruptCallback);
    p_to_void_func getInterruptCallback ();
    float getSamplingPeriod();  
         
  private:
	
    static void defaultInterrupt();
    p_to_void_func interruptCallback;
     #if defined(ARDUINO_ARCH_AVR) && !defined(Servo_h)
		// Default: Timer1
		const unsigned long timerResolution = 65536; 					// AVR Timer 1 is 16bit            
		const unsigned char cpuFrequency = 16; 							// CPU frequency in micro Hertz
		#warning "sampling is running on timer 1"
	#elif defined(ARDUINO_ARCH_AVR) && defined(Servo_h)
	    	   // Default: Timer2
		const unsigned long timerResolution = 256; 					// AVR Timer 2 is 8bit            
		const unsigned char cpuFrequency = 16; 							// CPU frequency in micro Hertz
		#warning "sampling is running on timer 2"	
	#endif	
    float samplingPeriod;        		 	// Sampling period in seconds  
    bool setSamplingPeriod(unsigned long microseconds);
};
extern SamplingClass Sampling; 


#endif

Architectures sam and samd not in there yet, do not pay attention to that.

The problem is with recognizing library token(Servo_h) from servo lib., within Sampling library .
Here is what happens:
Step one:
.Ino file compiles (Servo.h included) and calls Sampling.h, witch recognizes insider tokens of Servo and sets to timmer 2 (just simplifing).
Step two:
.cpp file (All of them in library folder) compiles and each one runs on different timer.... see on pic.3

Therefore tokens are quiet useless in what I want to achieve.
Please any ideas about how to make it work???

Lukas009:
-The headers (.h) are compiled all together and exchange informations if included in one another, than they are compiled into an object - so the header knows that another header is included.

I don't fully understand what you're saying there, but I think it's not quite correct. The way it works is essentially as if the contents of the file replace an #include directive for that file.

Lukas009:
IDE has developed preprocessor macros (ARDUINO_ARCH_XXX). Those are different from tokens and are possible to recognize even from .cpp files.

The ARDUINO_ARCH_XXX macro is defined at the command line via a -D flag to the compilation command. For this reason, you could think of it as a "global" macro, which is visible in all translation units. However, if you define a macro in one translation unit, it will not be visible in other translation units.

Lukas009:
The problem is with recognizing library token(Servo_h) from servo lib., within Sampling library .

It's not clear to me exactly what you're trying to achieve, but I think my previous explanation of translation units explains your problem.

pert:
The ARDUINO_ARCH_XXX macro is defined at the command line via a -D flag to the compilation command. For this reason, you could think of it as a "global" macro, which is visible in all translation units. However, if you define a macro in one translation unit, it will not be visible in other translation units.

You have answered my question. And is there any possibility of creating a "global" macro on my own?
Because I really need my Sampling library to work with particular .cpp file when Servo library is included in sketch.

Lukas009:
is there any possibility of creating a "global" macro on my own?

Unfortunately this is quite difficult with the Arduino IDE. You would need to add your own -D flag to the compilation recipes in platform.txt. There isn't a way to do it from the sketch.

Lukas009:
Because I really need my Sampling library to work with particular .cpp file when Servo library is included in sketch.

The best solution I've found to this is to move all the code that's dependent on that macro to the .h file. As long as the #include directive for Servo.h comes before the #include directive for your custom .h file, the Servo_h macro will be visible in the custom .h file.

pert:
Unfortunately this is quite difficult with the Arduino IDE. You would need to add your own -D flag to the compilation recipes in platform.txt. There isn't a way to do it from the sketch.
The best solution I've found to this is to move all the code that's dependent on that macro to the .h file. As long as the #include directive for Servo.h comes before the #include directive for your custom .h file, the Servo_h macro will be visible in the custom .h file.

The idea of header occured to me as well, but my lecturor declined it.
But anyway thank you very much for your advices :slight_smile: