Czy są źli? Może. Problem z globalnymi polega na tym, że mogą być one dostępne i modyfikowane w dowolnym momencie przez dowolną wykonywaną funkcję lub fragment kodu, bez ograniczeń. Może to prowadzić do sytuacji, które, powiedzmy, są trudne do prześledzenia i wyjaśnienia. Pożądane jest zatem zminimalizowanie ilości globali, jeśli to możliwe, przywrócenie tej wartości do zera.
Czy można tego uniknąć? Prawie zawsze tak. Problem z Arduino polega na tym, że zmuszają cię do tego dwufunkcyjnego podejścia, w którym zakładają ciebie setup()i ciebie loop(). W tym konkretnym przypadku nie masz dostępu do zakresu funkcji wywołującej tych dwóch funkcji (prawdopodobnie main()). Gdybyś to zrobił, byłbyś w stanie pozbyć się wszystkich globali i zamiast tego użyć miejscowych.
Wyobraź sobie następujące:
int main() {
setup();
while (true) {
loop();
}
return 0;
}
To prawdopodobnie mniej więcej tak wygląda główna funkcja programu Arduino. Zmienne, których potrzebujesz zarówno w funkcji, jak setup()i w loop()funkcji, byłyby wówczas najlepiej zadeklarowane w zakresie main()funkcji niż w zakresie globalnym. Można je następnie udostępnić dwóm pozostałym funkcjom, przekazując je jako argumenty (w razie potrzeby używając wskaźników).
Na przykład:
int main() {
int myVariable = 0;
setup(&myVariable);
while (true) {
loop(&myVariable);
}
return 0;
}
Pamiętaj, że w tym przypadku musisz również zmienić podpis obu funkcji.
Ponieważ może to nie być wykonalne ani pożądane, widzę naprawdę tylko jeden sposób na usunięcie większości globali z programu Arduino bez modyfikowania struktury programu wymuszonego.
Jeśli dobrze pamiętam, możesz doskonale używać C ++ podczas programowania dla Arduino, a nie C. Jeśli nie znasz (jeszcze) OOP (Object Oriented Programming) lub C ++, może to trochę przyzwyczaić się i trochę czytanie.
Moją propozycją byłoby utworzenie klasy Program i utworzenie pojedynczej globalnej instancji tej klasy. Klasę należy uznać za plan dla obiektów.
Rozważ następujący przykładowy program:
class Program {
public:
Program();
void setup();
void loop();
private:
int myFirstSampleVariable;
int mySecondSampleVariable;
};
Program::Program() :
myFirstSampleVariable(0),
mySecondSampleVariable(0)
{
}
void Program::setup() {
// your setup code goes here
}
void Program::loop() {
// your loop code goes here
}
Program program; // your single global
void setup() {
program.setup();
}
void loop() {
program.loop();
}
Voilà, pozbyliśmy się prawie wszystkich globali. Funkcje, w których chcesz zacząć dodawać logikę aplikacji, to funkcje Program::setup()i Program::loop(). Funkcje te mają dostęp do zmiennych składowych specyficznych dla instancji, myFirstSampleVariablea mySecondSampleVariabletradycyjne setup()i loop()funkcje nie mają dostępu, ponieważ zmienne te zostały oznaczone jako prywatne. Ta koncepcja nazywa się enkapsulacją lub ukrywaniem danych.
Nauczenie cię OOP i / lub C ++ jest trochę poza zakresem odpowiedzi na to pytanie, więc zatrzymam się tutaj.
Podsumowując: globałów należy unikać i prawie zawsze można drastycznie zmniejszyć ich liczbę. Również podczas programowania dla Arduino.
Co najważniejsze, mam nadzieję, że moja odpowiedź będzie dla ciebie przydatna :)