Using Raspberry Pi 2 Camera from C++ Programs with Visual Studio

This tutorial shows how to use the Raspberry Pi 2 camera from C++ programs developed with Visual Studio and VisualGDB. Before you begin, install VisualGDB 5.0r5 or later. We will also show how to get the latest Raspberry Pi Jessie image and use the corresponding cross-toolchain for faster compilation.

  1. Download the Raspberry Pi Jessie image and write it to the SD card. Ensure you select the “Extend the Ext2FS partition” checkbox so that the Linux partition can fit the entire SD card:01-flash
  2. Start Visual Studio and open the VisualGDB Linux project Wizard:02-newprj
  3. Select “Application (executable file)” to create a new application project:03-newprjWarning: this tutorial uses GNU Make, that is not recommended for new projects and may not work with the latest Raspberry Pi toolchain. Please consider using Advanced CMake or MSBuild instead.
  4. If you have not installed the Jessie toolchain for Raspberry Pi yet, you can select “download more toolchains” and then pick the toolchain from the list. Ensure you select the latest Jessie toolchain:jessie
  5. Select the connection settings in the “Deployment computer” field or choose “Create a new SSH connection” if you have not connected to your Raspberry Pi  from VisualGDB before:04-jessie
  6. Press “Finish” to create your project. VisualGDB will test the toolchain and ensure that it can build code that runs on your Raspberry Pi without any problems:05-test
  7. VisualGDB may detect that the PATH variable is configured differently for interactive SSH sessions and commands started via SSH, potentially interfering with GDB debugging. Select “Fix value” to resolve this automatically:06-fixenv
  8. Build your project, set a breakpoint on the return statement and run it with F5. Check the output in the “gdbserver” window for the “Hello, World” message:07-hello
  9. Now we will configure the Raspberry Pi to use the camera module. Open the SSH Console via Debug->Windows->SSH Console:08-shell
  10. Click on the “open a new shell” link and run the “sudo raspi-config” command. Then use the arrow keys to enable the camera module:09-camera
  11. Select “Finish” and shutdown your Raspberry Pi. Once the power is unplugged, connect the camera module as shown below:camera
  12. We will use the Raspicam library from SourceForge to connect to the camera from C++ code. Download the latest source package and extract it somewhere on your Windows machine. Now we will import it to your Visual Studio solution by adding another project:10-newprj
  13. Specify the name and location for the wrapper project. It can be a different folder than the one with the sources of raspicam:11-raspicam
  14. On the first page of the wizard select “Import a project”:12-importcmake
  15. The next page will show the last used toolchain and computer locations. Click on the “cross-compiler” option and VisualGDB will load the last used settings automatically:13-machine
  16. On the last page specify the location of CMake on your Windows machine (you can download CMake for Windows here) and the directory where you have extracted the raspicam library:14-cmakeimp
  17. Before you can build the raspicam library, you need to download the /opt/vc directory from Raspberry Pi to the toolchain sysroot folder. This can be done by opening VisualGDB Project Properties, going to the Makefile Settings page, clicking “Synchronize Sysroot” and adding the “/opt/vc” folder to the folder list: 15-opt-vc
  18. The raspicam library checks the CMAKE_SYSTEM_PROCESSOR library to determine when it’s being built on Raspberry Pi. To support this, we need to specify the variable manually in the CMake project properties:17-processor
  19. If you try building the project now, CMake will complain that the mmal libraries are not found:16-mmal
  20. This happens because the library search paths in CMakeLists.txt are hardcoded to /opt/vc and do not use the sysroot variable. Modify CMakeLists.txt accordingly to fix this:
    FIND_LIBRARY(mmalcore_LIBS NAMES mmal_core PATHS ${CMAKE_SYSROOT}/opt/vc/lib)
    FIND_LIBRARY(mmalutil_LIBS NAMES mmal_util PATHS ${CMAKE_SYSROOT}/opt/vc/lib)
    FIND_LIBRARY(mmal_LIBS NAMES mmal PATHS ${CMAKE_SYSROOT}/opt/vc/lib)
  21. Now you should be able to build the RaspiCam project successfully:18-build
  22. In order to use the header files and libraries from the project add the corresponding paths to the include and library directories of your main project. Also add “raspicam” to the library list so that the project is linked against it:19-settings
  23. Finally, add a project reference to the RaspiCam library from your main project so that Visual Studio knows in which order to build the projects:20-prjref
  24. Now we can add some code using the camera to the main source file:
    #include <fstream>
    #include <iostream>
    #include <vector>
    #include <raspicam.h>
    #include <unistd.h>
     
    using namespace std;
     
     
    int main(int argc, char **argv) 
    {
        raspicam::RaspiCam camera;
        
        if (!camera.open()) 
        {
            cerr << "Could not open the camera" << endl; 
            return 1;
        }
        
        cout << "Initial delay..." << endl;
        sleep(3);
        cout << "Acquiring image..." << endl;
        camera.grab();
     
        std::vector<unsigned char> buf;
        buf.resize(camera.getImageTypeSize(raspicam::RASPICAM_FORMAT_RGB));
        
        camera.retrieve(buf.data(), raspicam::RASPICAM_FORMAT_RGB);
     
        std::ofstream outFile("output.ppm", std::ios::binary);
        outFile << "P6\n" << camera.getWidth() << " " << camera.getHeight() << " 255\n";
        outFile.write((char*)buf.data(), buf.size());
     
        cout << "Image saved to output.ppm" << endl;
        return 0;
    }
  25. If you build the project and start debugging it now, VisualGDB will report that the session could not be started and the detail window will show a missing shared library:21-library
  26. This happens because the CMake files in the RaspiCam project specify a lot of different targets and VisualGDB does not know which of them should be deployed. Open VisualGDB Project Properties for the library project and specify the missing library as the explicit debugged executable:22-sofile
  27. As VisualGDB deploys the outputs of the debugged project and all projects referenced by it, this will ensure that the library gets deployed along with the main binary and you should be able to run and step through the program:23-step
  28. Once the program exits, you can check the output window to see that the image has been written successfully:24-output
  29. If you are using a Custom edition or higher, you can configure VisualGDB to automatically convert the image to a .jpg one and download it to the Windows machine. Install the “netpbm” package on Raspberry Pi by running “sudo apt-get install netpbm” and add 2 actions shown below to the post-debug action list:25-custom
  30. If you run your project now, you should be able to see the output.jpg file copied to the project directory on the Windows machine:26-output
  31. As you have imported the RaspiCam project into Visual Studio, you can now use the Code Map window to explore the relations between its functions and fields used by them:27-codemap