Arduino Uno není schopen zpracovat 2-dimenzionální pole

Nyní kód, který píšu v Arduinu (pomocí Arduina), používá více 2-dimenzionálních polí. Nyní, když Vytisknu něco pomocí Serial Monitoru, vytiskne to správně, ale když deklaruji a inicializuji 2-dimentionální pole, nevytiskne to.

Kód:

 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"); }  

Nyní v tomto případě“ code works „netiskne, ale když odstraním deklaraci pole a vytiskne se inicializační kód. V čem je problém?

Fungují dvourozměrná pole v Arduinu jinak, nebo jde o problém s prostorem?

Komentáře

  • Dokonce i jednorozměrné pole 5376 bajtů na procesoru s 2048 bajty selže.
  • Chtěl jsem říct, 10752 bajtů. Přehlédl jsem, že každá položka pole má 2 bajty. Pamatujte, že nemáte k dispozici všech 2048 bajtů '. Samotné vyrovnávací paměti pro sériový přenos a příjem spotřebovávají až 128 bajtů.
  • Pokud tedy připojím vozidlo s mikro SD, existuje nějaká metoda pro deklaraci pole v této paměti?
  • Můžete připojit SD kartu a zapište si data do svého srdce ' obsahu. Můžete však ' t " deklarovat pole v paměti ". Jaká je vaše žádost? Arduino se 2 kB RAM není ' to nejlepší pro zpracování obrazu.
  • Potřebuji přečíst malý soubor BMP v řadě ints v Arduinu a je třeba to trochu zpracovat. A velikost souboru je 56 x 96 pixelů.

Odpověď

2D pole fungují na arduinu dobře, ale vy velmi rychle dojde místo.

Uno má 2 kilobajty RAM; vaše pole má 56 * 96 = 5376 dvoubajtových prvků.

Hádal bych, že píšete přes nějakou kritickou hodnotu paměti s 5 v určitém okamžiku, což způsobí selhání programu.

Komentáře

  • Nejen v paměti, ale pravděpodobně i ve všech I / O registrech.
  • 16bitové adresování, SRAM začíná od 256. Takže ' má 65279 bajtů adresního prostoru. ' toho tedy nedosáhnete. Také jsem si ' jistý, že tomu nějaká ochrana brání.
  • Žádná ochrana neexistuje. Registry CPU jsou mapovány do paměti počínaje adresou 0, poté I / O registry od adresy 32, poté staticky přidělená RAM začíná na adrese 256.

Answer

Snažíte se použít více paměti, než kolik máte k dispozici: 96 * 56 * 2 = 10,752KBytes. Není mnoho, co může MCU udělat, když k tomu dojde.

Pokud nahlédnete do datového listu , uvidíte, že váš mikrokontrolér (ATmega328p) má pouze 2 kB paměti RAM.

Myslím, že otázkou tedy je, zeptat se sami sebe, zda opravdu potřebujete takové velké pole. Můžete zvážit získání externího flash čipu nebo štítu SD karty. Pokud ho potřebujete pouze pro účely jen pro čtení (například pro vyhledávání tabulka), můžete použít část své paměti flash programu (máte 32 kBytů).

Komentáře

  • Já ' m používám kartu SDcard, ale ' m čtu data do takto deklarovaného pole. Jak bych mohl používat paměť SD karty.
  • Obvykle nepotřebujete ' narazit na všech 5376 prvků vašeho pole v jednom okamžiku. Zvažte rozdělení vašeho obrazu na menší bloky pro zpracování. V závislosti na druhu zpracování, které provádíte, můžete k optimalizaci procesu vyžadovat různé chytrosti . 😉
  • Lze na paměť flash zapisovat data znovu a znovu. Co máte na mysli jen pro čtení? Jak se do něj jednou zapisují data. Například chci zapsat obrazová data na flash paměť. Jak to zvládnu?
  • Mám na mysli flash paměť vašeho programu. AFAIK, během programování můžete psát do programu pouze flash. Jakmile spustíte svůj MCU, programový blesk se použije jako paměť jen pro čtení (takže program ' nezkazíme, když ' s běží.) Protože chcete zapisovat svá data, program Flash není vhodný.
  • Opravdu potřebujete zpracovat celý obraz najednou? Jak jsem již ' zmínil, můžete svůj obrázek rozdělit na menší bloky, řekněme, že část [8] [8] by byla pro Arduino pohodlná velikost vlaštovka a funguje dobře, i když používáte konvoluční filtry. (Z tohoto důvodu musím zdůraznit, že Arduino Uno je nevhodné pro jakoukoli seriózní aplikaci pro zpracování obrazu.)

Odpověď

Toto je skutečně problém paměti RAM, která je k dispozici.Pokud nepotřebujete 8 bitů na kus dat (pokud jste například ochotni snížit kvalitu obrazu), zvažte zhutnění dat tak, abyste měli více dat na bit. Například hexadecimální hodnoty nebo BCD (binárně kódovaná desetinná místa) mohou fungovat v závislosti na velikosti každého datového souboru.

Komentáře

  • OP chce načíst soubor BMP do paměti, takže pochybuji, že by z něj bylo velmi užitečné udělat BCD.
  • To ' je dobré. Možná je ' ochoten výrazně snížit kvalitu obrazu? Ať tak či onak, další úložiště by bylo moudré.

Odpovědět

Jak již uvedli ostatní, vaše pole je větší než dostupnou RAM ve vašem Arduinu. Jiní zmínili Flash paměť, která by pro vás mohla být řešením. Vaše Arduino má 32 kB paměti, do které se vejde vaše pole. V následující příručce najdete další informace o paměti Flash. Mějte na paměti, že Flash a EEPROM mají omezený počet cyklů zápisu, než se stanou nespolehlivými.

Skryté pravomoci – ukládání dat do Flash a EEPROM

Odpověď

V případě, že je matice většinou prázdná nebo má hodnoty, které lze vypočítat programově, řídká pole by mohla přijít na pomoc. Vyžaduje přidělení paměti a přeskakování, takže doba přístupu k jednotlivým prvkům není deterministická, ale můžete vypočítat nejhorší scénář.

Odpověď

Tímto způsobem jsem nakrmil své 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() { }  

Toto poběží přes celé pole, zatímco tisk bude probíhat přes Serial, který poté vytiskne „Hotovo!“ jakmile to bude. Navrhuji změnu:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96  

Na nižší hodnoty, pokud nemáte několik dobrých minut po ruce.

Komentáře

  • Tím se jeho problém vůbec nevyřeší. Není to ' čas, je to velikost pole. 56 * 96 * 2 (int je dva bajty) používá 10752 bajtů. Vaše Uno má 2048 bajtů. Problém není čas, je to úložiště.
  • Nick měl pravdu, toto ' můj problém nevyřešilo. Každopádně děkujeme za vyzkoušení.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *