Skocz do zawartości

Tablice w Arduino – #1 – szybki start


Gieneq

Pomocna odpowiedź

1 godzinę temu, tenNowy napisał:

Od D4 do D36 mam przekaźniki od A0 do A15 i od D37 do D52 włączniki ot to co chce osiągnąć za pomocą pętli

I teraz wystarczyłoby sobie uświadomić, że aliasy od A0 do A15 istnieją po to, by ułatwić zapis kodu przy wykorzystania analogowych możliwości danych pinów czy np. zmianę wariantu płytki. A tak naprawdę Twoje włączniki podłączone są do pinów od 37 do 69, z pominięciem 53.

Także wystarczy:

#define BUTTON(number) \
	({ int _n = (number); \
	  _n < 0 || _n >= 32 ? -1 : (_n < 16 ? 37 + _n : 54 - 16 + _n); })

Lub, jeżeli wolisz życie na krawędzi:

#define BUTTON(n) (n < 0 || n >= 32 ? -1 : (n < 16 ? 37 + n : 54 - 16 + n))

Biblioteki wbudowane Arduino stosują drugi styl, ale to wybucha, jeżeli ktoś użyje tego w formie BUTTON(zmienna++) czy z innymi wyrażeniami. Kompilator przy włączonej jakiejkolwiek optymalizacji i tak zamieni użycie wersji pierwszej na jedną liczbę (a chyba Arduino IDE domyślnie używa -Os). 

Ach, no i zmieniłem logikę numeracji Twoich przycisków, którą sobie ustawiłeś w głowie, bo mam jednak podejrzenie, że wynika ona właśnie z nierozumienia numeracji pinów. Ja bym wolał podłączyć po kolei. Ale jak się uprzesz, to łatwo możesz zmienić te makra pod założoną kolejność. Albo życie sobie bardziej ułatwić i użyć też pinu 53, o ile nie ma on jakichś nieznanych mi wad i wtedy może używać po prostu:

const byte BUTTONS_START = 53;
const byte BUTTONS_COUNT = 32;
  
...
  
for (int i = 0; i < BUTTONS_COUNT; ++i)
  cośtam(BUTTONS_START + i);

Można też po prostu zrobić funkcję int button(int n). Kompilator też taką potrafi zoptymalizować do pojedynczej stałej. Więc nie trzeba męczyć się z preprocesorem.

Edytowano przez trainee
  • Lubię! 2
Link do komentarza
Share on other sites

Kolega wyżej pokazał sposób, jednak od siebie mogę powiedzieć, że trzeba być doświadczoną osobą, by w ogóle zrozumieć co ten kod robi.

Jeśli chcesz wpisać po prostu Piny do tablicy to nie musisz przecież wpisywać nazw. Te nazwy jak Trainee powiedział służa tylko programiście by wiedział, który pin jest który. Pod spodem A0-A15 to zwykłe cyferki wstawiane przy kopilacji w to miejsce gdzie piszesz np A0: 


image.thumb.png.e4ade68851a8c4699412ca36f264182a.png

Możesz sobie wpisać do tablicy Włączniki[32] po prostu pętla numery od 37 do 52 a później od od 54 do 69 jeśli to ma być jak najprościej. 

edit: ewentualnie na chama gdybyś chciał wyłaczyć 32-52 😛

for(uint8_t i = 32; i < 53; i++)
{
  digitalWrite(i, LOW);
}

 

Edytowano przez Dantey
Link do komentarza
Share on other sites

Co do mojej wzmianki o optymalizacji, przykład w Compiler Explorer. Dodałem jeszcze static do funkcji, dzięki czemu sama funkcja nie jest generowana. To co wystarczy wiedzieć, to że w linii 7 assemblera jest ldi r24,lo8(42) i ta linijka będzie się zmieniać przy zmianie argumentu funkcji button(). Podstawiony jest wynik wyliczony na etapie kompilacji.

Mówiąc prościej: używanie preprocesora jest trudne, ma pułapki. A kompilator radzi sobie równie dobrze, jak nie lepiej, sam.

Edytowano przez trainee
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

A0 to 54, A15 to 69. Jeśli używasz standardowego IDE do arduino to zainstaluj sobie Visual studio Code z Platform IO. W samym VSC pisanie to zupełnie inna liga, z racji autouzupełniania i pokazywania co jest co. Najedziesz sobie na nazwe A0 i pokaże Ci co w ogóle to znaczy, jak ten mój screen wyżej 😉 

Edytowano przez Dantey
Link do komentarza
Share on other sites

@tenNowy, a na deser zostawię Ci taką myśl: 32 przyciski mógłbyś też obsłużyć używając 12 pinów zamiast 32. Ot tak tylko, by Cię ta myśl trochę mobilizowała do dalszych przemyśleń, na przyszłość.

Edytowano przez trainee
Link do komentarza
Share on other sites

3 godziny temu, trainee napisał:

Lub, jeżeli wolisz życie na krawędzi:

😅 

Fajna dyskusja się rozwinęła, cieszę się 🙂 

Link do komentarza
Share on other sites

Pokusiłbym się stwierdzeniem, że w idealnych warunkach obsłużyłbym je tylko 1 pinem z pomocą rezystorów czy o to Ci chodzi? Jednak trzeba wziąć pod uwagę długości żył i spadki napięć. Wole jednak pewne rozwiązanie 1 do 1 co nie znaczy, że to o czym mówisz by nie działało, swoją drogą masz rację mało ambitnie do tego podszedłem.

Edytowano przez tenNowy
Link do komentarza
Share on other sites

Aha o krzyżowanie Ci chodzi ja myślałem o dzielniku napięcia bo Arduino jest w stanie mierzyć napięcie w zakresie od 0-5v z dokładnością bodajże 10bitów więc obsłuży wszystkie przyciski jednym pinem analogowym.

Link do komentarza
Share on other sites

36 minut temu, tenNowy napisał:

Aha o krzyżowanie Ci chodzi ja myślałem o dzielniku napięcia bo Arduino jest w stanie mierzyć napięcie w zakresie od 0-5v z dokładnością bodajże 10bitów więc obsłuży wszystkie przyciski jednym pinem analogowym.

Tak, chodzi mi o sensowną metodę, na bazie której skonstruowana jest m.in. klawiatura Twojego komputera. Nie o metodę kreatywno-szaloną, której nikt pewnie nigdzie nie użył, bo tu same problemy na każdym kroku by były.

Edytowano przez trainee
Link do komentarza
Share on other sites

witam

w kwestii tablic mam jedno pytanie, bo nie doczytałem się tego i nie wiem czy to wogóle jest możliwe - a mianowicie problem wygląda tak:

mam dwie tablice:

image.png.97f60e0c908884d898eca042b0103444.png

w związku z tym pytanie, czy znając wartość tablicy numer - np. 65 co daje nam numer [2] który jest odpowiednikiem tablicy maszyna [2] mogę zmienić jej wartość np. z 2 na 10  ... nie mam zielonego pojecia jak to zapisać w postaci funcji by zadziałało ... z góry dziękuję za pomoc 

Link do komentarza
Share on other sites

8 minut temu, merinum napisał:

w związku z tym pytanie, czy znając wartość tablicy numer - np. 65 co daje nam numer [2] który jest odpowiednikiem tablicy maszyna [2] mogę zmienić jej wartość np. z 2 na 10  ... nie mam zielonego pojecia jak to zapisać w postaci funcji by zadziałało ... z góry dziękuję za pomoc 

int numer[] = {63, 64, 65};
int maszyna[] = {1, 2, 2};

void update_maszyna(int numerVal, int newVal)
{
  // Tymczasowa zmienna określająca indeks w tablicy numer
  int index = 0;
  
  // Dla każdej wartości w tablicy numer
  for(int i = 0; i < sizeof(numer)/sizeof(numer[0]); i++)
  {
    // Jeżeli wartość jest identyczna jak oczekiwana zakończ iterację z obecną wartością zmiennej index
	if (numer[i] == numerVal) break;
    
    // W przyciwnym razie przejdź do następnej iteracji, bądź zakończ pętlę w przypadku zakończenia tablicy
    index++;
  }
  
  // Sprawdź czy indeks nie wykracza poza zakres, jeżeli tak zakończ funkcję
  if(index >= sizeof(maszyna)/sizeof(maszyna[0])) return;
  
  // Zaktualizuj wartość 
  maszyna[index] = newVal;
}

Jakoś tak, pisane na kolanie 😉 Musisz przeiterować przez tablicę numer szukając wartości i zwiększając wartość index. Bez zmiennej index też by się obyło, ale wolę taki system zapisu.

Potem sprawdzasz czy tablica maszyna zawiera dany indeks i aktualizujesz jego wartość 😉 

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.