Arduino Uno não é capaz de lidar com array bidimensional

Agora, o código que estou escrevendo em Arduino (usando Arduino) usa vários arrays bidimensionais. Agora, quando Eu imprimo algo usando o Serial Monitor, ele imprime corretamente, mas quando eu declaro e inicializo o array bidimensional, ele não o imprime.

Código:

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

Agora, neste caso,” o código funciona “não é impresso, mas quando eu removo a declaração da matriz e o código de inicialização funciona é impresso. Qual é o problema?

Os arrays bidimensionais funcionam de maneira diferente no Arduino ou é um problema de espaço?

Comentários

  • Mesmo uma matriz unidimensional de 5376 bytes, em um processador com 2048 bytes, irá falhar.
  • Eu quis dizer, 10752 bytes. Eu esqueci que cada item do array tem 2 bytes. Lembre-se de que você não ‘ nem tem todos esses 2.048 bytes disponíveis. Os buffers de transmissão e recepção serial sozinhos usam até 128 bytes.
  • Bem, se eu conectar um carro micro-SD, existe algum método para declarar o array nessa memória?
  • Você pode conectar um Cartão SD e grave os dados no conteúdo ‘ do seu coração. No entanto, você pode ‘ t ” declarar o array na memória ” nele. Qual é a sua aplicação aqui? Um Arduino com 2 KB de RAM não é ‘ a melhor coisa para processamento de imagens.
  • Preciso ler um pequeno arquivo BMP em um array de ints no Arduino e precisa fazer algum processamento nele. E o tamanho do arquivo é de 56 por 96 pixels.

Resposta

Arrays 2D funcionam bem no Arduino, mas você ficar sem espaço muito rapidamente.

Um uno tem 2 kilobytes de RAM; seu array tem 56 * 96 = 5376 elementos de 2 bytes.

Eu acho que você está escrevendo sobre algum valor de memória crítico com 5 em algum ponto, causando a falha do programa.

Comentários

  • Não apenas sobre a memória, mas provavelmente também sobre todos os registradores de E / S.
  • Endereçamento de 16 bits, com SRAM começando em 256. Para que ‘ s 65279 bytes de espaço de endereço. Então você não ‘ alcançará isso. Além disso, ‘ tenho certeza de que existe algum tipo de proteção que impede que isso aconteça.
  • Não há proteção. Os registros da CPU são mapeados na memória começando no endereço 0, então os registros I / O do endereço 32, então a RAM alocada estaticamente começa no endereço 256.

Resposta

Você está tentando usar mais memória do que tem disponível: 96 * 56 * 2 = 10.752 KBytes. Não há muito que o MCU possa fazer quando isso acontecer.

Se você olhar a folha de dados , verá que seu microcontrolador (ATmega328p) tem apenas 2 KB de RAM.

Acho que a questão então é se perguntar se você realmente precisa de um array tão grande. Você pode considerar obter um chip flash externo ou um escudo SDcard. Se você só precisa dele para fins somente leitura (como uma pesquisa tabela), você pode usar parte de sua memória de programa flash (você tem 32 KBytes).

Comentários

  • Eu ‘ m usando um escudo SDcard, mas eu ‘ estou lendo os dados em um array declarado como este. Como eu seria capaz de usar a memória do cartão SD.
  • Você não ‘ normalmente precisa lidar com todos os 5376 elementos do seu array em um instante. Considere dividindo sua imagem em pedaços menores para processamento. Dependendo do tipo de processamento que você faz, você pode precisar de inteligência diferente para otimizar o processo . 😉
  • Pode-se escrever dados na memória flash repetidamente. O que você quer dizer com somente leitura? Como alguém escreve os dados uma vez nele. Por exemplo, eu quero gravar os dados da imagem na memória flash. Como poderei fazer isso?
  • Refiro-me ao seu programa de memória flash. AFAIK, você só pode escrever no flash do programa durante a programação. Depois de inicializar o MCU, o flash do programa é usado como memória somente leitura (para que não ‘ bagunçamos o programa quando ele ‘ está em execução.) Como você deseja gravar seus dados, o programa flash não é adequado.
  • Você realmente precisa processar a imagem inteira de uma vez? Como ‘ mencionei antes, você pode dividir sua imagem em blocos menores, digamos que chunk [8] [8] seria um tamanho confortável para o Arduino engula, e funciona bem mesmo se você usar filtros de convolução. (Dito isso, devo enfatizar que o Arduino Uno é inadequado para qualquer aplicativo sério de processamento de imagens.)

Resposta

Na verdade, este é um problema de RAM disponível.Se você não precisa de 8 bits por dado (se talvez esteja disposto a reduzir a qualidade da imagem, por exemplo), considere compactar seus dados de forma que você tenha vários dados por bit. Por exemplo, valores hexadecimais ou BCD (decimais codificados em binários) podem funcionar, dependendo do tamanho de cada parte dos dados.

Comentários

  • O OP deseja ler um arquivo BMP na memória, então duvido que ele possa ser transformado em BCD de forma útil.
  • Isso ‘ é um bom ponto. Talvez ele ‘ esteja disposto a diminuir significativamente a qualidade da imagem? De qualquer maneira, armazenamento adicional seria útil.

Resposta

Como outros observaram, sua matriz é maior do que a RAM disponível em seu Arduino. Outros mencionaram a memória Flash, que pode ser uma solução para você. Seu Arduino tem 32 KB de memória que pode conter seu array. Consulte a referência a seguir para obter mais informações sobre a memória Flash. Lembre-se de que Flash e EEPROM têm um número limitado de ciclos de gravação antes de se tornarem não confiáveis.

Poderes ocultos – armazenamento de dados em Flash e EEPROM

Resposta

Caso a matriz esteja quase vazia ou tenha valores que podem ser calculados programaticamente, matrizes esparsas podem ajudar. Requer alocação de memória e saltos, portanto o tempo de acesso a elementos individuais não é determinístico, mas você pode calcular o pior cenário possível.

Resposta

Isso é o que alimentei meu 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() { }  

Este irá percorrer todo o array, enquanto imprime o progresso em Serial, que então imprime “Done!” uma vez que é. Eu sugiro mudar:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96  

Para valores menores, a menos que você tenha alguns bons minutos disponíveis.

Comentários

  • Isso não vai resolver o problema dele. Não é ‘ hora, é o tamanho da matriz. 56 * 96 * 2 (um int tem dois bytes) usa 10752 bytes. Seu Uno tem 2.048 bytes. O problema não é o tempo, é o armazenamento.
  • Nick estava certo, isso não ‘ resolveu meu problema. De qualquer forma, obrigado por tentar.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *