Een const array van const arrays?

algemene C code
Gebruikers-avatar
Berichten: 63
Geregistreerd: 10 Jul 2014, 14:54

Een const array van const arrays?

Berichtdoor MrHaroldA » 26 Okt 2017, 21:24

Moeilijk uit te leggen maar heb de volgende arrays gedefinieerd:

Code: Alles selecteren
const unsigned char FX1[] = {0x60, 0x00, 0x00, 0x30};
const unsigned char MOD1[] = {0x60, 0x00, 0x04, 0x30};
const unsigned char L1[] = {0x60, 0x00, 0x00, 0x20};
const unsigned char L2[] = {0x60, 0x00, 0x00, 0x21};
const unsigned char L3[] = {0x60, 0x00, 0x00, 0x22};
const unsigned char FX2[] = {0x60, 0x00, 0x02, 0x29};
const unsigned char MOD2[] = {0x60, 0x00, 0x05, 0x1E};
const unsigned char DLY[] = {0x60, 0x00, 0x06, 0x10};
const unsigned char REV[] = {0x60, 0x00, 0x06, 0x30};
const unsigned char NS[] = {0x60, 0x00, 0x06, 0x56};
const unsigned char SOLO[] = {0x60, 0x00, 0x0B, 0x02};
const unsigned char CTL_OUT_1[] = {0x60, 0x00, 0x0B, 0x05};
const unsigned char CTL_OUT_2[] = {0x60, 0x00, 0x0B, 0x06};


En daar wil ik arrays mee kunnen vullen:

Code: Alles selecteren
const unsigned char PATCH_DATA[4][4] = {
    FX1,
    L1,
    L2,
    L3
};


... en dat werkt (natuurlijk) niet ;)

Ik kan er ook weinig over vinden, maar kan goed zijn dat ik gewoon niet de juiste zoektermen gebruik. is dit eigenlijk wel mogelijk, of moet ik een andere oplossing verzinnen?

Advertisement

Gebruikers-avatar
Berichten: 4890
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Een const array van const arrays?

Berichtdoor nicoverduin » 26 Okt 2017, 21:47

Klopt je geeft nu een char * door van het eerste element van elke array. Ik zou eerder aan uint32_t denken en die vullen met een hex getal. En jouw patch array met een union opzetten om de 4x4 bytes leeg haalt.
Docent HBO Software Engineering, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 63
Geregistreerd: 10 Jul 2014, 14:54

Re: Een const array van const arrays?

Berichtdoor MrHaroldA » 26 Okt 2017, 21:57

Hey Nico, ik had ergens jou al wel verwacht ;)

Die vier hex getallen komen van de SysEx waar mijn Boss MS-3 over USB mee praat. Ik kan die inderdaad overzetten naar een uint32_t, maar het liefste laat ik de hex daar staan omdat het nogal een lijst wordt en dit makkelijker te onderhouden is. Ik ben het wel met je eens dat dat wel een stuk makkelijker zou zijn.

Ik gebruik op een andere plek overigens al het platslaan van deze 4 hexen:

Code: Alles selecteren
const unsigned char PATCH[4] = {0x00, 0x01, 0x00, 0x00};

uint32_t parameterSum(const unsigned char *parameter) {
    uint32_t sum = 0;

    for (uint8_t i = 0; i < 4; i++) {
        sum += parameter[i] >> (i * 8); // Mogelijk de verkeerde kant op geshift; maar maakt niets uit voor de werking.
    }

    return sum;
}

void parseData(uint8_t *parameter, uint8_t *data) {
    uint32_t sum = parameterSum((const unsigned char*)parameter);

    if (parameterSum(PATCH) == sum) {
        DEBUG(F("PC received: "));
        DEBUGLN(data[0]);
        activateSet(Patch.load(data[0], 0));
    }
}


Ik denk dat ik het maar gewoon dubbel ga definiëren ...

Gebruikers-avatar
Berichten: 4890
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Een const array van const arrays?

Berichtdoor nicoverduin » 26 Okt 2017, 22:05

Hi harald. Ik zou eens naar die union kijken. Dan heb je hem gelijk.
Docent HBO Software Engineering, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 63
Geregistreerd: 10 Jul 2014, 14:54

Re: Een const array van const arrays?

Berichtdoor MrHaroldA » 26 Okt 2017, 22:28

Verrek ... een uint32_t kun je natuurlijk ook definieren met bv 0x60000030.

Code: Alles selecteren
const uint32_t FX1  = 0x60000030;
const uint32_t MOD1 = 0x60000430;

const uint32_t PATCH_DATA[] = {
    FX1,
    MOD1
};


Die kost me natuurlijk wel 2x zo veel geheugen ...


nicoverduin schreef:Ik zou eens naar die union kijken. Dan heb je hem gelijk.


Die gaat nog even boven mijn pet. Wat voor voordeel gaat me dat geven?

Berichten: 2476
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Een const array van const arrays?

Berichtdoor shooter » 26 Okt 2017, 23:04

dan wordt het 1 lange array, en die kun je dus snel een 4 bij 4 maken.
paul deelen
shooter@home.nl

Gebruikers-avatar
Berichten: 63
Geregistreerd: 10 Jul 2014, 14:54

Re: Een const array van const arrays?

Berichtdoor MrHaroldA » 26 Okt 2017, 23:07

MrHaroldA schreef:
nicoverduin schreef:Ik zou eens naar die union kijken. Dan heb je hem gelijk.


Die gaat nog even boven mijn pet. Wat voor voordeel gaat me dat geven?


Zo te lezen kan ik daar eventueel de individuele bytes van een long mee uitlezen; dezelfde inhoud, maar een andere representatie dus.

Code: Alles selecteren
union parameter {
    char b[4];
    uint32_t f;
};

const parameter P_EDIT = {0x7F, 0x00, 0x00, 0x01};


Ik denk dat ik het op mijn eerdere array van long's ga houden ... scheelt ook complexiteit in pointers en zo; alleen even netjes de individuele bytes uit kunnen halen om te kunnen versturen via USB.

Gebruikers-avatar
Berichten: 1859
Geregistreerd: 06 Aug 2016, 01:03

Re: Een const array van const arrays?

Berichtdoor Koepel » 27 Okt 2017, 12:57

Dit is reuze grappig :lol: Er zijn namelijk heel veel manieren om dit te doen. Wij weten elk een paar goede oplossingen en bij elkaar zijn er misschien wel meer dan 10 goede oplossingen.

Ik zou zelf grote blokken gegevens als PROGMEM opslaan in flash geheugen (naast de code).
Maar let op, de Arduino kan geen data lezen van flash. Dat kan alleen met een speciale functie.
PROGMEM: https://www.arduino.cc/en/Reference/PROGMEM.
Nick Gammon: http://www.gammon.com.au/progmem.

De vier byte passen in een uint32_t. In een Arduino Mega kan een pointer (met groot PROGMEM blok) ook 4 byte kosten. Dan maakt het niet meer uit of je een pointer gebruikt om meteen de data.

Voor welk Arduino board is het ?
Hoeveel van deze dingen "FX1[] = {0x60, 0x00, 0x00, 0x30}" heb je ?
Zijn het er gegarandeerd altijd minder dan 256 ?
Hoeveel arrays heb je ? Hoeveel van die FX1 dingen kunnen in zo'n array staan ?

Je zou die "FX1" dingen in een array kunnen zetten. Vervolgens de arrays met data vullen met de index (als byte) van het "FX1" array. En dan beide blokken in PROGMEM. Maar als het weinig gegevens zijn, dan is zo'n optimalisatie niet nodig.

Gebruikers-avatar
Berichten: 63
Geregistreerd: 10 Jul 2014, 14:54

Re: Een const array van const arrays?

Berichtdoor MrHaroldA » 15 Nov 2017, 23:23

Hey Koepel, Hier alsnog mijn (verlate) reactie. :roll:

Ik heb er voor gekozen de 4-byte arrays in een unsigned long op te slaan. Zo kan ik makkelijk switch cases gebruiken. Ik plaats ze wel als kopie in een array, dus ben wel 2x zoveel geheugen kwijt, maar in mijn geval is dat nu "maar" 16x4 bytes. Dat is natuurlijk relatief altijd veel, maar ik kan het nu nog wel missen ;)

Hier is een mooi voorbeeld van ik het nu in mijn MS-3 library opgelost heb: https://github.com/MrHaroldA/MS3/blob/m ... _state.ino

Als er een oplossing is die minder geheugen gebruikt ben ik altijd geïnteresseerd! Makkelijker gaat het echter niet worden ;)

Gebruikers-avatar
Berichten: 1859
Geregistreerd: 06 Aug 2016, 01:03

Re: Een const array van const arrays?

Berichtdoor Koepel » 16 Nov 2017, 01:04

Er zijn heel veel manieren om minder geheugen te gebruiken. Dan gaat het om data die PROGMEM gebruikt en geen ram meer gebruikt. Maar het is maar 13*4 = 52 byte. Dat is de moeite niet. Wanneer het 520 of 5200 of 52000 bytes zijn, dan vraag je nog maar eens ;)

Je mag gerust een beetje reclame maken voor jezelf hoor, dat is geen probleem: https://tank86.com/

Kijk eens naar je sketch. Dan valt er iets op.
Je hebt niet alleen de nummers "P_FX1 = 0x60000030", maar ook tekst daar aan gekoppeld "case P_FX1: Serial.print(F("FX1: "))".
Die koppeling doe je code, maar dat hoort natuurlijk een koppeling als data te zijn.

Je zou dus die nummers en die tekst bij elkaar in een pakketje kunnen stoppen, dus er een 'struct' van maken.
Code: Alles selecteren
struct myDataStruct
{
  uint32_t number;
  char text[7];
};

const myDataStruct myData[] PROGMEM =
{
  { 0x60000030, "FX1:  " },
  { 0x60000430, "MOD1: " },
  ...
}


Tot zover staan alle gegevens in flash en gebruikt nog geen ram.
Om ze er uit te halen heb dan wel een pgm_read... functie nodig.

Ik denk als een programmeur, maar ik heb dan weer nog nooit gitaar gespeeld :geek: :(

De PROGMEM is trouwens voor de good old Arduino Uno en andere Arduino boards met een microcontroller van de AVR familie.
De nieuwere Arduino Due, Arduino Zero en Arduino M0 hebben een ARM SAMD processor, dan is het voldoende om 'const' te gebruiken en is PROGMEM helemaal overbodig.

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 2 gasten