Developing in C on the AVR ATmega328P: Frequently Found Errors (FFE)

6 minute read

Where I attempt to gather in one place, all of the errors found while building (compile/link/locate) and uploading code to the Uno.

1. Everytime, I run make, I get an error from Makefile like “Makefile:65: *** missing separator. Stop.” or “Makefile:125….”

A: Make and tabs

2. I just downloaded the Windows AVR bundle from Zak and I’m getting this wierd error “error: array subscript 0 is outside array bounds”!

A: GCC 12 AVR array subscript 0 is outside array bounds

3. I get errors when I attempt to execute make, like “make: No targets specified and no makefile found. Stop.” or “undefined reference to ‘main’”

A: Developing in C for the ATmega328P: Build

4. I don’t understand how to solve this error “statement with no effect”

A: The full error is this:

make flash
avr-gcc -Og -ggdb -std=gnu99 -Wall -Wundef -Werror -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums  -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=9600UL -DSOFT_RESET=0 -I.  -I../../../Library -mmcu=atmega328p -c -o main.o main.c
main.c: In function 'main':
main.c:11:5: error: statement with no effect [-Werror=unused-value]
   11 |     init_serial;
      |     ^~~~~~~~~~~
cc1: all warnings being treated as errors
make: *** [main.o] Error 1

There are two answers:

  1. The specific answer to this particular problem is “add () to the end of init_serial”. An older version of the code used init_serial; as the complete command, it has since been changed to add a set of parentheses to make it look more like a function. (It is actually a macro.) It isn’t unusual to find older code which still uses the older version, which will cause an error.
  2. A more general (and better answer) is to “look at the examples”. In this case, the example is in a folder called serialio and the main.c program in it, uses the proper form init_serial();. While the answer #1 will solve the immediate problem, use answer #2 to solve similar problems with other functions.

5. I don’t understand how to solve this error “expected identifier”

A: Explanation

6. I don’t understand how to solve this error “implicit declaration”

A: Explanation

7. I tried “make flash” in the examples folder and I got a “fatal error….no such file or directory

A: The examples folder is one level higher than the dev lab content, so the the line in env.make needs to be changed from:

# Use this line to compile programs the dev folder
LIBDIR = ../../../Library
# Use this line to compile in programs in the examples folder
LIBDIR = ../../Library

8. I don’t understand how to solve this error “suggest parentheses around assignment used as truth value”

A: The full error message is this:

1
2
3
4
5
6
main.c: In function 'main':
main.c:34:13: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
   34 |         if (number = 0) {
      |             ^~~~~~
cc1: all warnings being treated as errors
make: *** [main.o] Error 1

Note that in line 3, we are attempting a comparison, which requires two “=” as compared to one. Once we added a second “=”, we had a line which looked like this:

        if (number == 0) 

and the code ran fine.

9. I don’t understand how to solve this error “expected ‘,’ or ‘;’ before”

A: The full error message is this:

1
2
3
4
5
main.c: In function 'main':
main.c:23:5: error: expected ',' or ';' before 'pinMode'
   23 |     pinMode(bit0, OUTPUT);
      |     ^~~~~~~
make: *** [main.o] Error 1
This is a fairly accurate error message, however, it is the previous line which is missing an “;” as in:
22
23
    int bit2 = 6
    pinMode(bit0, OUTPUT);
Add a “;” at the end of line 22, and the code will be fine.

10. I don’t understand how to solve this error “undeclared (first use in this function); did you mean ‘pow’?”

A: The full error message is this:

1
2
3
4
5
6
main.c: In function 'main':
main.c:35:32: error: 'Low' undeclared (first use in this function); did you mean 'pow'?
   35 |             digitalWrite(bit0, Low);
      |                                ^~~
      |                                pow
main.c:35:32: note: each undeclared identifier is reported only once for each function it appears in

I typically ignore the suggestions such as “did you mean ‘pow’”. In this case, “LOW” is mis-spelled as “Low”, I changed the spelling and it compiled.

11. I don’t understand how to solve this error “variable ‘input’ set but not used”

A: The full error message is this:

1
2
3
4
5
6
7
8
make flash
avr-gcc -Og -ggdb -std=gnu99 -Wall -Wundef -Werror -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums  -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=9600UL -DSOFT_RESET=0 -I.  -I../../../Library -mmcu=atmega328p -c -o main.o main.c
main.c: In function 'main':
main.c:21:10: error: variable 'input' set but not used [-Werror=unused-but-set-variable]
   21 |     char input;
      |          ^~~~~
cc1: all warnings being treated as errors
make: *** [main.o] Error 1

In reviewing my code, I realized while I declared the variable “char input” and defined it “input = getchar()”, I didn’t use it to define another variable or in a logic statement. In C, this is a warning. When we provide the compilation instructions, we ask the C compiler to treat all warnings as errors. This ensures we aren’t allowing a warning to slip by causing issues with our code later.

12. I don’t understand how to solve this error “error: ‘A0’ undeclared “. I’ve used the Uno pin A0 elsewhere, without this error.

A: The full error message is this:

1
2
3
4
5
6
7
avr-gcc -Og -ggdb -std=gnu99 -Wall -Wundef -Werror -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums  -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=9600UL -DSOFT_RESET=0 -I.  -I../../Library -mmcu=atmega328p -c -o main.o main.c
main.c: In function 'main':
main.c:22:32: error: 'A0' undeclared (first use in this function)
   22 |     const uint8_t analog_pin = A0;
      |                                ^~
main.c:22:32: note: each undeclared identifier is reported only once for each function it appears in
make: *** [main.o] Error 1

This error occurs when you attempt to use a Uno pin number, however, you haven’t included the Uno header file. Typically, the Uno header file “unolib.h” will have already been included, however, it some rare instances like this one, it hasn’t. The solution is to add:

#include "unolib.h"

at the beginning of the file with the other includes.

13. I don’t understand how to solve this error “invalid operands to binary ^” (have ‘float’ and ‘int’). I’m not using binary, I am attempting to raise a float to a power of 3.

A: The full error message is this:

1
2
3
4
5
6
avr-gcc -Og -ggdb -std=gnu99 -Wall -Wundef -Werror -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums  -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=9600UL -DSOFT_RESET=0 -I.  -I../../Library -mmcu=atmega328p -c -o main.o main.c
main.c: In function 'main':
main.c:25:43: error: invalid operands to binary ^ (have 'float' and 'int')
   25 |             float voltage = (analog_value ^ 3);
      |                                           ^
make: *** [main.o] Error 1

The problem is that the "^” operator in C is a binary XOR and not the power operator. To raise a variable to a power, use the powf(variable, power) function. The pow() function (without the f) is the double power operator.

14. In VS Code, my build task does NOT look like the one in the image:

VS Code AVR_C build task

VS Code AVR_C build task

Large Version to see detail

A: It appears the .vscode/tasks.json file is not setup correctly:

Follow this step to install the build task.

15. In VS Code, the file didn’t upload to my Uno

A If you see text in the VS Code Terminal window, which looks like this:

avrdude -q -q  -c arduino -p atmega328p -F -V -P /dev/ttyACM0 -b 115200 -U flash:w:main.hex
avrdude OS error: cannot open port /dev/ttyACM0: No such file or directory
avrdude error: unable to open port /dev/ttyACM0 for programmer arduino
make: *** [../../Makefile:185: flash] Error 1

This means your env.make doesn’t have the correct serial port or your Uno is not plugged into the Raspberry Pi. Use this command to determine the name of your serial port and correct it in the env.make file:

ls /dev/tty* | grep -E 'ACM|USB'

This command will respond with the name of the port, which you need to be using as in /dev/ttyACM0 or /dev/ttyUSB0. Make sure that specific string, is the same string you use in line 39 in env.make:

SERIAL = /dev/ttyACM0

Comments powered by Talkyard.