Using Netbeans for Arduino Software Development

Synopsis: This is about setting up a Netbeans environment for Arduino programming. No plugins, no external Makefiles required.

The Arduino environment is great for getting started without requiring any knowledge about compiler, linker and all the stuff 'under the hood'. For that reason the Arduino IDE is kept somewhat simple and lacks features that are essential when 'quick hacking' or 'rapid prototyping' turn into software development.

Approach

There are approaches that are using custom Makefiles that have to be adapted and copied in your Netbeans project directory. One good example is Kerry Wongs Makefile and Netbeans Plugin. It works but lacks basic dependency checking. I did not like the fact that the core lib files were compiled every time (same with the Arduino IDE, btw).

I wanted to see if Netbeans can be configured for Arduino software development using just the means that are provided by Netbeans.

This was done on Mac OS X 10.7 using Arduino 1.0 and Netbeans 7.0.1. It should work as well on any other system.

It looks really complicated but it isn't. big grin

Requirements

Cross Compiler Toolchain

There are a couple of options here:
  • Using the Arduino Toolchain (on a Mac located at /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin)
  • Using Mac Ports: sudo port install avr-binutils avr-gcc avr-libc avrdude Beware: As of today the gcc version is rather old (4.0.2)
  • Using CrossPack
  • Compiling your own toolchain from scratch, e.g. german howto

I went with the CrossPack package for Mac OS X.

Make sure your cross compiler binaries are in the $PATH.

Arduino core lib and other libraries

The nice thing about Arduino is that it comes with a nice core library and a truckload of additional libraries and examples for SPI, LCD, SD cards, OneWire protocol etc. We need these files.

I copied them to /usr/local/arduino1.0 because in case of an update of the arduino software my stuff will stil compile.

  1. copy everything from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino to /usr/local/arduino1.0/
  2. copy everything from /Applications/Arduino.app/Contents/Resources/Java/libraries to /usr/local/arduino1.0/
  3. copy /usr/local/arduino1.0/variants/standard/pins_arduino.h to /usr/local/arduino1.0/cores/arduino

Setting up Netbeans

Setting up a new tool collection

Netbeans needs to know what compiler toolchains to use for which project and where to find it:
  • Netbeans, Preferences, C/C++: Add a toolchain
  • Enter base directory, set "Tool Collection Family" to GNU, name it e.g. "Arduino"
  • Adjust pathes to binaries of avr-gcc, avr-g++, avr-as and avr-gdb

Screen_Shot_2012-01-08_at_18.25.35.png

  • Go to the "code assistance" tab and add /usr/local/arduino1.0/cores/arduino for both C and C++

Screen_Shot_2012-01-08_at_18.40.11.png

Compiling the Arduino core lib

We want to create a static core lib library that we can link our projects against later:
  • Create a new project: C/C++ static library
  • Name it "arduino_corelib"
  • Select Arduino toolchain
  • Click "Finish"
  • Right-click on the newly created project "arduino_corelib" and select "Add existing Items from Folders..."
  • Select /usr/local/arduino1.0/cores/arduino
  • Click "Add"
  • Set project configuration to DEBUG (Menu: Run, Set Project Configuration)

Now we have to adjust some compiler settings for this project.

Breaking down the compiler options that we are going to use:
  • -Os: Optimizing size
  • -Wall: Print all warnings
  • -ffunction-sections -fdata-sections: Arduino IDE does this, so I copied it: "Place each function or data item into its own section in the output file if the target supports arbitrary sections. The name of the function or the name of the data item determines the section's name in the output file."
  • -mmcu=atmega328p -DF_CPU=16000000L: Type and speed of the microcontroller
  • -DARDUINO=100: Arduino specific define, software revision of the libs.
  • -fno-exceptions: (g++ only!): Disables exception handling

Screen_Shot_2012-01-08_at_18.52.24.png

This is done in the project properties:
  • Right-click on the arduino_corelib project and select "Properties"
  • Select Build, C Compiler
  • Add include directory: /usr/local/arduino1.0/cores/arduino
  • Add additional compiler options
-Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=100
  • Select Build, C++ Compiler
  • Add include directory: /usr/local/arduino1.0/cores/arduino
  • Add additional compiler options:
-Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=100
  • Select Build, Archiver
  • Adjust pathes for ar and ranlib to avr-ar and avr-ranlib

Now we are ready to compile the corelib:
  • Press F11 (Build Main Project)
You should find a nice corelib under dist/Debug/Arduino-MacOSX/libarduino_corelib.a in your Netbeans project directory.

Compiling a simple program

We are going to create a simple main.cpp that toggles the onboard LED connected to port 13.
  • Create a new C/C++ application, name it e.g. "blink", set toolchain to "Arduino"
  • Edit main.cpp:
#include <Arduino.h>
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
  This example code is in the public domain.
 */
int main(void)
{
	init();
	setup();
	for (;;)
		loop();

	return 0; // must NEVER be reached
}

void setup() {                
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(13, OUTPUT);  
  }

void loop() {
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);              // wait for a second
}

  • Edit projects settings, apply same compiler/linker config as above (include path and compiler options for gcc/g++)
  • Edit linker settings:
    • Add additional linker directory: Path of your libarduino_corelib.a (e.g. /Users/mattzz/NetBeansProjects/arduino_corelib/dist/Debug/Arduino-MacOSX)
    • Add library: Add libarduino_corelib.a file
    • Add library: Standard library: Mathematics
    • Set tool: avr-gcc
    • Add additional linker settings: -Os  -Wl,--gc-sections -mmcu=atmega328p

Screen_Shot_2012-01-08_at_20.45.41.png

  • Build main project

If everything went well you will find a file dist/Debug/Arduino-MacOSX/blink build/Debug/Arduino-MacOSX/main.o

Great, so what are we supposed to do with that? We have to convert the file to hex format and upload it to our device. One final tweak and we are done.

Converting to Intel HEX format and uploading

We are going to use Netbeans' generated makefiles. They provide several hooks that we can use.
  • In the project explorer, open "Important Files" and open "Makefile"
  • Add a line after the .build-post target, starting the line with a real TAB:
	avr-objcopy -O ihex ${CND_ARTIFACT_PATH_${CONF}} ${CND_ARTIFACT_PATH_${CONF}}.hex
	avr-size --mcu=atmega328 -C ${CND_ARTIFACT_PATH_${CONF}}
  • Add a new target called upload, change the path for avrdude.conf and the tty device according to your environment:
upload: .build-post
	avrdude -C/usr/local/CrossPack-AVR/etc/avrdude.conf -patmega328p -carduino -P/dev/tty.usbmodem1d11 -b115200 -D -F -V -Uflash:w:${CND_ARTIFACT_PATH_${CONF}}.hex:i 

So a part of your makefile should look like:
[...]
.build-post: .build-impl
# Add your post 'build' code here...
	avr-objcopy -O ihex ${CND_ARTIFACT_PATH_${CONF}} ${CND_ARTIFACT_PATH_${CONF}}.hex 
	avr-size --mcu=atmega328 -C ${CND_ARTIFACT_PATH_${CONF}}
	
upload: .build-post
	avrdude -C/usr/local/CrossPack-AVR/etc/avrdude.conf -patmega328p -carduino -P/dev/tty.usbmodem1d11 -b115200 -D -F -V -Uflash:w:${CND_ARTIFACT_PATH_${CONF}}.hex:i 

#clean
[...]

  • Open up the project properties, open category "Run"
  • Change "Run Command" to make upload
  • Press F6 and check the output.

If everything went well you will see your Arduino board blinking.

Adding libraries (SD, LiquidCrystal, SPI etc.)

  • Right-Click project, select "Add Existing Item..."
  • Navigate to /usr/local/arduino1.0/libraries/LiquidCrystal
  • Select LiquidCrystal.cpp and LiquidCrystal.h files (ignore example directories!)
  • Add include directories for C and C++ compiler: /usr/local/arduino1.0/libraries/LiquidCrystal
  • If you want editor coding support, you have to add the same path in the global Netbeans settings:
    • Menu Netbeans, Preferences: C/C++ Settings, Code Assistance tab
    • Select Arduino toolchain
    • Add include directory /usr/local/arduino1.0/libraries/LiquidCrystal for C and C++

Rinse and repeat for every library you are going to use.

The good news is: Once you have set up coding project for Arduino you can just copy it (right-click project) and go from there.

Did anybody say "serial console"?

Use gnu screen, e.g. port install screen. Best console ever!
  • Connect your Arduino board (otherwise the interface will not come up on your computer)
  • Find your usb device: ls /dev/tty.* e.g. mine is called /dev/tty.usbmodem1d11
  • screen /dev/tty.usbmodem1d11
  • To quit hit 'CTRL-a' followed by 'k' (kill)

Happy hacking!

-- MatthiasWientapper - 08 Jan 2012
Topic revision: r4 - 09 Jan 2012, MatthiasWientapper
 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback