Arduino Uno kan de tweedimensionale array niet verwerken

Nu gebruikt de code die ik in Arduino schrijf (met Arduino) meerdere 2-dimensionale arrays. Ik print iets met behulp van de seriële monitor, het drukt het correct af, maar wanneer ik de tweedimensionale array declareer en initialiseer, wordt het “niet afgedrukt.

Code:

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

Nu wordt in dit geval” code werkt “niet afgedrukt, maar wanneer ik de array-declaratie verwijder en de initialisatiecode werkt, wordt deze afgedrukt. Wat is het probleem?

Werken tweedimensionale arrays anders in Arduino of is het een probleem met de ruimte?

Opmerkingen

  • Zelfs een eendimensionale array van 5376 bytes, op een processor met 2048 bytes, zal mislukken.
  • Ik bedoelde, 10752 bytes. Ik heb over het hoofd gezien dat elk array-item 2 bytes is. Houd er rekening mee dat u ‘ niet eens al die 2048 bytes beschikbaar heeft. Alleen al de seriële verzend- en ontvangstbuffers gebruiken 128 bytes.
  • Als ik een micro-SD-auto aansluit, is er dan een methode om de array in dat geheugen te declareren?
  • Je kunt een SD-kaart en schrijf gegevens naar uw hart ‘ s inhoud. U kunt echter ‘ t ” de array in het geheugen ” erop declareren. Wat is uw aanvraag hier? Een Arduino met 2 KB RAM is niet ‘ het beste voor beeldverwerking.
  • Ik moet een klein BMP-bestand lezen in een reeks ints in Arduino en moet er wat bewerkingen aan uitvoeren. En de bestandsgrootte is 56 bij 96 pixels.

Answer

2D-arrays werken prima op Arduino, maar jij snel te weinig ruimte hebben.

Een uno heeft 2 kilobytes ram; je array heeft 56 * 96 = 5376 2-byte elementen.

Ik denk dat je op een gegeven moment een kritische geheugenwaarde overschrijft met een 5 waardoor het programma mislukt.

Opmerkingen

  • Niet alleen over het geheugen, maar waarschijnlijk ook over alle I / O-registers.
  • 16 bit adressering, met SRAM vanaf 256. Zodat ‘ 65279 bytes adresruimte heeft. Dus je hebt ‘ dat niet bereikt. Ook ben ik ‘ er vrij zeker van dat er een soort bescherming is die dit verhindert.
  • Er is geen bescherming. De CPU-registers worden in het geheugen toegewezen, beginnend bij adres 0, vervolgens de I / O-registers vanaf adres 32, en vervolgens begint het statisch toegewezen RAM bij adres 256.

Antwoord

U probeert meer geheugen te gebruiken dan beschikbaar is: 96 * 56 * 2 = 10.752KBytes. De MCU kan niet veel doen als dit gebeurt.

Als je de datasheet bekijkt, “zie je dat je microcontroller (ATmega328p) slechts 2 KBytes RAM heeft.

Ik denk dat de vraag is om jezelf af te vragen of je die grote array echt nodig hebt. Je kunt overwegen om een externe flash-chip of een SD-kaartschild aan te schaffen. Als je deze alleen nodig hebt voor alleen-lezen doeleinden (zoals een zoekopdracht table), kunt u een deel van uw flash-programmageheugen gebruiken (u heeft 32 KBytes).

Opmerkingen

  • Ik ‘ m gebruikmakend van een SD-kaartscherm, maar ik ‘ m lees de gegevens in een array die op deze manier is gedeclareerd. Hoe zou ik het geheugen van de SD-kaart kunnen gebruiken.
  • U hoeft ‘ meestal niet alle 5376 elementen van uw array in één keer te verwerken. uw afbeelding opsplitsen in kleinere delen voor verwerking. Afhankelijk van het soort verwerking dat u uitvoert, heeft u mogelijk verschillende slimme opties nodig om het proces te optimaliseren;-)
  • Kan men keer op keer gegevens naar het flash-geheugen schrijven. Wat bedoel je met alleen-lezen? Hoe schrijf je de gegevens er één keer op? Ik wil bijvoorbeeld de afbeeldingsgegevens naar het flashgeheugen schrijven. Hoe kan ik het doen?
  • Ik verwijs naar het flash-geheugen van uw programma. AFAIK, je kunt alleen tijdens het programmeren naar de programmaflits schrijven. Als je je MCU opstart, wordt de programmaflash gebruikt als alleen-lezen geheugen (zodat we ‘ het programma niet verknoeien als het ‘ s loopt.) Aangezien u uw gegevens wilt schrijven, is de programmaflits niet geschikt.
  • Moet u echt de hele afbeelding in één keer verwerken? Zoals ik ‘ al eerder heb vermeld, kun je je afbeelding in kleinere blokken verdelen, bijvoorbeeld chunk [8] [8] zou een comfortabele maat zijn voor Arduino om slikken, en het werkt goed, zelfs als u convolutiefilters gebruikt. (Dat gezegd hebbende, moet ik benadrukken dat de Arduino Uno niet geschikt is voor een serieuze beeldverwerkingstoepassing.)

Antwoord

Inderdaad, dit is een kwestie van beschikbare RAM.Als u geen 8 bits per stuk gegevens nodig hebt (als u bijvoorbeeld de beeldkwaliteit wilt verminderen), overweeg dan om uw gegevens zo te comprimeren dat u meerdere gegevensstukken per bit hebt. Hex-waarden of BCD (binair gecodeerde decimalen) kunnen bijvoorbeeld werken, afhankelijk van de grootte van elk gegeven.

Opmerkingen

  • Het OP wil een BMP-bestand in het geheugen lezen, dus ik betwijfel of het erg nuttig kan worden omgezet in BCD.
  • Dat ‘ is een goed punt. Misschien is hij ‘ bereid om zijn beeldkwaliteit aanzienlijk te verminderen? Hoe dan ook, extra opslagruimte zou verstandig zijn.

Answer

Zoals anderen hebben opgemerkt, is je array groter dan het beschikbare RAM-geheugen in uw Arduino. Anderen noemden Flash-geheugen dat een oplossing voor u zou kunnen zijn. Je Arduino heeft 32 KB geheugen dat je array zou kunnen bevatten. Zie de volgende referentie voor meer informatie over Flash-geheugen. Houd er rekening mee dat Flash en EEPROM een beperkt aantal schrijfcycli hebben voordat ze onbetrouwbaar worden.

Verborgen bevoegdheden – gegevens opslaan in Flash en EEPROM

Antwoord

Als de matrix grotendeels leeg is of hoe dan ook waarden heeft die programmatisch kunnen worden berekend, sparse arrays kunnen te hulp komen. Het vereist geheugentoewijzing en hoppen, dus de toegangstijd tot individuele elementen is niet deterministisch, maar je kunt het worstcasescenario berekenen.

Answer

Dit is wat ik mijn Uno heb gegeven:

 #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() { }  

Dit zal over de hele array lopen, terwijl de voortgang via Serial wordt afgedrukt, die vervolgens “Gereed!” als het eenmaal is. Ik stel voor het volgende te wijzigen:

 #define IMAGEWIDTH 56 #define IMAGEHEIGHT 96  

In mindere waarden, tenzij je een paar goede minuten bij de hand.

Opmerkingen

  • Dit zal zijn probleem helemaal niet oplossen. Het is niet ‘ t tijd, het is de grootte van de array. 56 * 96 * 2 (een int is twee bytes) gebruikt 10752 bytes. Uw Uno heeft 2048 bytes. Het probleem is niet de tijd, het is de opslag.
  • Nick had gelijk, dit heeft mijn probleem niet ‘ t opgelost. Hoe dan ook, bedankt voor het proberen.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *