Skocz do zawartości

Jak pisać biblioteki na Arduino?


Pomocna odpowiedź

11 minut temu, ethanak napisał:

 A tak w ogóle to po co tam zmienna pin?

No wlasnie takich rzeczy chcialem sie dowiedziec, np. ktore zmienne sa zbedne..😉 moglbys mi to odrobinke rozjasnic? czemu ta zienna jest zbedna?

(edytowany)
2 godziny temu, farmaceuta napisał:

czemu ta zienna jest zbedna?

Jeżeli użytkownik nie musi jej podawać / zmieniać to wyrzucasz ją do private/protected. Jeżeli ustawia ją tylko raz (w konstruktorze) to też. To takie najprostsze podejście.

Plus możesz się obejść bez tej zmiennej.

Edytowano przez H1M4W4R1
  • Pomogłeś! 1
17 minut temu, H1M4W4R1 napisał:

 Jeżeli ustawia ją tylko raz (w konstruktorze) to też. To takie najprostsze podejście.

Plus możesz się obejść bez tej zmiennej.

No wlasnie...sprawdzilem i bez tej zmiennej "pin" tez dziala normalnie...i tego nie moge wlasnie zrozumiec, czemu nie musze tworzyc tej zmiennej?...dobrze rozumiem ze nie musze miec tej zmiennej bo ona i tak powstanie w konstruktorze i po wykonaniu kodu zostanie zniszczona, a ja inicjuje tylko raz pin wiec nie jest mi dalej potrzebna ta zmienna...to jak w przypadku zwyklych funkcji z argumentami tak? czyli tylko lokalnie robie co mam robic tymi zmiennymi i po opuszczeniu one sa skasowane..

20 minut temu, farmaceuta napisał:

No wlasnie...sprawdzilem i bez tej zmiennej "pin" tez dziala normalnie...i tego nie moge wlasnie zrozumiec, czemu nie musze tworzyc tej zmiennej?

Ponieważ uint8_t masz zdefiniowane zarówno w konstruktorze jak i w klasie. Wtedy definicja wewnątrz konstruktora nadpisuje definicję, która jest w klasie, więc zmienna pin wewnątrz klasy jest zbędna.

  • Pomogłeś! 1

A sprawdź sobie, gdzie w programie odwołujesz się do tej zmiennej.

Owszam, masz argument metody która się tak sami nazywa. Ale nie zmienną/własność czy jak to tak nazwiesz.

A do odróżnienia czy "pin" to parametrczy zmienna służy magiczne słówko this.

  • Pomogłeś! 1
54 minuty temu, ethanak napisał:

A do odróżnienia czy "pin" to parametrczy zmienna służy magiczne słówko this.

Albo konsekwentne stosowanie jakiegoś standardu nazewnictwa.

@farmaceuta można się spotkać z zapisem, że zmiennym w klasach dodaje się przedrostek m_ (member) i wtedy czytając kod łatwo jest odróżnić członków klasy od argumentów czy zmiennych lokalnych. 

  • Pomogłeś! 1
(edytowany)
9 minut temu, ethanak napisał:

Ja zawsze lubiłem podkreślnik

Pewnego pięknego razu zdecydowaliśmy w firmie, że argumenty funkcji i zmienne lokalne nazywamy właśnie od _ i... do dzisiaj żałuję tej decyzji. Gdyby tyczyło się to tylko memberów to byłoby to na plus. Ale gdy mowa o argumentach i zamiennych lokalnych to po prostu dodaliśmy sobie pracy. Dlatego obecnie jestem za szkołą m_ i tylko do memberów a wszystko inne bez żadnych dodatków.

Edytowano przez Matthew11
  • Lubię! 1

Każdy ma... to co życie mu da...

Ja piszę jednoosobowo, więc konwencja, że w przypadku konfliktu argument funkcji jest z podkreślnikiem całkiem nieźle się sprawdza. Ale zgodzę się, że można inaczej.

  • 3 tygodnie później...

Witam...ciag dalszy...😉 mam takie dwa pytania...ale zaczne od jednego...powiedzmy ze chcialbym sie odwolywac do jakiejs funkcji z poziomu biblioteki ktora znajduje sie w glownym kodzie...cos  na zasadzie przerwan INT czy PCInt...czyli jako argument podaje nazwe funkcji ktora stworzylem w kodzie..wewnatrz biblioteki mam odpowiedni wektor przerwania ISR a w nim z kolei wywolanie tej funkcji...jak to zrobic najprosciej? Domyslam sie ze pewnie przez wskazniki, ale jak to ogarnac to nie mam pojecia...😕

(edytowany)

@farmaceuta Chodzi ci o przekazanie wskaźnika na funkcję, taki odpowiednik klasy anonimowej/interfejsu/handlera? Może ten wpis coś rozjaśni, od śródtytułu Twór klasopodobny.

Edytowano przez Gieneq
  • Pomogłeś! 1

Ale z czym dokładnie masz problem?

Ogólnie wskaźnik na funkcję wygląda tak:

typ_wyniku (* nazwa)(typy_argumentów)

Jeśli funkcja ma być wywoływana przez inną funkcję, nad którą nie masz kontroli - powinieneś zaimplementować jakiś mechanizm pozwalający na zapamiętanie przez bibliotekę tego wskaźnika. Najprostsze (chociaż niekoniecznie najlepsze) rozwiązanie to stworzenie jakiejś funkcji w bibliotece typy "init" czy "begin", której jednym z argumentów będzie właśnie Twoja funkcja, a wskaźnik będzie zapamiętany w jakiejś zmiennej statycznej.

 

  • Pomogłeś! 1
19 minut temu, farmaceuta napisał:

chcialbym sie odwolywac do jakiejs funkcji z poziomu biblioteki ktora znajduje sie w glownym kodzie

Rozumiem, że nie chcesz uzależnić biblioteki od funkcji w kodzie głównym, tylko przekazać tą funkcje z kodu głównego do biblioteki. Jeśli tak to rozwiązań jest w sumie dwa - pierwsze z użyciem wskaźników na funkcje (C style), drugie z wykorzystaniem std::function (modern C++ style). 

#include <functional>
#include <iostream>

class Test
{
public:
    Test(std::function<void(void)> callbackOne, void (*callbackTwo)()) : m_callbackOne{callbackOne}, m_callbackTwo{callbackTwo}
    {
    }

    void call()
    {
        m_callbackOne();
        m_callbackTwo();
    }

private:
    std::function<void(void)> m_callbackOne;
    void (*m_callbackTwo)();
};

auto functionOne = []()
{ std::cout << "Function One called!\n"; };

void functionTwo()
{
    std::cout << "Function Two called!\n";
}

int main()
{
    Test t{functionOne, functionTwo};

    t.call();
}

Do std::function można podać lambdę (to jest ten zapis [](){}), ale można też podać adres dowolnej funkcji, która pasuje pod względem sygnatury w tym wypadku funkcja która nic nie zwraca i nic nie przyjmuje. Więc mógłbym też zrobić:

Test t{functionTwo, functionTwo};
t.call();

Oczywiście jak chcesz, żeby te funkcje coś zwracały albo przyjmowały jakieś argumenty to zamiast void(*function)(void) możesz wstawić właśnie to co chcesz, i tak samo z lambdami (tylko trzeba się w nich orientować) ale dają więcej możliwości (i mogą generować więcej problemów).

  • Pomogłeś! 1
18 minut temu, ethanak napisał:

Ale z czym dokładnie masz problem?

Najczesciej??...to z glowa..😁haha a tak na serio..

 

19 minut temu, ethanak napisał:

 Najprostsze (chociaż niekoniecznie najlepsze) rozwiązanie to stworzenie jakiejś funkcji w bibliotece typy "init" czy "begin", której jednym z argumentów będzie właśnie Twoja funkcja, a wskaźnik będzie zapamiętany w jakiejś zmiennej statycznej.

 

Dokladnie o to mi chodzi, cos w stylu..

void funkcja() {
  /// wykonaj podczas przerwania
  }
void setup() {
  biblioteka.begin(funkcja);
  }
void loop() {
  }

 No a w bibliotece ma sie znajdowac obsluga przerwania ISR i to z tego miejsca mam "przeskoczyc" do funkcja() czyli..

 // cpp
ISR (vect_) {
  funkcja();
  
}

No jakos tak...

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...