0

I have a complex program I'm writing for Arduino, and I dont want to use avoid using globals, as this is not a good programming style.

see the two basic examples below, is there's a difference between them? Is there's anything happning in the system level after loop() function ends?

common Arduino project:

int a;

void setup() {
   a=0;
}

void loop() {
   int b = f(a);
   ++a;
   ...
}

Modular, more coherent programming:

//no globals!!!
void setup() {}//do not use it

void loop() {
    int a=0;
    for(;;)
    {
       //main aruduino loop
        int b = f(a);
       ++a;
       ...
       if (serialEventRun) serialEventRun();
    }
}

UPDATE:

following bolov 's answer and the Arduino main.cpp, I've updated the Modular example

Mercury
  • 1,886
  • 5
  • 25
  • 44
  • the `while (true)` is much much worse then a global variable. you can use `static int a` to create a 'global' variable with local scope. – Juraj Jun 19 '20 at 08:36
  • why is while(true) worse? this keeps a clean scope, and is equivelent to the actual for(;;) implementation. – Mercury Jun 19 '20 at 08:50
  • I would go the next step and create a embedded C or C++ project instead. I wouldn't write complex programs in Arduino. Of course you can always somehow find ways to create local variables or split your project into multiple files but I always feel very limited Arduino. I would do simple prototyping with Arduino and complex and production code without Arduino. – Thomas Sablik Jun 19 '20 at 22:19

1 Answers1

1

You shouldn't block the loop function in Arduino. If you look how main is defined (<arduino_install_dir>\hardware\arduino\avr\cores\arduino\main.cpp) you will see:


int main(void)
{
    init();

    initVariant();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }

    return 0;
}

If you block the first loop call with a while (true) you don't get serialEventRun a chance to be called. As far as I can tell it is used to handle serial events.

So yes, it is true that global variables should generally be avoided. However because of how Arduino sketch is designed for small programs I can say you should stick with the recommended Arduino style of global variables + setup + loop.

What you can do to alleviate this is organize your code into classes that abstract your model. For instance if you control a motor instead of:

#define DRIVER_EN   5
#define DRIVER_DIR  6
#define DRIVER_PUL  7

int motor_microstepping;
int motor_gear_ratio;

void setup()
{
    motor_microstepping = 8;
    motor_gear_ratio = 2;

    pinMode(DRIVER_EN, OUTPUT);
    pinMode(DRIVER_DIR, OUTPUT);
    pinMode(DRIVER_PUL, OUTPUT);

    digitalWrite(DRIVER_EN, LOW);
}

I have created a class for my motor controller. This is how it is used:

using namespace em::physics::literals;

em::motor::TB6600 slider_motor{
    5,       // EN
    6,       // DIR
    7,       //  PUL
    1.8_deg, // pulse_angle
    8,       // microstepping
    1,       // gear ratio
};

void setup()
{

    slider_motor.setup();
}

void loop()
{
    // ...
    slider_motor.enable();
    slider_motor.set_direction_low();
    //...
}
bolov
  • 72,283
  • 15
  • 145
  • 224
  • Why not just add "if (serialEventRun) serialEventRun();" in my while loop? :) Then I can actually controll (a) if I want to handle serial events (b) when to control them – Mercury Jun 19 '20 at 08:45
  • 1
    @Mercury I don't have enough experience and expertise to know if that is a bad thing or if you are safe to do that. – bolov Jun 19 '20 at 08:49
  • This is why I'm asking it here :) – Mercury Jun 19 '20 at 08:56