Skocz do zawartości

Określenie rozmiaru tablic globalnych w trakcie kompilacji


farmaceuta

Pomocna odpowiedź

7 godzin temu, Elvis napisał:

ale jeśli to kod dla Arduino i pisany w C++ to może warto w tym języku go napisać zamiast na sile w C?

Może i warto ale najpierw trzeba umieć 😜 no a słowo extern? nie do końca rozumiem co ono robi i być może błędnie rozumiem że może mi pomóc ..🤔

Link do komentarza
Share on other sites

@farmaceuta Pisanie biblioteki w C nie jest niczym złym, ale warto podjąć decyzję co się wybiera: C czy C++. W przypadku Arduino większość bibliotek jest chyba pisana w C++, chociaż to o niczym nie świadczy. Extern na razie nie ma znaczenia, ale już używanie calloc zamiast new może mieć. Poza tym użycie C++ pozwala na wykorzystanie dodatkowych możliwości tego języka i przykładowo zastąpienie #define przez szablon, albo użycie constexpr zamiast const int.

Natomiast co do kodu, który pokazałeś w tym wątku, to moim zdaniem mógłbyś go mocno uprościć przez rozdzielenie biblioteki dla jednego pinu oraz kodu obsługującego grupę pinów. Bardzo dobrym krokiem w tym kierunku była propozycja kolegi @ethanak czyli definicja struktury PharmaPin opisującej jeden pin. W przypadku C++ można byłoby dodać do niej metody, a całość napisać bez jakiegokolwiek calloc czy innej alokacji.

Przykładowo masz kod:

void updat() {

  for (int i = 0; i < ilosc_pin; i++) {

    if (digitalRead(pin[i]) == pin_LH[i]) {
      if (stan[i] == 0) {
        last[i] = millis();
        stan[i] = 1;
      }
      if (millis() - last[i] > interval[i] && stan[i] == 1) {
        pin_stan[i] = 1;
        stan[i] = 2;

      } else {
        pin_stan[i] = 0;
      }
    } else {
      stan[i] = 0;
      pin_stan[i] = 0;
   
    }

  }
}

W tej funkcji masz pomieszane 2 rzeczy. Najpierw jest iteracja po elementach tablicy czyli:

void updat() {

  for (int i = 0; i < ilosc_pin; i++) {
    ...
  }
}

Dopiero później masz kod, który dotyczy już i-tego pinu.

Kod dla jednego pinu były prostszy, przykładowo gdyby klasa/struktura PharmaPin miała metodę updat(), mogłoby to być coś w rodzaju:

void PharmaPin::updat() {
    if (digitalRead(pin) == pin_LH) {
      if (stan == 0) {
        last = millis();
        stan = 1;
      }
      if (millis() - last > interval && stan == 1) {
        pin_stan = 1;
        stan = 2;

      } else {
        pin_stan = 0;
      }
    } else {
      stan = 0;
      pin_stan = 0;   
    }
}

Przy takim podejsciu, klasa PharmaPin zajmuje się tylko jednym pinem, natomiast zupełnie pomija alokację pamięci oraz pozostałe piny.

Można jej użyć dowolnie, nawet pisząc po prostu:

PharmaPin pin_up(UP, INPUT_PULLUP, LOW, 30);
PharmaPin pin_down(DOWN, INPUT_PULLUP, LOW, 30);

...

pin_up.updat();
pin_down.updat();

Natomiast jeśli bardzo chciałbyś mieć tablicę obiektów PharmaPin, to jak najbardziej - nawet zdefiniować nową klasę, np. PharmaPinGroup i w niej już według uznania trzymać tablice, dynamiczne alokacje oraz wszystkie iteratory po obiektach.

Edytowano przez Elvis
  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Iteracje w for są chyba ok, bo najpierw sprawdzam warunek, jeśli prawdziwy to wykonuje i dopiero wtedy następuje inkrementacja... Właśnie chciałem uniknąć wywołań typu.. 

updat.1
  updat.2
  itp

zminimalizować dodatkowe linie w kodzie głównym (tylko pin_setup jest powielany) generalnie już wywaliłem .updat() i zostało samo pres() sprawdzane wtedy kiedy trzeba...to na wypadek gdybym siedział dłuższy czas w jakimś while i nie aktualizował .updat()...co do reszty @Elvis to żeby zrobić tak jak mówisz to cza umić😜 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Wtrące swoje 3 grosze może jeśli chodzi o coś takiego jak Pin.

Ja u siebie robiąc osługe Pinów albo przycisków zrobiłem sobie Class z Enumem STATE_T. Prosta rzecz ale dało mi satysfakcje zrobienie tego:

class Button
{
  // methods
  //...........
  // variables
  uint8_t ReadPin;
  uint16_t DebbounceTime;
  unsigned long LastTick;
}


Metoda w danej klasie/strukturze która sprawdza mi co pętle stan Pinu. W PinIdle() jest sprawdzenie czy stan sie zmienił, jak tak to zmienia State na DEBBOUNCE i przy drugim obiegu pętli wchodze już w PinDebbounce(). 

void Button::PinTask()
{
  switch (this->State)
  {
  case IDLE:
    PinIdle();		break;
  case DEBBOUNCE:
    PinDebbounce();	break;
  case ACTIVE:
    PinIsActive();	break;
  default:		break;
  }
}

Program później wygląda tak:

void setup()
{
}
 
void loop()
{
  Button1.PinTask();
  Button2.PinTask();
  //itd
}

Wiadomo, że wadą tego rozwiązania jest to, że ponowne sprawdzenie stanu jest przy drugim obiegu pętli i jesli po drodze jest dużo kodu, to będzie to się srednio sprawdzać. Narazie testowałem z prostym układem sterowannia Osiami X Y Z w połączeniu z silniczkami i działa fajnie. Wszystko dzieje się wewnątrz funkcji. Wiadomo, że obsługa pinu Read/Write nie jest jakimś RocketScience ale robiąc sobie coś takiego ja obecnie tylko kopiuje biblioteke z Pinem i w konstruktorze mam setup. 

Button(const uint8_t &ReadPin, const uint8_t &WritePin);

Button Somebutton(11, 12);

W ten sposób masz "czym odczytujesz" i gdzie "ustawiasz". Narazie u mnie się sprawdza i według mnie jest fajniej czytelne niż kolejne piętrowe ify 😄 

Edytowano przez Dantey
  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.