The problem is a misunderstanding of what the guards include. Turn on protective measures so that the compiler does not see the same content again in the same translation system (for the same .cpp file). They do not prevent individual translation units from seeing the same code.
In your header file, you define (not just declare) variables. Therefore, each translation unit that includes a heading creates its own copy of these variables.
The correct way to do this is to define the variables in the .cpp file and only declare them in the header (in any case, protective measures must be present to prevent multiple inclusion in the same block of translations).
That is, in your sample.h file, prefix your variables with extern and remove the initializer (so that they are declared, not defined) and define them in the corresponding .cpp file (where the functions are also defined), putting the exact definitions from your header there .
In an unrelated note, you should put #include "mbed.h" in sample.h inside the included guards, because some compilers optimize compilation speed for such guards and that optimization does not work if there is material outside the included guards. Please note that this is not a correctness problem (assuming that mbed.h is also correctly protected by the included guards), but a performance compilation problem.
source share