Arduino Uno는 2 차원 배열을 처리 할 수 없습니다.

이제 Arduino (Arduino 사용)에서 작성하는 코드는 여러 2 차원 배열을 사용합니다. 직렬 모니터를 사용하여 인쇄하면 올바르게 인쇄되지만 2 차원 배열을 선언하고 초기화하면 인쇄되지 않습니다.

코드 :

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

이제이 경우”code works “가 인쇄되지 않지만 배열 선언을 제거하고 초기화 코드가 작동하면 인쇄됩니다. 문제가 무엇인가요?

Arduino에서 2 차원 배열이 다르게 작동하나요? 아니면 공간 문제인가요?

댓글

  • 2048 바이트의 프로세서에서 5376 바이트의 1 차원 배열도 실패합니다.
  • 내 말은 10752 바이트입니다. 각 배열 항목이 2 바이트라는 것을 간과했습니다. 사용 가능한 2048 바이트를 모두 사용할 수있는 '도 없다는 점에 유의하세요. 직렬 전송 및 수신 버퍼 만 128 바이트를 사용합니다.
  • 마이크로 SD 자동차를 연결하면 해당 메모리에 배열을 선언하는 방법이 있나요?
  • SD 카드 및 데이터를 마음의 ' 콘텐츠에 기록하세요. 그러나 ' 메모리에서 배열을 " 선언 할 수 없습니다 ". 여기서 귀하의 응용 프로그램은 무엇입니까? 2KB RAM이있는 Arduino는 ' 이미지 처리에 가장 적합하지 않습니다.
  • Arduino에서 int 배열의 작은 BMP 파일을 읽어야합니다. 일부 처리를해야합니다. 파일 크기는 56×96 픽셀입니다.

Answer

2D 배열은 arduino에서 잘 작동하지만 공간이 매우 빨리 부족합니다.

uno는 2 킬로바이트의 램을 가지고 있습니다. 배열에 56 * 96 = 5376 2 바이트 요소가 있습니다.

어떤 시점에서 프로그램이 실패하게 만드는 중요한 메모리 값을 5로 덮어 쓰고 있다고 생각합니다.

주석

  • 메모리뿐만 아니라 모든 I / O 레지스터에도 적용됩니다.
  • SRAM이 256부터 시작하는 16 비트 주소 지정. 따라서 '는 65279 바이트의 주소 공간입니다. 따라서 ' 이에 도달하지 못했습니다. 또한 '이를 방지하는 보호 수단이 있다고 확신합니다.
  • 보호가 없습니다. CPU 레지스터는 주소 0에서 시작하여 메모리 매핑되고, I / O는 주소 32에서 시작되고, 정적으로 할당 된 RAM은 주소 256에서 시작됩니다.

Answer

사용 가능한 것보다 더 많은 메모리를 사용하려고합니다 : 96 * 56 * 2 = 10.752KBytes. 이 경우 MCU가 할 수있는 일은 많지 않습니다.

데이터 시트 를 살펴보면 마이크로 컨트롤러 (ATmega328p)에 2KB의 RAM 만 있다는 것을 알 수 있습니다.

그런 다음 질문은 그렇게 큰 어레이가 정말로 필요한지 스스로에게 물어 보는 것입니다. 외장 플래시 칩이나 SD 카드 실드를 고려할 수 있습니다. 읽기 전용 목적 (예 : 조회 표), 플래시 프로그램 메모리 중 일부를 사용할 수 있습니다 (32KB가 있음).

댓글

  • ' SDcard sheild를 사용하고 있지만 ' 이와 같이 선언 된 배열로 데이터를 읽습니다. SD 카드 메모리를 어떻게 사용할 수 있을까요?
  • 일반적으로 배열의 5376 개 요소를 모두 한 번에 처리 할 필요는 없습니다. '. 처리를 위해 이미지를 더 작은 청크로 분할합니다. 수행하는 처리 유형에 따라 프로세스를 최적화하기 위해 다른 스마트가 필요할 수 있습니다. . 😉
  • 플래시 메모리에 데이터를 반복해서 쓸 수 있습니다. 읽기 전용이란 무엇을 의미합니까? 데이터를 한 번 작성하는 방법은 무엇입니까? 예를 들어 플래시 메모리에 이미지 데이터를 쓰고 싶습니다. 어떻게 할 수 있습니까?
  • 당신의 프로그램 플래시 메모리를 언급하고 있습니다. AFAIK, 프로그래밍 중에 만 프로그램 플래시에 쓸 수 있습니다. MCU를 부팅하면 프로그램 플래시가 읽기 전용 메모리로 사용됩니다 (따라서 프로그램이 실행될 때 ' 엉망이되지 않도록 '가 실행 중입니다.) 데이터를 쓰고 싶기 때문에 프로그램 플래시가 적합하지 않습니다.
  • 정말 전체 이미지를 한 번에 처리해야합니까? 앞서 언급했듯이 ' 이미지를 더 작은 블록으로 나눌 수 있습니다. 예를 들어 chunk [8] [8] 는 Arduino가 삼키고 컨볼 루션 필터를 사용하더라도 잘 작동합니다. (하지만 Arduino Uno가 모든 심각한 이미지 처리 애플리케이션에 부적합 하다는 점을 강조해야합니다.)

답변

사실, 이것은 사용 가능한 RAM 문제입니다.데이터 조각 당 8 비트가 필요하지 않은 경우 (예를 들어 이미지 품질을 낮추려는 경우) 비트 당 여러 데이터 조각을 갖도록 데이터를 압축하는 것이 좋습니다. 예를 들어 각 데이터의 크기에 따라 16 진수 값 또는 BCD (이진 코드 소수)가 작동 할 수 있습니다.

댓글

  • The OP BMP 파일을 메모리로 읽고 싶어서 BCD로 매우 유용하게 변환 할 수 있을지 의심 스럽습니다.
  • ' 좋은 지적입니다. 그가 ' 자신의 이미지 품질을 크게 낮출 의향이 있습니까? 어느 쪽이든 추가 스토리지가 현명 할 것입니다.

답변

다른 사람들이 언급했듯이 배열은 Arduino에서 사용 가능한 RAM. 다른 사람들은 당신에게 해결책이 될 수있는 플래시 메모리를 언급했습니다. Arduino에는 어레이를 저장할 수있는 32KB의 메모리가 있습니다. 플래시 메모리에 대한 자세한 내용은 다음 참조를 참조하십시오. 플래시 및 EEPROM은 신뢰할 수 없게되기 전에 제한된 수의 쓰기주기를가집니다.

숨겨진 전원-플래시 및 EEPROM에 데이터 저장

답변

행렬이 대부분 비어 있거나 어쨌든 프로그래밍 방식으로 계산할 수있는 값이있는 경우, 희소 배열 이 구출 될 수 있습니다. 메모리 할당 및 호핑이 필요하므로 개별 요소에 대한 액세스 시간은 결정적이지 않지만 최악의 시나리오를 계산할 수 있습니다.

Answer

이것이 제가 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() { }  

Serial을 통해 진행률을 인쇄하는 동안 전체 어레이에서 실행되고 “Done!”이 인쇄됩니다. 일단. 다음과 같이 변경하는 것이 좋습니다.

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96  

좋은 몇 가지가없는 한 더 작은 값으로 몇 분 남았습니다.

댓글

  • 이것은 그의 문제를 전혀 해결하지 못할 것입니다. ' 시간이 아니라 배열의 크기입니다. 56 * 96 * 2 (int는 2 바이트)는 10752 바이트를 사용합니다. Uno는 2048 바이트입니다. 문제는 시간이 아니라 저장 공간입니다.
  • 닉이 맞았어요. ' 내 문제가 해결되지 않았습니다. 어쨌든 시도해 주셔서 감사합니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다