Using Netbeans for Arduino Software Development

(Taken from http://mattzz.dyndns.org/wiki/bin/view/Projects/ArduinoAndNetbeans)

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).

So 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. ;-)

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 mac ports gcc version is rather old (4.0.2)

  • Using CrossPack
  • Compiling your own toolchain from scratch

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.

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

If you are using Arduino Mega ADK copy pins_arduino.h from /usr/local/arduino1.0/variants/mega/ otherwise your app will compile and upload, but the pins will be different

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
  • Go to the "code assistance" tab and add /usr/local/arduino1.0/cores/arduino for both C and C++

Windows

Add each lib folder, and the utility folders of Ethernet, SD, Wire, to the following

Code Assistance C and C++ Compiler Includes for C and C++ (time consuming but you only have to do it once)

Add your toolchain and make.exe /bin paths to the PATH environmental variable;

for me this was

C:\Downloads\arduino-1.0\hardware\tools\avr\bin; C:\Downloads\arduino-1.0\hardware\tools\avr\utils\bin;

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

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 options: -Os -Wl,--gc-sections -mmcu=atmega328p
  • 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.

Windows

You need to slightly modify the above commands; -C to the path of avrdude.conf -P to the COM port of your Arduino

Mine look like this;

	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 C:\Downloads\arduino-1.0\hardware\tools\avr\etc\avrdude.conf -p atmega328p -c arduino -P COM20 -b115200 -D -F -V - Uflash:w:${CND_ARTIFACT_PATH_${CONF}}.hex:i 

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!

Extras that may be required (Netbeans 7.2 on a Mac)

  • If your 'make upload' in project configuration is not being called, try just adding .upload to you .build-post step ie. build-post: .build-impl .upload

  • You may also need to specify the location of avr-size etc. To do this, add these lines to the environment section at the top of your makefile (change directories as required)
AVROBJCOPY=/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-objcopy
AVRSIZE=/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-size
AVRDUDE=/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avrdude
  • Once you've done this, reference the call to the binaries in the standard makefile way ie. <tab>${AVRSIZE} etc.

  • Don't forget to specify the correct location of your avrdude.conf file eg. (for a Mac)

    -C/Applications/Arduino.app/Contents/Resources/Java//hardware/tools/avr/etc/avrdude.conf

  • I also had to specify the correct #include directory in project setting for Arduino.h.

In summary, all works well on a Mac, but you may need to go through your settings fixing the standard bits and pieces in project settings and the makefile. Pete

Windows additions by josephdouce

Share