Assert4a – assert dla Arduino IDE – szybkie libki

Ta biblioteka jest zajefajna i powstała dziś rano.

Pisanie programów to fajne zajęcie. Jednak od czasu do czasu zdarzają się chwile, że program nie chce działać tak jak tego oczekuję. Im dłużej to trwa tym bardziej projekt demotywuje.

Jednym z ciekawszych podejść do tego problemu jest pisanie programów opartych na testach. Najpierw pisze się program, który sprawdzi czy nasz program lub jego elementy działają dobrze. Potem pisze się właściwy program tak długo, aż ten testujący zakończy wszystkie testy jako prawidłowe.

W takich chwilach zwykle uruchamia się profesjonalne narzędzia typu debugger, którym analizuje działanie programu krok po kroku i sprawdzam jakie dane znajdują się w zmiennych. Jak znajdują się złe to zastawiam się czemu ;-).

Niestety w Arduino IDE nie ma debuggera. Trzeba sobie radzić amatorsko.
Najbardziej prymitywnym sposobem jest świecenie wbudowaną diodą L13, gdy następuje jakieś ważne/dziwne wydarzenie w programie.

int zmienna;

void setup() {
  pinMode(13, OUTPUT);

}

void loop() {
  zmienna++;
  if (zmienna < 0)
  {
    digitalWrite(13, HIGH);
  }
}

Tu program sprawdza czy zmienna jest mniejsza niż zero. Jeśli tak to świeci lampką L na płytce drukowanej Arduino.

Innym sposobem jest testowanie programu przez wysyłanie komunikatów do Monitora Portu Szeregowego w Arduino.

int zmienna;

void setup() {
  while (!Serial);
  Serial.begin(9600);
}

void loop() {
  zmienna++;
  if (zmienna < 0)
  {
    Serial.println(zmienna);
    delay(1000);
  }
}

Gdy zmienna jest poniżej zera program wyśle jej wartość do komputera.

Fachowo takie sprawdzanie programu nazywane jest >>debug za pomocą print “dupa”<< 😉 i jest często powodem drwin profesjonalnych programistów.

Takie testowanie programu może być kłopotliwe przy bardziej rozbudowanych kodach. Upychasz coraz więcej print w różnych zakamarkach programu i na końcu Monitor Portu Szeregowego zaczyna wyświetlać tyle komunikatów, że przypomina to monitorowanie z filmu Matrix.

W wielu językach programowania wymyślono już ciekawe rozwiązania pomagające w takim testowaniu programu. Najpopularniejsze nazywa się “assert” [twierdzić/dowodzić czegoś].

Jego użycie w programie wygląda jak użycie normalnej funkcji. Z tym, że zamiast argumentu podajesz warunek. Warunek to określenie przy jakich parametrach program będzie działał prawidłowo. W przypadku naszego programu zapiszę to jako:

assert(zmienna >= 0);

Ponieważ zakładam twierdzenie, że funkcja będzie działała dobrze tylko wtedy, kiedy zmienna będzie większa lub równa zeru.

Jeśli wydarzy się coś w programie i warunek nie będzie spełniony (zmienna będzie miała wartość mniejszą niż zero) to dostaniemy komunikat informujący w którym pliku programu, w jakiej linii i jakiej funkcji warunek nie został spełniony. Program zostanie dla bezpieczeństwa zatrzymany.
Taka prosta funkcja funkcja, a zwraca wszystkie niezbędne informacje.

Standardowa biblioteka assert.h z języka C++ nie działa dobrze w Arduino IDE. Postanowiłem napisać bibliotekę poprawiającą jej działanie. Nazwałem ją Assert4a.h.

#include <Assert4a.h>

int zmienna;

void setup() {
  while (!Serial);
  Serial.begin(9600);
}

void loop() {
  zmienna++;
  assert(zmienna >= 0);
}

W funkcji loop za pomocą assert, zakładam że program będzie dobrze działał, jeśli zmienna będzie miała wartość większą lub równą 0.
Gdy program nie spełni tego warunku, w Monitorze Portu Szeregowego otrzymam komunikat:

Assertion: ‘zmienna >= 0’ failed
   File ‘sketch_dec09a.ino’, at line 12, in function ‘loop’

Mówi on, że twierdzenie “zmienna >= 0” okazało się nieprawdziwe. Nieprawidłowość wystąpiła w pliku programu “sketch_dec09a.ino”, w linii 12, w funkcji “loop”.

Możesz obstawić dużą część programu takimi twierdzeniami i jak coś złego się stanie to będziesz miał informację gdzie i dlaczego.

Gdy przetestujesz już cały program nie musisz usuwać assert-ów żeby je wyłączyć. Wystarczy, że nad include z biblioteką napiszesz #define NDEBUG

#define NDEBUG
#include <Assert4a.h>

int zmienna;

void setup() {
  while (!Serial);
  Serial.begin(9600);
}

void loop() {
  zmienna++;
  assert(zmienna > 0);
}

Gdy zajdzie potrzeba ponownego testowania, usuniesz define i bedziesz mógł dostawać komunikaty o błędnym działaniu.

By zainstalować bibliotekę, wystarczy pobrać plik zip, a potem w Arduino IDE wybrać menu Szkic -> Importuj bibliotekę… -> Dodaj bibliotekę…

PS. Zadanie domowe z gwiazdką – kto wytłumaczy w komentarzach czemu w pierwszym programie lampka L13 zaświeciła się?

sprae

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.