Arduino Uno nie jest w stanie obsłużyć dwuwymiarowej tablicy

Teraz kod, który piszę w Arduino (przy użyciu Arduino), używa wielu dwuwymiarowych tablic. Teraz, kiedy Wydrukowuję coś używając Serial Monitora, drukuje to poprawnie, ale kiedy deklaruję i inicjalizuję dwuwymiarową tablicę, to jej nie drukuje.

Kod:

 void setup() { Serial.begin(9600); int image_width = 56; int image_height = 96; int image_result[image_width][image_height]; for (int i=0; i<image_height; i++) { for (int j=0; j<image_width; j++) { image_result[j][i] = 5; } } Serial.print("code works"); }  

Teraz w tym przypadku” code works „nie jest drukowane, ale kiedy usuwam deklarację tablicy i działa kod inicjalizacji. W czym problem?

Czy dwuwymiarowe tablice działają inaczej w Arduino, czy jest to problem z przestrzenią?

Komentarze

  • Nawet jednowymiarowa tablica 5376 bajtów na procesorze z 2048 bajtów zawiedzie.
  • Miałem na myśli 10752 bajtów. Przeoczyłem, że każdy element tablicy ma 2 bajty. Pamiętaj, że nie masz ' nawet wszystkich tych 2048 bajtów. Same bufory transmisji i odbioru szeregowego zajmują 128 bajtów.
  • Cóż, jeśli podłączę samochód micro-SD, czy jest jakaś metoda zadeklarowania tablicy w tej pamięci?
  • Możesz podłączyć Karta SD i zapisuj dane w swoim ' treści. Możesz jednak ' t ” zadeklarować tablicę w pamięci „. Jaka jest twoja aplikacja tutaj? Arduino z 2 KB pamięci RAM nie jest ' t najlepszą rzeczą do przetwarzania obrazu.
  • Muszę odczytać mały plik BMP w tablicy int w Arduino i trzeba go przetworzyć. Rozmiar pliku to 56 na 96 pikseli.

Odpowiedź

Tablice 2D działają dobrze na arduino, ale ty szybko zabraknie miejsca.

Uno ma 2 kilobajty pamięci RAM; twoja tablica ma 56 * 96 = 5376 2-bajtowych elementów.

Domyślam się, że nad jakąś krytyczną wartością pamięci wpisujesz 5 w pewnym momencie powodując awarię programu.

Komentarze

  • Nie tylko w pamięci, ale prawdopodobnie także we wszystkich rejestrach I / O.
  • 16-bitowe adresowanie, z SRAM zaczynającym się od 256. Dzięki temu ' ma 65279 bajtów przestrzeni adresowej. Więc wygrałeś ', żeby to osiągnąć. Ponadto ' jestem prawie pewien, że istnieje jakiś rodzaj ochrony, który temu zapobiega.
  • Nie ma żadnej ochrony. Rejestry procesora są mapowane w pamięci począwszy od adresu 0, następnie rejestry I / O od adresu 32, a następnie statycznie przydzielona pamięć RAM zaczyna się od adresu 256.

Odpowiedź

Próbujesz użyć więcej pamięci niż jest dostępna: 96 * 56 * 2 = 10,752 KB. Niewiele, co MCU może zrobić, gdy tak się stanie.

Jeśli zajrzysz do arkusza danych , zobaczysz, że Twój mikrokontroler (ATmega328p) ma tylko 2 KB pamięci RAM.

Wydaje mi się, że należy zadać sobie pytanie, czy naprawdę potrzebujesz tak dużej tablicy. Możesz rozważyć zakup zewnętrznego chipa flash lub osłony karty SD. Jeśli potrzebujesz go tylko do celów tylko do odczytu (np. table), możesz użyć części swojej pamięci programu flash (masz 32 KB).

Komentarze

  • ' m używam arkusza karty SD, ale ' m wczytuję dane do tablicy zadeklarowanej w ten sposób. Jak mógłbym korzystać z pamięci karty SD.
  • Zwykle nie ' t zazwyczaj nie musisz zajmować się wszystkimi 5376 elementami tablicy w jednej chwili. podzielenie obrazu na mniejsze fragmenty do przetworzenia. W zależności od rodzaju przetwarzania możesz potrzebować różnych sprytnych metod optymalizacji procesu . 😉
  • Czy można wielokrotnie zapisywać dane do pamięci flash. Co masz na myśli mówiąc „tylko do odczytu”? Jak jeden raz zapisać na nim dane. Na przykład chcę zapisać dane obrazu w pamięci flash. Jak będę mógł to zrobić?
  • Mam na myśli pamięć flash twojego programu. AFAIK, do programu flash można zapisywać tylko podczas programowania. Po uruchomieniu MCU program flash jest używany jako pamięć tylko do odczytu (abyśmy ' nie zepsuli programu, gdy ' s działa.) Ponieważ chcesz zapisać swoje dane, program flash nie jest odpowiedni.
  • Czy naprawdę potrzebujesz przetworzyć cały obraz za jednym razem? Jak już ' wspomniałem wcześniej, możesz podzielić obraz na mniejsze bloki, powiedzmy, że fragment [8] [8] będzie wygodnym rozmiarem dla Arduino połknąć i działa dobrze, nawet jeśli używasz filtrów splotowych. (Powiedziawszy to, muszę podkreślić, że Arduino Uno źle nadaje się do jakiejkolwiek poważnej aplikacji do przetwarzania obrazu.)

Odpowiedź

Rzeczywiście, jest to problem z dostępną pamięcią RAM.Jeśli nie potrzebujesz 8 bitów na jedną część danych (jeśli na przykład być może chcesz obniżyć jakość obrazu), rozważ kompaktowanie danych w taki sposób, aby uzyskać wiele danych na bit. Na przykład, mogą działać wartości szesnastkowe lub BCD (binarnie zakodowane miejsca po przecinku), w zależności od rozmiaru każdego elementu danych.

Komentarze

  • OP chce odczytać plik BMP do pamięci, więc wątpię, aby można go było zamienić na BCD bardzo pożytecznie.
  • To ' to dobry punkt. Być może ' chce znacznie obniżyć jakość swojego obrazu? Tak czy inaczej, dodatkowe miejsce byłoby rozsądne.

Odpowiedź

Jak zauważyli inni, twoja tablica jest większa niż dostępnej pamięci RAM w Twoim Arduino. Inni wspominali o pamięci Flash, która może być dla Ciebie rozwiązaniem. Twoje Arduino ma 32 KB pamięci, która może pomieścić twoją tablicę. Więcej informacji na temat pamięci Flash można znaleźć w następującym dokumencie. Pamiętaj, że Flash i EEPROM mają ograniczoną liczbę cykli zapisu, zanim staną się zawodne.

Ukryte moce – przechowywanie danych we Flash i EEPROM

Odpowiedź

Jeśli macierz jest w większości pusta lub mimo wszystko zawiera wartości, które można obliczyć programowo, rzadkie tablice . Wymaga alokacji pamięci i przeskoku, więc czas dostępu do poszczególnych elementów nie jest deterministyczny, ale możesz obliczyć najgorszy scenariusz.

Odpowiedź

Oto, czym karmiłem mój Uno:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96 void setup() { Serial.begin(9600); int i, j; int image_result[IMAGEWIDTH][IMAGEHEIGHT]; for (i = 0; i < IMAGEWIDTH; i++) { Serial.print("\nIMAGEWIDTH "); Serial.print(i + 1); Serial.println(":"); for (j = 0; j < IMAGEHEIGHT; j++) { image_result[i][j] = i + j; Serial.print("image_result["); Serial.print(i + 1); Serial.print("]["); Serial.print(j + 1); Serial.print("]: "); Serial.println(image_result[i][j]); } } Serial.println(F("\nDone!")); } void loop() { }  

To przejdzie przez całą tablicę, podczas drukowania postępu przez Serial, który następnie wyświetli „Gotowe!” raz to jest. Proponuję zmienić:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96  

Na mniejsze wartości, chyba że masz kilka dobrych minut w zasięgu ręki.

Komentarze

  • To wcale nie rozwiąże jego problemu. Nie jest to ' t czas, jest to rozmiar tablicy. 56 * 96 * 2 (int to dwa bajty) wykorzystuje 10752 bajty. Twój Uno ma 2048 bajtów. Problemem nie jest czas, ale przechowywanie.
  • Nick miał rację, to nie ' nie rozwiązało mojego problemu. W każdym razie dziękuję za próbę.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *