Fixing "was not declared in this scope" in Arduino
Beginner
Or see every lesson.
- 455parts on the bench
- 43boards running now
- 1.00xreal time, on every board
The Arduino IDE’s compiler says 'reading' was not declared in this scope when your sketch uses a name it has not met at that point in the file. It is the most common Arduino error there is, and it has about six causes. The name in the quotes is the clue: it tells you which word to look for, and the line number tells you where the compiler gave up looking.
Mokxi compiles with clang rather than GCC, so in its build tab the same mistake reads use of undeclared identifier 'reading'. The causes and the fixes are the same in both. The circuit above is a button and an LED on an Uno with a working sketch: open it in the editor, make each mistake below on purpose, press Run to see the error, then put it right.
A typo, or the wrong capital letter
C++ is case sensitive, so digitalwrite, pinmode and serial.println are different names from digitalWrite, pinMode and Serial.println, and none of them exists. Both compilers usually spot this and suggest the right one: clang says did you mean 'digitalWrite'?, and GCC adds a note with a suggested alternative. Take the suggestion; it is almost always right.
Your own names work the same way. A variable declared as ledPin and used as LEDpin or ledpin is undeclared. Pick one style, such as camelCase for variables and capitals for constants, and typos like these get easier to see.
Declared inside braces, used outside them
A variable exists from the line that declares it to the closing brace of the block it is in, and nowhere else. This is the cause that confuses people most, because the declaration is right there on the screen a few lines up. In if (millis() > 1000) { int reading = analogRead(A0); } the variable reading is gone at the closing brace, so a Serial.println(reading); after it fails. The same happens to a variable declared in setup() and used in loop(): each function is a block of its own.
The fix is to declare it where every line that uses it can see it: before the if, at the top of loop(), or, for a value that has to last from one pass of loop() to the next, at the top of the sketch outside every function. A global like that is also the only way for setup() and loop() to share a variable.
const int LED_PIN = 13;
int presses = 0; // global: every function sees it, and it keeps its value
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(2, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int reading = digitalRead(2); // local: it starts again on every pass
if (reading == LOW) {
presses = presses + 1;
Serial.println(presses);
delay(250);
}
digitalWrite(LED_PIN, reading == LOW ? HIGH : LOW);
}A library object without its #include
Code copied from a tutorial often loses its first lines. Without #include <LiquidCrystal_I2C.h> at the top, the line that creates the display fails first, with 'LiquidCrystal_I2C' does not name a type from GCC (clang: unknown type name 'LiquidCrystal_I2C'), and then every later use of lcd fails with "was not declared". Fix the first error and the rest go with it.
If the #include is there and the error stays, the library is not installed, or a different library with the same header name is. There are several LiquidCrystal_I2C libraries, and they do not all name their functions the same way: one has init(), another begin(). In the Arduino IDE, install the one the tutorial used from the Library Manager. Mokxi carries the common libraries under their usual names, and for others its build tab offers to install one from the same Arduino Library Manager.
A name that belongs to another board
Some names only exist on some boards. Serial1 is the second serial port of a Mega or a Leonardo, and an Uno has none, so a sketch written for a Mega fails on an Uno with 'Serial1' was not declared in this scope. Clang adds did you mean 'Serial'?, which compiles but is not what the sketch meant. Pin names like D5, which ESP8266 boards define for their silk-screen labels, fail on an Uno the same way.
Check that the board selected in the IDE is the one the sketch was written for, or change the sketch: on an Uno, a second serial port means SoftwareSerial on two ordinary pins. In Mokxi the board in the circuit is the board the code is compiled for, so the same sketch can build on a Mega in one project and fail on an Uno in another.
Used above the line that declares it
Functions are forgiving. The Arduino IDE, and Mokxi, write a declaration for every function in the sketch before compiling it, so loop() can call a function written below it. Variables, constants and #defines get no such help: a const int LED_PIN = 9; at the bottom of the sketch is undeclared in every function above it. Keep them at the top.
A few functions miss out on that automatic declaration, and a call above one of them fails with this same error; the compile errors guide lists which. For those, write the one-line declaration at the top yourself, such as void blinkTimes(int count);, and the call works wherever it is.
A global in another tab
A sketch split into several .ino tabs is joined into one file before it is compiled: the main tab first, then the others in alphabetical order, in the Arduino IDE and in Mokxi. Functions are fine wherever they are, because they all get declarations at the top. A global variable is not: one declared in a tab called settings comes after the main tab’s code, so the main tab cannot see it. Put shared globals at the top of the main tab.
Questions
What does "was not declared in this scope" mean?
The compiler met a name, a variable, a function or an object, that it does not know at that point in the sketch. The name is in the quotes. Either it is misspelled, it was declared somewhere this line cannot see, or it comes from a library or a board that is not there.
Why is my variable not declared when I can see it?
Because it is declared inside a pair of braces, an if, a for or another function, and used outside them. Move the declaration up, above the block, or to the top of the sketch.
How do I fix "Serial1 was not declared in this scope"?
The sketch was written for a board with more than one serial port, such as a Mega or a Leonardo. Select that board, or on an Uno or a Nano use SoftwareSerial on two free pins.
Is "use of undeclared identifier" the same error?
Yes. It is clang’s wording for the same mistake; GCC, which the Arduino IDE uses, says "was not declared in this scope". Mokxi compiles with clang, so its build tab shows clang’s words.
Keep going
Where the facts on this page come from
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.