Arduino Uno non è in grado di gestire array bidimensionali

Ora il codice che sto scrivendo in Arduino (utilizzando Arduino) utilizza più array bidimensionali. Ora quando Stampa qualcosa usando il monitor seriale, lo stampa correttamente ma quando dichiaro e inizializzo larray bidimensionale non lo stampa.

Codice:

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

Ora in questo caso” code works “non viene stampato ma quando rimuovo la dichiarazione dellarray e il codice di inizializzazione viene stampato. Qual è il problema?

Gli array bidimensionali funzionano diversamente in Arduino o si tratta di un problema di spazio?

Commenti

  • Anche un array unidimensionale di 5376 byte, su un processore con 2048 byte, fallirà.
  • Intendevo 10752 byte. Ho trascurato che ogni elemento dellarray è di 2 byte. Tieni presente che non ‘ non hai nemmeno tutti quei 2048 byte disponibili. I buffer di trasmissione e ricezione seriale da soli utilizzano fino a 128 byte.
  • Bene, se collego unauto micro-SD, esiste un metodo per dichiarare larray in quella memoria?
  • Puoi collegare un Scheda SD e scrivi i dati nel tuo cuore ‘ contenuto. Tuttavia puoi ‘ t ” dichiarare larray in memoria ” su di esso. Qual è la tua applicazione qui? Un Arduino con 2 KB di RAM non è ‘ la cosa migliore per lelaborazione delle immagini.
  • Ho bisogno di leggere un piccolo file BMP in un array di int in Arduino e devi fare qualche elaborazione su di esso. E la dimensione del file è di 56 per 96 pixel.

Answer

Gli array 2D funzionano bene su arduino, ma tu esaurire lo spazio molto rapidamente.

Uno ha 2 kilobyte di ram; il tuo array ha 56 * 96 = 5376 elementi a 2 byte.

Immagino che tu stia scrivendo su un valore di memoria critico con un 5 a un certo punto che causa il fallimento del programma.

Commenti

  • Non solo sulla memoria, ma probabilmente anche su tutti i registri di I / O.
  • Indirizzamento a 16 bit, con SRAM a partire da 256. Quindi ‘ sono 65279 byte di spazio degli indirizzi. Quindi ‘ non lo raggiungerai. Inoltre, ‘ sono abbastanza sicuro che ci sia un qualche tipo di protezione che impedisce che ciò accada.
  • Non cè protezione. I registri della CPU sono mappati in memoria a partire dallindirizzo 0, quindi i registri I / O dallindirizzo 32, quindi la RAM allocata staticamente inizia dallindirizzo 256.

Risposta

Stai tentando di utilizzare più memoria di quella disponibile: 96 * 56 * 2 = 10,752 KB. Non molto che lMCU possa fare quando ciò accade.

Se guardi nella scheda tecnica , vedrai che il tuo microcontrollore (ATmega328p) ha solo 2 KB di RAM.

Immagino che la domanda sia chiedersi se hai davvero bisogno di un array così grande. Potresti prendere in considerazione lacquisto di un chip flash esterno o di uno scudo per scheda SD. Se ne hai bisogno solo per scopi di sola lettura (come una ricerca table), puoi utilizzare parte della tua memoria flash del programma (hai 32 KByte).

Commenti

  • ‘ utilizzo uno sheild della scheda SD ma ‘ leggo i dati in un array dichiarato come questo. Come potrei utilizzare la memoria della scheda SD.
  • Non ‘ di solito devi occuparti di tutti i 5376 elementi del tuo array in un istante. Considera suddividendo la tua immagine in parti più piccole per lelaborazione. A seconda del tipo di elaborazione che fai, potresti aver bisogno di intelligenze diverse per ottimizzare il processo . 😉
  • Si possono scrivere dati sulla memoria flash ancora e ancora. Cosa intendi per sola lettura? Come si scrivono i dati una volta su di esso. Ad esempio, voglio scrivere i dati dellimmagine su quella della memoria flash. Come potrò farlo?
  • Mi riferisco alla memoria flash del tuo programma. Per quanto ne so, è possibile scrivere solo nella flash del programma durante la programmazione. Una volta avviato lMCU, la memoria flash del programma viene utilizzata come memoria di sola lettura (in modo che ‘ non rovini il programma quando ‘ è in esecuzione.) Dato che vuoi scrivere i tuoi dati, il programma flash non è adatto.
  • Hai davvero bisogno di elaborare lintera immagine in una volta? Come ho ‘ accennato prima, puoi dividere la tua immagine in blocchi più piccoli, ad esempio pezzo [8] [8] sarebbe una dimensione comoda per Arduino deglutire e funziona bene anche se si utilizzano filtri a convoluzione. (Detto questo, devo sottolineare che Arduino Uno è inadatto per qualsiasi applicazione seria di elaborazione delle immagini.)

Risposta

In effetti, questo è un problema di RAM disponibile.Se non hai bisogno di 8 bit per pezzo di dati (se forse sei disposto a ridurre la qualità dellimmagine, per esempio), considera la compattazione dei tuoi dati in modo da avere più pezzi di dati per bit. Ad esempio, i valori esadecimali o BCD (decimali in codice binario) potrebbero funzionare, a seconda della dimensione di ogni parte di dati.

Commenti

  • LOP vuole leggere un file BMP in memoria, quindi dubito che possa essere convertito in BCD molto utilmente.
  • Questo ‘ è un buon punto. Forse ‘ è disposto a ridurre in modo significativo la qualità dellimmagine? In ogni caso, sarebbe saggio spazio di archiviazione aggiuntivo.

Risposta

Come altri hanno notato, il tuo array è più grande di la RAM disponibile nel tuo Arduino. Altri hanno menzionato la memoria Flash che potrebbe essere una soluzione per te. Il tuo Arduino ha 32 KB di memoria che potrebbero contenere il tuo array. Vedere il riferimento seguente per ulteriori informazioni sulla memoria Flash. Tieni presente che Flash ed EEPROM hanno un numero limitato di cicli di scrittura prima di diventare inaffidabili.

Hidden Powers – memorizzazione dei dati in Flash ed EEPROM

Risposta

Nel caso in cui la matrice sia per lo più vuota o comunque abbia valori che possono essere calcolati in modo programmatico, array sparsi potrebbero venire in soccorso. Richiede lallocazione e lhopping della memoria, quindi il tempo di accesso ai singoli elementi non è deterministico, ma puoi calcolare lo scenario peggiore.

Risposta

Questo è ciò che ho alimentato con il mio 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() { }  

Questo eseguirà lintero array, mentre stampa lavanzamento su Serial, che quindi stamperà “Fatto!” una volta che lo è. Suggerisco di cambiare:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96  

a valori minori, a meno che tu non ne abbia alcuni buoni minuti a portata di mano.

Commenti

  • Questo non risolverà affatto il suo problema. Non è ‘ t tempo, è la dimensione dellarray. 56 * 96 * 2 (un int è due byte) utilizza 10752 byte. Il tuo Uno ha 2048 byte. Il problema non è il tempo, è larchiviazione.
  • Nick aveva ragione, questo ‘ non ha risolto il mio problema. Comunque, grazie per aver provato.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *