Sunday, 3 October 2010

Visual Studio 2010 Intellisense for Arduino

I use Visual Studio 2010 for work, I thought it would be nice to use it to write Arduino sketches, in particular because of Intellisense.

(Update 1 March 2011: added a #define to set the target Arduino board.)

On the web, various suggestions exist, including the Visual Studio plugin from visualmicro.com (which didn't work on my PC and feels like it needs a bit more rounding-off). Another alternative method is described on Arduino Playground and Instructables instruct on compiling avr hex files from Visual Studio.

Anyway, I was able to get Intellisense using the following steps. I hope it works for you too...

Objective 1: Make Visual Studio treat .pde files like .cpp files
  1. Start Visual Studio 2010
  2. Go to Tools >> Options >> Text Editor >> File Extensions
  3. Add extension "pde" with Editor "Microsoft Visual C++"
  4. Click OK
Objective 2: Create a MakeFile project and point it at the Arduino libraries
  1. Create a new project of type "MakeFile" (Visual C++ >> Makefile Project)
  2. Give it a name, for example, ArduinoVS. (This is also the name of the Arduino Sketch)
  3. Click through the wizard. You need not enter anything. We don't intend to build, only edit.
  4. Go to Project >> Properties >> Configuration Properties >> VC++ Directories
  5. Set "Include Directories" to the following 3 paths (this depends on where you installed the Arduino IDE on your computer):
  6. C:\Users\Thomas\Arduino\arduino-0018\hardware\arduino\cores\arduino;
    C:\Users\Thomas\Arduino\arduino-0018\hardware\tools\avr\lib\gcc\avr\4.3.2\include;
    C:\Users\Thomas\Arduino\arduino-0018\hardware\tools\avr\avr\include
  7. Set "Source Directories" to the same paths as above.
Objective 3: Let Intellisense get around the pre-compile actions of the Arduino environment
  1. Add a new C++ file to your project. Name it exactly like the project and give it a .pde extension, for example, "ArduinoVS.pde". This is your main sketch.
  2. At the top of that file, add
     #ifdef _MSC_VER
     // Select your target Arduino board here
     #define __AVR_ATmega1280__
     #define __attribute__(x)
     #define __inline__
     #define __cplusplus
     #define __builtin_va_list int
     #define __asm__(x)
     #include "WProgram.h"
     #endif
  3. You should now have intellisense support.
Objective 4: Tell the Arduino IDE to use an external editor
  1. Start the Arduino environment and open the above .pde file (ArduinoVS.pde)
  2. Go to File >> Preferences
  3. Check "Use external editor"
  4. You should now be able to compile and deploy with the standard Arduino IDE and be able to edit in Visual Studio with Intellisense. Whenever you rebuild, the Arduino IDE checks for file changes before building.
By the way, Visual Studio 2010 Express is free.


Now, back to CNC...

25 comments:

Tomas said...

Thank you! The arduino IDE is not very comfortably to code in. Especially if one is spoiled by using VC :)

Anonymous said...

Very cool. Used this to program VxWorks on PPC in Visual Studio using NMake.

Anonymous said...

Hi.. I'm exited about this possibility but am having a few issues...

1st. I want to use Visual Studio(VS) to create libraries for the arduino. I'm having problems having it recognize W.Program.

2nd. I have pasted in your ifndef section and have opened the arduino ide. I then include a library that I want to reference, and then try to compile and load via the arduino ide. It immediately pukes saying undefined reference to main and to loop...

Can you help?

Thomas said...

Anonymous:

Regarding question 1:
I have never written a library for an Arduino, and just had a quick look at http://arduino.cc/it/Hacking/LibraryTutorial, so apologies for my lack of insight. My view is that since an Arduino library requires the #include WProgram.h, you cannot put that include inside the #ifdef section. So, I would add the #ifdef section to the header file of your library, but would place the #include WProgram.h outside the section so that both, Arduino IDE and Visual Studio can see it.


Regarding question 2:
Not sure if that is a spelling erorr in your post, but the included section is an #ifdef and not an #ifndef section. Basically, it makes the section only 'visible' to Visual Studio, but not visible to the Arduino IDE. So, when you are in the Arduino IDE, first try compiling without that section altogether. If it doesn't work. It's another problem. If it does work, include the section. There should be no difference in compilation with the section added.

Hope this helps.

Thomas

Anonymous said...

Hi Thomas. Thanks for answering...
I'm trying to figure out what I get with the VS handshake...

Do I compile anything in VS? Take for example this very simple program below. I have it named ArduinoVS.pde and it resides in the ArduinoVS project. Intellisense underscores Serial. So, am I missing a library? I have tried including other Arduino libraries from the hardware subdirectory - and they become underlined...

#ifdef _MSC_VER
#define __attribute__(x)
#define __inline__
#define __cplusplus
#define __builtin_va_list int
#define __asm__(x)
#include "WProgram.h"

void setup(){

Serial.begin(9600);
}

void loop(){
Serial.print("Hello");

delay(1000);
}

#endif

Anonymous said...

P.S. I don't think I understand the whole picture from 10,000 feet. I get an VS editor, but I can't compile? If I have to remove the header info in the Arduino IDE, then I have to deselect the external editor and cut out the header information...

Is this right, or am I confused and not doing the operations correctly...

Thomas said...

Anonymous:

The presented setup with Visual Studio provides the ability to use Intellisense (including 'show definition'), and provide the general features of editing source code in Visual Studio which is much better and richer than the Arduino IDE. It does not provide any feature to compile, run, debug, or manage solutions etc. That could be done, but it's more complicated.

So, the big picture is this: You need to get VS to be able to display pde files in a C++ manner, then make VS Intellisense know where to look up source, but at the same time do it in a way that does not cause confusion in the Arduino IDE.

The trick here is the #ifdef instruction, which makes the code between #ifdef ... #endif be visible to Visual Studio, but be ignored by the Arduino IDE.

You last code snippet, for example, includes the loop and setup functions in the ifdef part, which means Arduino IDE can't see that, so it won't work.

Thomas

Anonymous said...

Ok, I think I am beginning to understand.

For code below, intellisense is
now underlining Serial...

Any ideas:

#ifdef _MSC_VER
#define __attribute__(x)
#define __inline__
#define __cplusplus
#define __builtin_va_list int
#define __asm__(x)
#include "WProgram.h"
#endif


void setup(){

Serial.begin(9600);
}

void loop(){
Serial.print("Hello");

delay(1000);
}

Thomas said...

Anonymous:
Variable Serial comes from HardwareSerial.h, which is included via WProgram.h, both of which are in the same folder, so it should just work. I don't have time to set up a project right now, but maybe there is something wrong with your library path setup in VS?

Anonymous said...

Thanks for answering... I'll double check.

Anonymous said...

Oh, and by the way Tomas.. I'm using the latest Arduino ide - which I think is 022...

Anonymous said...

Hi,

The Arduino Visual Micro Add-In for Visual Studio works well.

Yes it would certainly benefit from more work but it works and is being used by many people.

It is library and boards aware so very useful for full intellisense.

If you had a problem installing on your machine then please use the visual micro forum to find out why.

BUT if you only have the free version of Visual Studio (express) then it will not work.

Thanks

Visual Micro

Anonymous said...

Hi Tomas... Just wondering if you had a chance to see if Visual Studio 2010 intellisense works with Arduino 022... I'm stuck and don't know what else to test...

Anonymous said...

Hi Tomas... Any luck? Just wondering if you are available today to help?

Thomas said...

Anonymous: Sorry, I haven't had time. I am pretty confident it will work with version 022 as long as your paths are set up correctly in Visual Studio. Make sure the paths point at the correct folders depending on your installation and that there are no typos. I may have a go at checking it myself, but unlikely during the next few days.

Anonymous said...

Hi Tomas - I'm hanging in hoping that this will work...

Still having problems with intellisense underscoring Serial.

I'm including all of this info with the hope that it will help debug the problem and maybe help others trying to get this to work with Arduino 022 and Microsoft Visual Studio 2010 Professional v10.0.3

When I right mouse click on Serial, I choose F12 - go to Definition, which then spawns a new tab in VS with the file HardwareSerial.h and positions the cursor over the word Serial in the following set of code:

#if defined(UBRRH) || defined(UBRR0H)extern HardwareSerial Serial;

I followed these steps in setting up VS.

I went back through and carefully started from scratch with a new VS project: ArduinoVS
and a new ArduinoVS.pde c++ file.

I go to ArduinoVS property pages and pick VC++ Directories and
then for the 2 settings, Include Directories and Source Directories,
I use the following:

C:\conversion\Arduino\hardware\arduino\cores\arduino
C:\conversion\Arduino\hardware\tools\avr\lib\gcc\avr\4.3.2\include
C:\conversion\Arduino\hardware\tools\avr\avr\include

Your example had semi-colons which I ignored...

Here is the complete file which when linked with the Arduino v022 version, compiles files and loads onto the chip.

#ifdef _MSC_VER
#define __attribute__(x)
#define __inline__
#define __cplusplus
#define __builtin_va_list int
#define __asm__(x)
#include "WProgram.h"
#endif

/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
*/

void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}

void loop() {
int sensorValue = digitalRead(2);
Serial.println(sensorValue, DEC);
}

Thomas said...

Anonymous:
Well, you whittled away my resistance to investigate an interesting technical problem. :-)

I believe the problem is that the implementation of Serial (and a whole range of other classes and definitions) depends on the type of target microcontroller you are compiling for. My guess is that the Arduino IDE injects this information in a pre-compile stage or as an argument to the compiler.

I downloaded v022 and created a new VS 2010 project, following the instructions in the main blog post. Indeed, Intellisense has problems with Serial. The solution I found is to add a single #define to the #ifdef section to identify the type of Arduino board you are using. For me, I am using the 1280 Mega and your adjusted program now looks as follows and Intellisense correctly shows the properties/methods for global variable Serial:

#ifdef _MSC_VER
// Select your target Arduino board here
#define __AVR_ATmega1280__
#define __attribute__(x)
#define __inline__
#define __cplusplus
#define __builtin_va_list int
#define __asm__(x)
#include "WProgram.h"
#endif

void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}

void loop() {
int sensorValue = digitalRead(2);
Serial.println(sensorValue, DEC);
}


This additional #define should also ensure that you can only intellisense-'see' the right ports/pins that are available for your Arduino board.

I'm also updating the main post to include this additional line.

Hope this helps, and let me know if it does(n't).

Thomas

Anonymous said...

Hi Thomas - success. Your insight into the board definition was spot on. (But also check out my other discovery a bit further down regarding library includes)...

Here are my entries...

//#define __AVR_ATmega1280__
//#define __AVR_ATmega328__
#define __AVR_ATmega168__

I tested successfully with the 168 and it worked fantastically. I love the effect that when now typing Serial. and hitting the dot I see all of the members that are available.

You really helped out...

So, the next step, is how to include any of the other libraries in the hardware section... For example, try loading the Ethernet library in the libraries directory. I have include the path for this C:\conversion\Arduino\libraries
in vc++ properties under: include, library and source.

When I try to include the file, intellisense likes
#include


BUT the Arduino side likes:
#include

Problem is that when you try and compile it within Arduino, it will say it can not find the file.

Not sure what else to change...

Anonymous said...

Hum... I just noticed my message did not include what was in the brackets

for intellisense:
#include bracket Ethernet\Ethernet.h bracket

for arduino
#include bracket Ethernet.h bracket

Thomas said...

Anonymous:
Glad to hear it's working.

The different #include formats might mean you have to add another path to the project settings. Here is the MSDN description of the two styles of #include: http://msdn.microsoft.com/en-us/library/36k2cdd4(v=VS.100).aspx

There are still other language elements that don't work, for example, I haven't figured out how to make the assembly instructions behave nicely in VS. Try to enter the statement cli(); and you can see what I mean.

Nevertheless, I think it's a nicer way to write Arduino sketches than with the Arduino ide.

Thomas

Anonymous said...

Hi... I think the problem lies in the fact that the .h files are buried in a folder. If you extract from the folder and put them at the root of \libraries\ then everything is fine - everybody is happy...

If you look the External Dependencies drop down in the your project, the .h files come and go by including\excluding the extra folder... Meaning, take out .h and place it at root and then the .h appears in the list.


The only thing is that from an organizational standpoint, it means copying out all of the .cpp and .h files from the subdirectories and placing them at the root - that is fine as long as there isn't an associated keyword.txt file - which would not be unique... So the directories become placeholders for original copies and/or dump repositories for versions or examples...

Don't know if this triggers any ideas or not

visual micro said...

Thanks for this useful info. I am pleased to report that the Visual Micro product you mention above has now been matured to be a 100% clone of arduino

The new version of Arduino for Visual Studio automatically creates and maintains a .h that provides full arduino intellisense in Visual Studio.

Multiple serial tool windows, auto pause/restart for upload, programmer upload, burn bootloader and much more

Anonymous said...

Hi,
Is Visual Micro supposed to work with VS 2010 Express?
I installed it but no menu comes up.
Thanks.

Thomas said...

Anonymous: According to VM's comment above (23 Feb 2011) it will NOT work with the free (Express) edition.
Thomas

Visual Micro said...

Arduino for Visual Studio - Update

Microsoft have a free offer for Visual Studio professional called WebSiteSpark.

Any individual who is not a web designer and not working for a web design company gets a copy of vs pro for free (for 3 years).

You can find more info about it on the visualmicro.com web site

The Arduino addin for Visual Studio Pro has many new features to make arduino development easier amnd faster such as memory usage reporting, reference guides, comprehensive intellisense, detection of new libraries and upload support for all arduino boards including the usb arduino leonardo. It's free and worth a look.

Aug 2012: There is a unique arduino debug debug plugin for visual studio in final stages of beta. If you would like to beta test please say so when registering for the forum. You can read more about it on visualmicro.com.

I hope you don't mind this post and that you find it useful. Thanks