The program runs on an ATtiny45 and simply transmits the temperature derived from an NTC via software emulated UART.
So far, it works but the size of the sketch is 4052 Bytes and this is too big as this is not the only thing the ATtiny is supposed to do.
As it seems, the core of the problem is the "mySerial.print(int(Temp))" function call.
For test purposes, I have replaced "int(Temp)" by "sensorValueA1", which is also an integer data type. Then, the sketch size is 2.574 Bytes. This would be perfectly acceptable.
Thanks for the quick answer.
Forgot to mention that type casting instead of using int() has no effect on the size. After compilation it has still 4.052 Bytes.
I do not know exactly what you mean, but why is the code significantly smaller when I replace the float variables in
Rntc = (R10k_ntc*Untc)/U10k_ntc;
by floating point numbers like 1.2345?
My biggest problem is to locate the origin of the problem. It is either in the obove mentioned line of code, as the substitution of this line results in smaller code, or it is in the line with
mySerial.print(int(Temp))
as the substitution of int(Temp) by "some chars" results in smaller code, too.
I never realized this problem when using an Arduino board, as these have enough memory, but there has to be some solution for the Tiny45.
as the substitution of int(Temp) by "some chars" results in smaller code, too.
When you quit printing Temp, the compiler sees that it is not necessary to compute it, so all the floating point arithmetic code is not linked in, resulting in a much smaller sketch.
If you are short of space, why not just send the analog reading (sensorValueA1) via serial print, and let the receiver do all that maths? Doing the log alone uses about 300 bytes. These chips don't have floating-point hardware so doing any sort of floating-point arithmetic is going to add to the program size somewhat.
I finally ended up with doing exactly this. But it is not an ideal solution as the temperature calculation within the controller offered the possibility to correct offsets given by the tolerances of the NTCs. By transmitting only the raw ADC data, the software at the PC has to be aware of the offsets of all transmitting devices.
Anyhow, I would like to understand this. I encountered, that compiling the original code for an Arduino Uno with both sending and not sending the temperature caused a difference of only 6 Bytes regarding the final sketch size. Compiling it for an ATtiny45 results in a vastly greater size difference.
Edit: Compiling it for Arduino UNO does not change things.
I took some other code, where I was printing the temperature to a LCD and transmitting it via UART.
If I switch off the data transmision, the code only shrinks a little bit. But switching off the LCD output, too, the sketch size is about 1900 Bytes smaller.
This strongly supports your comment on the compiler behaviour.
This strongly supports your comment on the compiler behaviour.
You can use objdump to dump the object files, to see what is actually happening. Using your original sketch, dump the object file. Then, change the print() statement to print a hardcoded value, instead of Temp. Compile and use objdump again. Notice how much code is NOT in the object file - nothing to do with floating point calculations, because the compiler can see that the result is never actually used, so there is no real need to perform the calculation.
This is really interesting. Until now, I never gave thought to this because when writing C programs for personal computers you rarely hit the memory limit.
That means, when I replace (for example) the expression
Rntc = (R10k_ntc*Untc)/U10k_ntc;
by
Rntc = 1.234; // some arbitrary value
the calculation of Temp will be performed as long as I print it, but the compiler "realizes" that the following code
That is quite interesting -- a day ago I thought that during compilation/linking everything from the source is going to be transformed into the binary program.
But there is always a lot to learn.
Thank you very much for these insights!
P.S.: I am aware of the fact that using the Arduino software platform for programming a Tiny45 might not be the best choice from the professional programmer's point of view. But as I am a chemist and try to monitor a -150 °C nitrogen gas stream for cooling ammonia rich crystals on a X-ray diffractometer, the whole platform offers me the possibility to build and program little environmental sensors. This is great. Thanks a lot guys!
The platform's fine. It saves space in a couple of ways. For one thing, the compiler aggressively optimizes away code that isn't needed. Second, the linker throws away functions that aren't called. (For example, if you use the math library and don't call log() then the code for that is not included).
However if you are running out of memory why not get a slightly larger chip? For example the Atmega328P? After all, it's only $5 and I bet that is a small part of your overall budget. Saves a lot of mucking around with the smaller chip.
Slightly larger? For 4¢ less than the price of an ATtiny45, @akkorber can get a processor with twice the memory. (In the U.S. ATtiny85s are sometimes cheaper than ATtiny45s. Rarely are they different by more than 20¢.)