Access globals from more than one source file (VEXcode)

I had promised here to do a quick explanation on how to access global variables from several c++ source files.

The general idea is that global variables must be defined once only for the entire program. Any file that needs to access the same variable is told of it’s existence but does not declare it.

In main.cpp I declare two globals, instances of the motor class, LeftMotor and RightMotor.

main.cpp

#include "vex.h"

using namespace vex;

// A global instance of vex::brain used for printing to the V5 brain screen
vex::brain       Brain;

// define you global instances of motors and other devices here
vex::motor       LeftMotor( vex:: PORT1 );
vex::motor       RightMotor( vex:: PORT10, true );

int main() {
    int count = 0;
   
    driveForwards( 100 );
    this_thread::sleep_for(1000);
    driveForwards( 0 );
    
    while(1) {
        Brain.Screen.printAt( 10, 50, "Hello V5 %d", count++ );
        // Allow other tasks to run
        this_thread::sleep_for(10);
    }
}

(main also want to call the function driveForwards we deal with that in a similar way to the globals as the function itself is essentially global)

In a second source file, drive.cpp, we have a single function called driveForwards that wants to use the LeftMotor and RightMotor variables.

drive.cpp

#include "vex.h"

using namespace vex;

void
driveForwards( int32_t speed ) {
    LeftMotor.spin(fwd, speed, velocityUnits::rpm );
    RightMotor.spin(fwd, speed, velocityUnits::rpm );
}

now to hook it all together, in vex.h declare both LeftMotor and RightMotor as extern. The driveForwards function is also declared (a function prototype).

vex.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "v5.h"
#include "v5_vcs.h"

extern vex::motor       LeftMotor;
extern vex::motor       RightMotor;

void driveForwards( int32_t speed );
11 Likes

And even more generally.

Just pointing out there is nothing special about vex.h or the vex specific functions. We use extern to tell the compiler “hey trust this variable exists and that it will be defined somewhere else”.

8 Likes

I feel like I should thank you here rather than in the PMs, so thanks for this.

Thanks! I was going to ask your advice on how to make projects more modular as we prepare our software systems for next season. I will port the Autonomous Feature selector to a prototypebot VEXcode project and post it here for a critique.

@jpearman in your example in the motor instances there is no mention of gear setting, nor does it appear in the vex code article on adding smart motors. Is that going away?

In the import from VCS to VEX code it creates a robot-config.h which has smart motor instances like this:

vex::motor Rightfront (vex::PORT1, vex::gearSetting::ratio18_1,false);

So moving forward, which is preferred?

Nothing has really changed. There are multiple overloaded constructors for the motor class.

motor( int32_t index );  
motor( int32_t index, bool reverse );
motor( int32_t index, gearSetting gears );
motor( int32_t index, gearSetting gears, bool reverse );

not using a parameter will cause the default value to be used. default for reverse flag is false, default for gears is ratio18_1.

The samples in this first preview of VEXcode are taken directly from VCS and hence end up using the VCS format of using robot-config.h, they will be replaced soon with VEXcode specific samples, perhaps in preview 2 or 3. As VCS used graphical robot configuration, it was easier to use the most verbose version of constructors all the time when it generated the C++ code.

3 Likes