When to use const int, int, or #define
What is the difference between #define and const int when defining pin names in Arduino IDE?
Predefined Constants Reference
arduino uno - How do I set a constant in setup() that I can use in loop()? - Arduino Stack Exchange
You can't, and there's other things wrong with your code.
int sensorValue1 = analogRead(A0);
int sensorValue2 = analogRead(A1);
Calling functions from the global scope is an incredibly bad idea. Those are run before the board has been properly initialized, and the results you may get from it are not guaranteed in any way, shape, or form. Instead you must call functions like analogRead() from within another function, like setup(), or loop().
As for const - a const is just that - a constant value that can never change. You can only assign a value to it at the moment of creation.
And that means that you can only use it within the scope it was defined within. As you can't do that in the global scope (see above) then you cannot use a constant.
So just use a normal global variable. It will only change when you tell it to change. Using a const only makes sense when you have a numeric literal that you want to refer to by name. Using const doesn't protect the variable from being changed at run-time by memory leaks, etc, it just protects it from attempts to modify it at compile time - and if possible replace it with the numeric literal that it refers to.
So in summary just use:
int sensorValue1;
int sensorValue2;
int p1;
int t1;
void setup() {
sensorValue1 = analogRead(A0);
sensorValue2 = analogRead(A1);
p1 = (1.09512*sensorValue2-22.105)*133.3225;
t1 = (-0.08126*sensorValue1+65.6597)*274.15;
}
... etc ...
HOWEVER: Your program methodology is also completely flawed. You read the analog values once, and do calculations with them once, then repeatedly display the same values over and over again.
You must perform a new analogRead() of your sensors every iteration of loop() in order to update the values in your variables.
You can define Constants using the "const" keyword. Ex:
const float pi = 3.14;
const int foo = 12;
https://www.arduino.cc/en/Reference/Const
It's important to note that const int does not behave identically in C and in C++, so in fact several of the objections against it that have been alluded to in the original question and in Peter Bloomfields's extensive answer are not valid:
- In C++,
const intconstants are compile time values and can be used to set array limits, as case labels, etc. const intconstants do not necessarily occupy any storage. Unless you take their address or declare them extern, they will generally just have a compile time existence.
However, for integer constants, it might often be preferable to use a (named or anonymous) enum. I often like this because:
- It's backward compatible with C.
- It's nearly as type safe as
const int(every bit as type safe in C++11). - It provides a natural way of grouping related constants.
- You can even use them for some amount of namespace control.
So in an idiomatic C++ program, there is no reason whatsoever to use #define to define an integer constant. Even if you want to remain C compatible (because of technical requirements, because you're kickin' it old school, or because people you work with prefer it that way), you can still use enum and should do so, rather than use #define.
EDIT: microtherion gives an excellent answer which corrects some of my points here, particularly about memory usage.
As you've identified, there are certain situations where you're forced to use a #define, because the compiler won't allow a const variable. Similarly, in some situations you're forced to use variables, such as when you need an array of values (i.e. you can't have an array of #define).
However, there are many other situations where there isn't necessarily a single 'correct' answer. Here are some guidelines which I would follow:
Type safety
From a general programming point-of-view, const variables are usually preferable (where possible). The main reason for that is type-safety.
A #define (preprocessor macro) directly copies the literal value into each location in code, making every usage independent. This can hypothetically result in ambiguities, because the type may end up being resolved differently depending on how/where it's used.
A const variable is only ever one type, which is determined by its declaration, and resolved during initialisation. It will often require an explicit cast before it will behave differently (although there are various situations where it can safely be implicitly type-promoted). At the very least, the compiler can (if configured correctly) emit a more reliable warning when a type issue occurs.
A possible workaround for this is to include an explicit cast or a type-suffix within a #define. For example:
#define THE_ANSWER (int8_t)42
#define NOT_QUITE_PI 3.14f
That approach can potentially cause syntax problems in some cases though, depending on how it's used.
Memory usage
Unlike general purpose computing, memory is obviously at a premium when dealing with something like an Arduino. Using a const variable vs. a #define can affect where the data is stored in memory, which may force you to use one or the other.
constvariables will (usually) be stored in SRAM, along with all other variables.- Literal values used in
#definewill often be stored in program space (Flash memory), alongside the sketch itself.
(Note that there are various things which can affect exactly how and where something is stored, such as compiler configuration and optimisation.)
SRAM and Flash have different limitations (e.g. 2 KB and 32 KB respectively for the Uno). For some applications, it's quite easy to run out of SRAM, so it can be helpful to shift some things into Flash. The reverse is also possible, although probably less common.
PROGMEM
It's possible to get the benefits of type-safety while also storing the data in program space (Flash). This is done using the PROGMEM keyword. It doesn't work for all types, but it's commonly used for arrays of integers or strings.
The general form given in the documentation is as follows:
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};
String tables are a bit more complicated, but the documentation has full details.