Soru:
Arduino Uno 2 boyutlu diziyi işleyemiyor
George J. Adams
2015-08-20 22:11:54 UTC
view on stackexchange narkive permalink

Şimdi Arduino'da yazdığım kod (Arduino kullanarak) birden çok 2 boyutlu diziler kullanıyor. Şimdi Seri Monitörü kullanarak bir şeyi yazdırdığımda, onu doğru şekilde yazdırıyor, ancak 2 boyutlu diziyi bildirip başlattığımda, onu yazdırmıyor.

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 ("kod çalışıyor");}  

Şimdi bu durumda "kod çalışıyor" yazdırmıyor, ancak dizi bildirimini kaldırdığımda ve başlatma kodu çalışmaları yazdırılıyor. Sorun nedir?

2 boyutlu diziler Arduino'da farklı mı çalışıyor yoksa bir uzay sorunu mu?

2048 baytlık bir işlemcide 5376 baytlık tek boyutlu bir dizi bile başarısız olur.
** 10752 ** bayt demek istedim. Her dizi öğesinin 2 bayt olduğunu gözden kaçırdım. Unutmayın ki bu 2048 baytın hepsine sahip değilsiniz. Seri gönderme ve alma arabellekleri tek başına 128 bayt kullanır.
Peki bir mikro SD kart bağlarsam, bu bellekte dizi bildirmek için bir yöntem var mı?
Bir SD kart bağlayabilir ve kalbinizin içeriğine veri yazabilirsiniz. Bununla birlikte, üzerinde "bellekteki diziyi bildiremezsiniz". Buradaki uygulamanız nedir? 2 KB RAM'e sahip bir Arduino, görüntü işleme için en iyi şey değildir.
Arduino'daki bir dizi ints içinde küçük bir BMP dosyası okumam gerekiyor ve üzerinde biraz işlem yapmam gerekiyor. Ve dosya boyutu 56 x 96 pikseldir.
Bunu yeniden düşünmeniz gerekecek. 2048 bayt RAM'li bir Arduino'da 10752 bayt piksel üzerinde okuyamaz ve "işlem yapamazsınız". Belki bir Due'da yapabilirsin. `` 2 boyutlu diziler Arduino'da farklı mı çalışıyor yoksa bir uzay sorunu mu? '' - bu kesinlikle bir uzay sorunudur.
Due'da farklı olan nedir? Artı Mega 2560 bunun için çalışabilir mi?
Ya görüntü verilerini flash belleğe kaydedersem ve bazı işlemler yaparsam sonuçları flash belleğe de kaydederim. Bu yaklaşım işe yarayacak mı?
`` Artı Mega 2560 bunun için çalışabilir mi? '' - Sorunuzu yanıtlarsa, Mega 8 KB RAM'e sahiptir. 10,5 KB istiyorsunuz.
[Due] (https://www.arduino.cc/en/Main/ArduinoBoardDue) 96 KB RAM'e sahiptir. Bu daha uygun görünüyor.
Altı yanıtlar:
BrettAM
2015-08-20 22:36:53 UTC
view on stackexchange narkive permalink

2D diziler arduino'da iyi çalışır, ancak çok hızlı bir şekilde alanınız tükenir.

Uno'da 2 kilobayt ram vardır; dizinizde 56 * 96 = 5376 2 baytlık elemanlar var.

Bir noktada 5 ile bazı kritik bellek değerlerinin üzerine yazdığınızı tahmin ediyorum, programın başarısız olmasına neden oluyor.

Yalnızca bellek üzerinde değil, aynı zamanda tüm G / Ç kayıtlarında da.
256'dan başlayan SRAM ile 16 bit adresleme. Yani 65279 baytlık adres alanı. Böylece ona ulaşamayacaksın. Ayrıca, bunun olmasını engelleyen bir tür koruma olduğundan oldukça eminim.
Koruma yok. CPU kayıtları, 0 adresinden başlayarak bellek eşlemelidir, daha sonra 32 adresinden G / Ç kayıtları, ardından statik olarak tahsis edilen RAM, adres 256'da başlar.
bot3663369
2015-08-21 10:34:45 UTC
view on stackexchange narkive permalink

Elinizde mevcut olandan daha fazla bellek kullanmaya çalışıyorsunuz: 96 * 56 * 2 = 10.752KBayt. Bu olduğunda MCU'nun yapabileceği pek bir şey yok.

Veri sayfasına bakarsanız, mikro denetleyicinizin (ATmega328p) yalnızca 2KByte RAM'e sahip olduğunu görürsünüz.

O halde asıl soru kendinize bu kadar büyük bir diziye gerçekten ihtiyacınız olup olmadığını sormaktır. Harici bir flash çip veya bir SD kart kalkanı almayı düşünebilirsiniz. Yalnızca salt okunur amaçlarla ihtiyacınız varsa (arama tablosu gibi), flash program belleğinizin bir kısmını kullanabilirsiniz (32 KB baytınız var).

Bir SD kart kalkanı kullanıyorum, ancak verileri böyle bildirilmiş bir diziye okuyorum. SD Kart belleğini nasıl kullanabilirim.
Genelde dizinizin 5376 öğesinin tümü ile tek seferde ilgilenmeniz gerekmez. Resminizi işlenmek üzere daha küçük parçalara bölmeyi düşünün. Yaptığınız işlemin türüne bağlı olarak, işlemi optimize etmek için farklı akıllılar gerekebilir. ;-)
Flash belleğe tekrar tekrar veri yazılabilir. Salt okunur derken neyi kastediyorsunuz? Veriler üzerine nasıl yazılır? Örneğin, görüntü verilerini flash belleğe yazmak istiyorum. Bunu nasıl yapacağım?
Programınızın flash belleğinden bahsediyorum. AFAIK, programlama sırasında sadece flash programa yazabilirsiniz. MCU'nuzu başlattığınızda, program flaşı salt okunur bellek olarak kullanılır (böylece programı çalışırken karıştırmayız.) Verilerinizi yazmak istediğiniz için program flaşı uygun değildir.
Tüm görüntüyü tek seferde işlemeniz gerçekten gerekiyor mu? Daha önce bahsettiğim gibi, görüntünüzü daha küçük bloklara bölebilirsiniz, örneğin ** yığın [8] [8] **, Arduino'nun yutması için rahat bir boyut olur ve evrişim filtreleri kullansanız bile iyi çalışır. (Bunu söyledikten sonra, Arduino Uno'nun herhangi bir ciddi görüntü işleme uygulaması için ** uygun olmadığını ** vurgulamalıyım.)
Dodo
2015-08-22 06:27:52 UTC
view on stackexchange narkive permalink

Doğrusu, bu mevcut bir RAM sorunudur. Veri parçası başına 8 bit'e ihtiyacınız yoksa (örneğin, görüntü kalitesini düşürmek istiyorsanız), verilerinizi bit başına birden çok veri parçası olacak şekilde sıkıştırmayı düşünün. Örneğin, her bir veri parçasının boyutuna bağlı olarak onaltılık değerler veya BCD (ikili kodlu ondalık sayılar) işe yarayabilir.

OP bir BMP dosyasını belleğe okumak istiyor, bu yüzden BCD'ye çok yararlı bir şekilde dönüştürülebileceğinden şüpheliyim.
İyi bir noktaya değindin. Belki de görüntü kalitesini önemli ölçüde düşürmek istiyordur? Her iki durumda da ek depolama akıllıca olacaktır.
linhartr22
2015-08-28 01:42:38 UTC
view on stackexchange narkive permalink

Diğerlerinin de belirttiği gibi, diziniz Arduino'nuzdaki mevcut RAM'den daha büyük. Diğerleri, sizin için bir çözüm olabilecek Flash bellekten bahsetti. Arduino'nuz dizinizi tutabilecek 32 KB belleğe sahiptir. Flash bellek hakkında daha fazla bilgi için aşağıdaki referansa bakın. Flash ve EEPROM'un güvenilmez hale gelmeden önce sınırlı sayıda yazma döngüsüne sahip olduğunu unutmayın.

Gizli Güçler - verileri Flash ve EEPROM'da depolama

Igor Stoppa
2015-08-28 13:04:55 UTC
view on stackexchange narkive permalink

Matrisin çoğunlukla boş olması veya yine de programla hesaplanabilen değerlere sahip olması durumunda, seyrek diziler kurtarmaya gelebilir. Bellek ayırma ve atlama gerektirir, bu nedenle tek tek öğelere erişim süresi belirleyici değildir, ancak en kötü senaryoyu hesaplayabilirsiniz.

avluis
2015-08-21 06:03:33 UTC
view on stackexchange narkive permalink

Uno'mu besledim:

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

Bu, Seri üzerinden yazdırılırken tüm dizi üzerinde çalışacaktır. yazdır "Bitti!" bir kez. Değiştirmenizi öneririm:

  #define IMAGEWIDTH 56 # define IMAGEHEIGHT 96  

Daha düşük değerlere, yoksa elinizin altında birkaç güzel dakika.

Bu, onun problemini hiç çözmeyecek. Zaman değil, dizinin boyutu. 56 * 96 * 2 (int iki bayttır) 10752 bayt kullanır. Uno'nuzda 2048 bayt var. Sorun zaman değil, depolamadır.
Nick haklıydı, bu benim sorunumu çözmedi. Neyse, denediğin için teşekkürler.


Bu Soru-Cevap, otomatik olarak İngilizce dilinden çevrilmiştir.Orijinal içerik, dağıtıldığı cc by-sa 3.0 lisansı için teşekkür ettiğimiz stackexchange'ta mevcuttur.
Loading...