Taulukon maksimikoko Arduinon IDEssä

Teen Arduino Unolle ohjelmanpätkää, johon tarvitsen mahdollisimman suuren taulukon (array, int-tyyppiä). Jos määrittelen esimerkiksi kooksi 10000, kehitysympäristö ilmoittaa, että array is too large. 8150 on suurin koko, jonka kehitysympäristö hyväksyy. Mikä määrittää tässä tapauksessa taulukon maksimikoon? Onko taulukon lisäksi jokin keino, jolla voi tallentaa suuria määriä dataa?

flash vai ram taulukkoa käyttämässä?

ATmega 328:ssa on vain 2kB rammia eli 16 bit arvoja 1024 kpl tai 32bit arvoja 512 kpl.

Ohjelmamuistiin tuleva kiinteä taulukko määrittyy täysin käytettävissä olevan FLASHin määrästä. Eli 32 kB - käyttis - oma koodi.

Sanoisin nyt, että ohjelmalogiikassasi on virhe tai sitten alustasi on väärä.

Onko taulukkosi jokin tallennuspaikka? Tarvitsetko ihan varmasti noin paljon dataa?

Tai toisaalta,

Onko taulukkosi jokin hakutaulukko? voiko taulukkosi arvot generoida laskemalla? Onko aikaa laskea niitä? Voitko kenties laskea pienemmästä bittimäärästä laskea tarkan arvon? Tarvitsetko kaikki nuo bitit siihen?

Itsellä tulee mieleen eräs asentomittari. Siinä oli sini taulukoitu 36 arvolla. Tästä sitten mentiin viivasuoraan pisteestä toiseen, koska oli varaa tehdä tuollainen pyöristys.

Lisäksi datan logitus tapahtui logaritmisesti. 100, 10, 1 ja 0,1 edellisen sekunnin asentotiedot olivat keskiarvottetuina käytössä ja uuden arvon tullessa laskettiin uudet arvot noille. Niiden perusteella tehtiin sitten päätelmiä.
Mittaus tehtiin kilohertsillä. Joten minulla oli 5 sadan alkion rengaspuskuria. Näin ulkomuistista muisteltuani.

Joudun edelleenin toteamaan näin aluksi, että perusteet näistä asioista ovat erittäin hataralla pohjalla. Olen tekemässä koodinpätkää, jossa haluan saada Wii-ohjaimen joystickilla ohjatun askelmoottorin “liikeradan” tallennettua taulukkoon. Liikerata tarkoittaa tehtyjen steppien määrää joystickin asennon määrittelemillä delay-arvoilla (skaala esim 200-500 mikrosekuntia). Haluan sitten tämän liikeradan toistuvan automaattisesti samanlaisena (mutta peilikuvana), kun esim. painan Wiin painiketta. Askelmoottori käyttämälläni ajurilla tekee 1600 steppiä / kierros. Eli vähimmäismäärä taulukkoon tallennettavaa moottorin delay-dataa on tuo 1600. Eikö näin? Pystyykö tämän tekemään pelkästään Arduinon (UNO) RAM-muistin varassa vai onko hankittava SD-kortti-plugin, jota käytetään juuri dataloggaustarkoituksiin?

Eli ristikko ohjaimella ajetaan?

Ajattele tilannetta näin:
Silloin tarvitsee tietää kuinka pitkään nappi on ollut pohjassa.

Taulukosta tulee silloin jotain tän tapaista:

vasemmalle sekunti
alas sekunti
kaikki ylhäällä viisi sekuntia
oikeaan kaksi sekuntia
koilliseen kolme sekuntia

Nyt ollaan viidellä rivillä (taulukon alkiolla) ilmaistu sekunnin resoluutiolla tuo kulku. Jos arvot olisivat kirjoitettu joka sekunti ylös näyttäisi taulukko:
VASSSSSOOLLL, jossa V on vasen, S on seis, O oikea ja L koiLlinen 13 alkiota.

//Huonoin tapa
int vasen[100];
int oikea[100];
int alas[100];
int ylos[100];
int aika = 0;
void tallenna(){
  vasen[aika++] =  lue(0);
  //JNE....
}

Muisti tuli täyteen nopiaan.

//Riippuen kohteestasi, optimoitu tapa
#define TAULUKON_KOKO 500
#define LIIKE_SUUNTA (1 << 15)
#define PYSTY_LIIKE (1 << 14)
#define VAAKA_LIIKE (1 << 13)
#define LIIKE_MASKI (PYSTY_LIIKE | VAAKA_LIIKE|LIIKE_SUUNTA)
#define MAX_AIKA (~LIIKE_MASKI)
uint16_t liike[TAULUKON_KOKO]; //kilotavu meni tähän.
uint16_t indeksi = 0;
void tallenna();
  int16_t napit = lue_napit();
  if((liike[indeksi] & LIIKE_MASKI) == ( napit & LIIKE_MASKI) && 
       ((liike[indeksi]&MAX_AIKA) < MAX_AIKA)){
    liike[indeksi] += 1;
  }else{
    indeksi = (indeksi + 1) % TAULUKON_KOKO; 
    //Pyörähtää ympäri ja alkaa kirjoittaan taulukkoa alusta.
    liike[indeksi] = napit;
  }
}

Nyt liike taulukossa on tieto suunnasta (8 kpl alkion ylimmissä biteissä) ja sen kestosta. Yksi taulukon arvo voi pitää sisällään 65536/2/2/2 = 8192 kpl mittausresoluution määräämiä aikayksiköitä. millisekunneilla reilu 8 sekuntia. Pönötystä taulukkoon mahtuu 4000 sekuntia, jos yhtään nappia ei paineta. Tunti ja kahdeksan minuuttia. Tai sitten 500 muutosta napeissa. Yksi muutos maksaa 8 sekuntia pitoa.

Auttoiko selvittämään ajatustani yhtään? | on bitti OR, & bitti AND ~ bitti NOT ja % jakojäännös. #define VAKIO arvo rivi käskee kääntäjää laittaan arvon joka paikkaan, jossa lukee VAKIO. Toivottavasti noilla koodi aukeaa.

Enkä kyllä ollut edes varma vastasinko ongelmaasi.

Vaihtoehtona on myös nauhoittaa kellon kanssa nappien muutoksia (reunoja) eli aikaleima millisekunteina ja mikä muutos; 10ms, YLÖS painettu, 1010ms YLÖS päästetty, 2000ms ALAS painettu, 2100ms OIKEALLE painettu, 2500 ALAS päästetty, 3050ms OIKEALLE päästetty

Kiitokset vinkeistä! Näistä opin taas uusia asioita. Tutkin näitä mahdollisuuksia.

Heh, minulla meni kaksi viikkoa, että lopulta käsitin tuon bittitason operaatioihin perustuvan koodiesimerkin. Tulipa todella opittua uusia asioita. Luulen, että tarvitsen kaikesta huolimatta muistilaajennoksen SD-kortilla. Tilasin korttisovittimen Adafruitista. Kiitos kuitenkin vinkeistä!

Oisi pitänyt heti mainostaa tuota omaa vanhaa lukija-artikkelia: viewtopic.php?f=15&t=146
Siinä nyplätään bittejä ihan urakalla. Toivottavasti löysit sen.

Mutta SD-kortin kanssa onkin sitten elää. Sinne mahtuu dumppaamaan vaikka joka sekunnin tilan. Jos joka sekunti tulisi tavu dataa, niin ilman tiedostojärjestelmän ylimäärää vuodessa tulisi 32 megaa dataa :slight_smile: