I am writing a program that will eventually run on an Attiny 45 but it is much easier to develop it on an Uno.
While developing it on the Uno I can use Serial.println() to display useful debugging information but, of course, hardware Serial doesn't work on an Attiny.
I can make the Serial.println() stuff "disappear" when the Attiny version is compiled by doing this sort of thing
#if defined(UNODEV)
Serial.println("a test message");
#endif
but it is very tedious having to make three lines of text for every Serial.println() and it makes it difficult to follow the code.
Is there any simpler method to have Serial.println() compiled in one version and not in another version.
I don't need to see any of the development messages on the Attiny.
I haven't bothered to go see what UBRRH and UBRR0H are but I guess they indicate the presence of the hardware UART. In any case, as long as nobody goes making any sweeping changes to HardwareSerial.h I don't see any problem using similar preprocessor conditions to select your macro definitions along the lines AWOL suggested.
I had been thinking of writing a routine that was a proxy for Serial.print but I had assumed I would need to allow for all the different data types that can be passed to Serial.print. I hadn't thought of using a macro.
I presume, based on your example, that everywhere I would normally use Serial.print() I will just use dprint().
This has the another enormous advantage of reducing the number of characters to be typed. If it works I think I will use it all the time.
The method I showed is only an outline - it doesn't define "println" or methods where you want to have a radix specifier (e.g. "Serial.print (val, HEX);"), but once you've written your macros, you can stick them in an include file and mostly forget about them.
I've analyzed verbose compilation output, but i still can't understand how compiler detects if UBRRH is defined or not. Can you explain it to me? I don't see any #include for product family headers
Graynomad:
Definitions for things like UBRRH are buried in AVR header files like iom32.h, look in
\hardware\tools\avr\avr\include\avr\
For all the chip definition files
Rob
Yes i did it and i found avr, avr-3, avr-4 folders in my desktop Arduino distribution and i've found definitions for UBRRH. But i need to understand the algo how to define what header should be included to -I paths or compiled libraries to -L paths
LarryD:
If you use a program like notepad++ you have the ability to search and replace.
To remove all Serial.print stuff:
Search
Replace...
Find what: Serial.
Replace with: //Serial.
Replace all.
You did not understand. i do WRITE smth like Notepad++ with autocomplete for Arduino so i need to know how to build command-line for compile (autocomplete to be more detailed) dependent on board type
So the file io.h decides what to include based on some definitions, for example
#elif defined (__AVR_ATmega32__)
# include <avr/iom32.h>
Is "AVR_ATmega32" etc defined in the command line with a -D?...no I don't see it, there is a "-mmcu=" switch that I think gets its value from boards.txt. That probably causes the correct file to be included but the link escapes me at this point.
Graynomad:
So the file io.h decides what to include based on some definitions, for example
#elif defined (__AVR_ATmega32__)
# include <avr/iom32.h>
Is "__AVR_ATmega32__" etc defined in the command line with a -D?...no I don't see it, there is a "-mmcu=" switch that I think gets its value from boards.txt.
Absolutely correct:
in "boards.txt" file
uno.name=Arduino Uno
...
uno.build.mcu=atmega328p
and i know mcu for the board and pass -mmcu argument just like desktop IDE does:
By the way, I thought I'd just point out "variadic macros" at this point, which can be very useful.
Variadic macros can have a variable number of arguments, which is great for creating this kind of debug print strategy when the target function can have different numbers of arguments:
The (...) tells the macro preprocessor that this is a place-holder for an unknown number of arguments. All those arguments are then put in wherever the VA_ARGS symbol is found within the macro.
This allows you to use:
dprint("Debug value: ");
dprintln(myVal, HEX);
without having to define options for all the different quantities of arguments.
Graynomad:
Is "AVR_ATmega32" etc defined in the command line with a -D?...no I don't see it, there is a "-mmcu=" switch that I think gets its value from boards.txt. That probably causes the correct file to be included but the link escapes me at this point.
If you use -mmcu=, the compiler will automatically define the appropriate _AVR macro.
Graynomad:
Is "AVR_ATmega32" etc defined in the command line with a -D?...no I don't see it, there is a "-mmcu=" switch that I think gets its value from boards.txt. That probably causes the correct file to be included but the link escapes me at this point.
If you use -mmcu=, the compiler will automatically define the appropriate _AVR macro.
How does it know what file needs to be included and what macro should be added?
The IDE in boards.txt has a line .build.mcu=. When you select the board type (tools->board), it will look at boards.txt to see what options to pass. The build.mcu option says to add the appropriate -mcu= to the compile line. So for an example, the lines for the Uno are:
MichaelMeissner:
The IDE in boards.txt has a line .build.mcu=. When you select the board type (tools->board), it will look at boards.txt to see what options to pass. The build.mcu option says to add the appropriate -mcu= to the compile line. So for an example, the lines for the Uno are:
The **uno.build.mcro=atmega328p** line says to add the **-mcu=atmega328p** option to the compiler.
If you look in the compiler source, in *<gcc>***/gcc/config/avr/avr-mcus.def**, there is the line for atmega328p board:
The third argument gives the identifier to be defined (**__AVR_ATmega328P__** in the case of the Uno).
I'm getting closer and closer.
So in order to emulate this avr-gcc toolchain -mmcu arg usage i need to define AVR_ATmega328P definition and include file "m328.h" in sketch code and it's path to I: