Skocz do zawartości

Przenoszenie wartości z tablicy do jednej zmiennej


Pomocna odpowiedź

Witam.

 

Arduino na pinach czyta stan czy jest HIGH czy LOW, wygląda to tak:

  int stateVIN1 = digitalRead(VIN);
  int stateGNDIN1 = digitalRead(GNDIN);
  int stateCKV121 = digitalRead(CKV12);
  int stateCKGND1 = digitalRead(CKGND);
  int stateCK1 = digitalRead(CK);
  int stateCANV121 = digitalRead(CANV12);
  int stateCANGND1 = digitalRead(CANGND);
  int stateCAN_H1 = digitalRead(CAN_H);
  int stateCAN_L1 = digitalRead(CAN_L);

wyniki zapisuję do tablicy w ten sposób:

int wynik[] = {stateVIN1, stateGNDIN1, stateCKV121, stateCKGND1, stateCK1, stateCANV121, stateCANGND1, stateCAN_H1, stateCAN_L1};

ale chciał bym przenieść te wszystkie liczby do jednej zmiennej, żeby później porównać tą całą wartość z inną.

Ogólnie robię sobie taki tester który ma sprawdzać kabelki więc w tym momencie tylko wartości stateVIN1,  stateCKV121, stateCANV121 powinny mieć stan wysoki, czyli tablica wygląda tak: int wynik[] = {1, 0, 1, 0, 0, 1, 0, 0, 0,} i muszę tą tablice porównać ze wzorem który mam zapisany w kodzie programu, mniej więcej tak:

//    if (wynik[tab]=101001000)
//    {
//      lcd.setCursor(0,14);
//      lcd.print("OK");
//    }
//    else
//    {
//      lcd.setCursor(0,14);
//      lcd.print("ER");      

Będę wdzięczny za wszelką pomoc, lub podsunięcie lepszej koncepcji 🙂

Link to post
Share on other sites

Najprościej chyba byłoby zrobić tablicę przechowującą wzorzec i porównać ją z otrzymaną tablicą

int result[] {...}//Tu wartości z pinów
int expected[] {...}//Wartości oczekiwane
bool AreEqual =true;//Wyznacznik czy obie są równe, zakładamy że tak
for (int i =0;i<_array_length;i++){//Iterujemy przez wszystkie elementy
  if (result[i]!=expected[i]) //Jeżeli jakieś są różne
  {
    AreEqual=false; // Elementy różne więc nie są równe
  	break; //Nie ma potrzeby dalej sprawdzać
  }
}
if (AreEqual)
  //To co chcesz zrobić dla tych samych
else
  //To co chcesz zrobić dla różnych

Można (a nawet wypadałoby) by zrobić z tego funkcję.

  • Lubię! 1
Link to post
Share on other sites
31 minut temu, Aiden_Pearce napisał:

Można (a nawet wypadałoby) by zrobić z tego funkcję.

Ale przecież taka funkcja już istnieje, memcmp się nazywa...

  • Pomogłeś! 1
Link to post
Share on other sites

Dzięki Serdeczne za pomoc 😄. memcmp() działa idealnie.

Tak wygląda część programu:

  int result[] = {stateVIN1, stateGNDIN1, stateCKV121, stateCKGND1, stateCK1, stateCANV121, stateCANGND1, stateCAN_H1, stateCAN_L1};
  int expected[] {1, 0, 1, 0, 0, 1, 0, 0, 0};
  int test = memcmp(result, expected, 9);
  
  
  for (int i = 0; i < 9; i++)
  {
    lcd.setCursor(i,1);
    lcd.print(result[i]);
  }

  for (;;)
  {
    lcd.setCursor(0,0);
    lcd.print("+12V:");
    
    lcd.setCursor(14,0);
    lcd.print(test);   
  }

 

Jak by się komuś nie chciało dalej szukać:

Funkcja zwraca wartość 1 jeśli trafi na wartość większą w tablicy pierwszej, wartość 0 gdy wartości w obu tablicach są takie same i wartość -1 gdy trafi na wartość większa w tablicy drugiej 🙂

W nawiasie podaje się trzy parametry: pierwszą tablicę, drugą tablicę i liczbę elementów w tablicach do porównania 🙂

  • Lubię! 1
Link to post
Share on other sites
2 minuty temu, kacperos.89 napisał:

memcmp() działa idealnie

Śmiem wątpić.

Masz w kodzie:

memcmp(result, expected,9);

Co będzie, jeśli różnić się będą elementy o indeksie np. 6?

3 minuty temu, kacperos.89 napisał:

W nawiasie podaje się trzy parametry: pierwszą tablicę, drugą tablicę i liczbę elementów w tablicach do porównania

Nieprawda.

Przeczytaj dokładnie podlinkowany fragment dokumentacji i powiedz czym się różnią takie zapisy i który z nich jest prawidłowy:
 

const int ILOSC = 9;

int a[ILOSC], b[ILOSC];

int test1 = memcmp(a,b,ILOSC);
int test2 = memcmp(a,b,2 * ILOSC);
int test3 = memcmp(a,b,sizeof(a));
int test4 = memcmp(a,b,sizeof(int) * ILOSC);

Którego powinieneś użyć?

  • Lubię! 2
Link to post
Share on other sites

Wiem, że to tylko część programu ale mnie coś niepokoi:

for (;;)
  {
    lcd.setCursor(0,0);
    lcd.print("+12V:");
    
    lcd.setCursor(14,0);
    lcd.print(test);   
  }

Dlaczego jest to nieskończona pętla?
I co ważniejsze, czy Ty wiesz co ona wyświetla?

Link to post
Share on other sites

@Aiden_Pearce

Cytat

Dlaczego jest to nieskończona pętla?

Nieskończona pętla bo nieskończony program. Będę tu dopisywał, może jakiegoś if-else sprawdzającego wartość guzika żeby przeskoczyć programem dalej.

Cytat

I co ważniejsze, czy Ty wiesz co ona wyświetla?

Na wyświetlaczu widzę chyba to co chcę? Zwykły wyświetlacz 16x2 z modułem do komunikacji po I2C. Lewa góra wyświetlacza to tekst "+12V:" a z prawej strony (14 znak od lewej) wyświetlam wynik funkcji memcmp() i wyświetla wartość albo 1 albo 0 albo -1.

1610910419040.thumb.jpg.911839b2563adbe0236c7e212a5c198c.jpg

@ethanak

Z tym, że faktycznie za bardzo się pośpieszyłem z moim "tłumaczeniem" jak to działa, bo źle działa. Faktycznie do 5 wartości w tabeli porównuje prawidłowo, a od 6 wartości dalej funkcja nie widzi różnicy.

Pobawiłem się trochę tymi sizeof() i powinienem użyć: int test3 = memcmp(a,b,sizeof(a)); a to dla tego, że sam określa ilość bajtów tablicy. Moim błędem było założenie, że jeden znak typu int zajmuje jeden bajt, a tak nie jest. Zmienne int zajmują 2 bajty, więc licząc ręcznie powinienem wpisać trzecią wartość 18.

Link to post
Share on other sites
1 minutę temu, kacperos.89 napisał:

Na wyświetlaczu widzę chyba to co chcę? Zwykły wyświetlacz 16x2 z modułem do komunikacji po I2C. Lewa góra wyświetlacza to tekst "+12V:" a z prawej strony (14 znak od lewej) wyświetlam wynik funkcji memcmp() i wyświetla wartość albo 1 albo 0 albo -1.

Okej. To w porządku. Wyglądało to tak trochę jakbyś chciał ciągle sprawdzać czy tablice są równe. Stąd pytanie.

Link to post
Share on other sites
22 minuty temu, kacperos.89 napisał:

Pobawiłem się trochę tymi sizeof() i powinienem użyć: int test3 = memcmp(a,b,sizeof(a));

Bardzo dobrze, ale...

22 minuty temu, kacperos.89 napisał:

Zmienne int zajmują 2 bajty

A tu można się naciąć. Owszem, w AVR-ach kompilator jest ustawiony tak, że zmienne int są 16-bitowe (chociaż można wymusić 8-bitowy int), ale już np. w ESP czy ARM-ach int jest standardowo 32-bitowy. Co więcej - niektóre kompilatory pozwalają na przełączanie inta z 32 na 16 bitów. Tak że nie wolno polegać na tych wartościach; jeśli jest konieczne użycie zmiennej o konkretnej wielkości (w znaczeniu ilości bitów), należy użyć typów int16_t (16 bitów) czy int32_t (32 bity).

Sam się kiedyś na to nabrałem przenosząc jakiś program z Amigi (kompilator bodajże Manx, 32-bitowy int) na 286 i Turbo C (16-bitowy int) 🙂

  • Lubię! 1
Link to post
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

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.