Ever since moving over from a Windows laptop to a MacBook as my everyday development machine, I have had to run Windows inside a VM to be able to use Visual Studio Pro which I used for all .NET development work. With the release of .NET Core and the light weight "Visual Studio Code" editor there was less need to use Windows, some time after that the full Visual Studio IDE was released for the Mac.

Arduino Development

When looking for a good alternative to use the Arduino editor, I noticed that there was an extension available for Arduino development as well the C/C++ extension, and both of them are developed by Microsoft.

By installing the following you can develop for the Arduino on your Mac:

The Arduino extension has several commands available in the command pallet which can be accessed by pressing F1

The "Arduino:Initialize" command configures the workspace, after asking for the name of the .ino file to create, you choose the board type and then the .vscode directory is created along with some config files.

C/C++ Intellisense

The "Arduino:Initialize" command also enables intellisense but does not properly configure all of the paths required for it work correctly. In this default configuration state the intellisense is useless, everything that you use from the various Arduino libraries will be underlined as a problem, so you either have to turn it off, or fix it.

Even the Arduino Blink test code shows intellisense problems.



To fix the intellisense you need to edit the c_cpp_properties.json file in the .vscode directory. The default file created by the "Arduino:Initialize" command is as follows:

{
    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino"
            ],
            "browse": {
                "limitSymbolsToIncludedHeaders": false,
                "path": [
                    "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino"
                ]
            },
            "intelliSenseMode": "clang-x64",
            "macFrameworkPath": [
                "/System/Library/Frameworks",
                "/Library/Frameworks"
            ]
        }
    ],
    "version": 3
}

The trick is to add all of the paths which contain the various AVR and Arduino libraries that may be used. Here is an example of what worked for me with an Arduino Uno/Nano.

{
    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "${workspaceRoot}",
                "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino",
                "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include",
                "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/avr",
                "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include",
                "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include-fixed",
                "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/variants/standard",
                "~/Documents/Arduino/libraries/some-library-you-are-using"
            ],
            "defines": [
                "UBRRH",
                "__AVR__",
                "__AVR_ATmega328P__",
                "__STL_HAS_NAMESPACES",
                "__STL_USE_NEW_IOSTREAMS"
            ],
            "browse": {
                "limitSymbolsToIncludedHeaders": false,
                "path": [
                    "${workspaceRoot}",
                    "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino",
                    "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include",
                    "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/avr",
                    "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include",
                    "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include-fixed",
                    "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/variants/standard",
                    "~/Documents/Arduino/libraries/some-library-you-are-using"
                ]
            },
            "intelliSenseMode": "clang-x64"
        }
    ],
    "version": 3
}

The same paths need to be included in both sections, the "defines" section contains the list of macro definitions that are used when the intellisense engine looks at the code in the libraries. Finding the correct macros is tedious, it depends on the hardware you are using and you have to search through the libraries to see where they are used. I also had some intellisense issues with the STL library I was using hence the 2 STL related entries. I removed the "macFrameworkPath" as I couldn't see why that should be listed.

The paths are not treated recursively and there seems to be no way of specifying how they are treated. I almost gave up on getting the intellisense to work and was just going to disable it, but in the end I spent some more time on it and managed to eliminate all but 2 false positives after a process of diminishing returns.

Conclusion

Getting the intellisense working was worth the effort, like anything new, there is always some pain involved getting everything working the way you want or expect it to work.

Next Post Previous Post