Dynamiska variabler Arduino

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
FormerMazda
Inlägg: 6076
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Dynamiska variabler Arduino

Inlägg av FormerMazda »

I brist på bättre rubrik..

Knåpar lite program till Arduinon, skulle vilja snygga till koden genom att rulla igenom varibler med for-loopar.

Typ:
Jag har 6 variabler som håller pin-nummer.
int pinEnN1 = 53; //Hög = Enable
int pinEnN2 = 51;
int pinEnN3 = 49;
int pinEnN4 = 47;
int pinEnN5 = 45;
int pinEnN6 = 43;

När jag sen i kod ska sätta alla pinnar låga till exempel så är det lite drygt att ha sex rader med unika digitalWrite.
En enkel for-loop som bygger varibelnamnet hade ju varit fiffigare. I mitt normala språk jag sitter i (CiCode) är detta rätt enkelt. (allt är enkelt när man kan det förvisso)
Men till Arduino går inte detta?

Är enda lösningen en array?
int pinEnN[7] = {0, 53, 51, 49, 47, 45, 43};
Corax, why?
Inlägg: 31
Blev medlem: 5 februari 2020, 18:37:59

Re: Dynamiska variabler Arduino

Inlägg av Corax, why? »

enum?

Om jag istället förstår vad du vill göra, så om det är C du programmerar finns det ingen snygg lösning som inte tar tid under körning (vilket kan vara en helt ok uppoffring beroende på sammanhang).

Det finns extremt komplicerade header-libraries som låter dig skriva koden i preprocessormakron om du vill att expansionen ska ske compile-time, inget som rekommenderas dock för det slutar bara i kaos att använda sådana bibliotek.

Gör en funktion istället, och sätt den som inline om kompilatorn stödjer det.

#define pineEnN1 (53)
#define pineEnN2 (51)

inline void setMyPins(bool logicLevel)
{
digitalWrite(pinEnN1, logicLevel);
digitalWrite(pinEnN2, logicLevel);
// osv
digitalWrite(pinEnSomHarInverteradLogikN3, !logicLevel);
// osv
}

jag reserverar mig för att jag inte kör arduino och inte har testat någon kod, vill bara illustrera principen
Användarvisningsbild
Gorgus
Inlägg: 1998
Blev medlem: 24 april 2006, 22:42:42
Ort: Eskilstuna
Kontakt:

Re: Dynamiska variabler Arduino

Inlägg av Gorgus »

Jag hade nog valt en array, verkar vara enklast.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Dynamiska variabler Arduino

Inlägg av sodjan »

Pin parametern i digitalWrite funktionen kan väl kunna vara en variabel i run-time?
Bara att loopa igenom din pinEnN array och köra digitalWrite på varje värde.

Du borde kunna definiera arrayen som:

int pinEnN[7] = {pinEnN1, pinEnN2, pinEnN3, pinEnN4, pinEnN5, pinEnN6, pinEnN7};

Så behöver du inte skriva pin-numren mer på mer än ett ställe...
FormerMazda
Inlägg: 6076
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Dynamiska variabler Arduino

Inlägg av FormerMazda »

Det lutar åt detta, särskilt ju mer jag googlar.

Så i sin enkelhet:

Kod: Markera allt

int pinEnN[7] = {0, 53, 51, 49, 47, 45, 43};

for (int i = 1; i <= 6; i++) {
    digitalWrite(pinEnN[i], LOW);
  }
Då jag vill ha namnen från 1 till 6 så behöver jag ju finta bort nollan så att säga.
Därav deklarationen och for-loopens start på 1.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Dynamiska variabler Arduino

Inlägg av sodjan »

Eller (om du även vill använda varje pinne för sig):

Kod: Markera allt

int pinEnN1 = 53;
int pinEnN2 = 51;
int pinEnN3 = 49;
int pinEnN4 = 47;
int pinEnN5 = 45;
int pinEnN6 = 43;

int pinEnN[7] = {0, pinEnN1, pinEnN2, pinEnN3, pinEnN4, pinEnN5, pinEnN6};

for (int i = 1; i <= 6; i++) {
    digitalWrite(pinEnN[i], LOW);
  }
Fast du kan ju även använda t.ex. pinEnE(3) i koden istället för pinEnN3...
Det kan bero på annat som inte är känt vilket som är mest praktiskt...
FormerMazda
Inlägg: 6076
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Dynamiska variabler Arduino

Inlägg av FormerMazda »

Huruvida jag skriver pinEnN3 eller pinEnN(3) senare i kod spelar mig mindre roll.
Enklast är att fortsätta med arrayen gissar jag, så pinEnN(3) i kommande kod.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Dynamiska variabler Arduino

Inlägg av sodjan »

Frågan är hur koden optimeras. Kommer pinEnN(3) att kompileras till
en uppslagning i arrayen? Beror kanske på om den anses som "static"
eller inte. Om den är static så borde kompilatorn kunna slå upp värdet.
Men det kan vara att pinEnN3 är snabbare...
FormerMazda
Inlägg: 6076
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Dynamiska variabler Arduino

Inlägg av FormerMazda »

Beträffande optimering så är jag ju en sån där förtappad själ som förvisso förstår vitsen med assembler men som trivs för bra med högnivåspråk och förlitar mig på hårdvaran istället.
I detta fallet är det till min nixie-klocka, så jag behöver nog ingen särskilt bra optimering på koden.

Men frågan är intressant ändå!
hummel
Inlägg: 2267
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Dynamiska variabler Arduino

Inlägg av hummel »

FormerMazda skrev: 6 augusti 2020, 15:38:44 Det lutar åt detta, särskilt ju mer jag googlar.

Så i sin enkelhet:

Kod: Markera allt

int pinEnN[7] = {0, 53, 51, 49, 47, 45, 43};

for (int i = 1; i <= 6; i++) {
    digitalWrite(pinEnN[i], LOW);
  }
Då jag vill ha namnen från 1 till 6 så behöver jag ju finta bort nollan så att säga.
Därav deklarationen och for-loopens start på 1.
Om du vill indexera från 1 till 6:

Kod: Markera allt

int pinEnN[6] = {53, 51, 49, 47, 45, 43};

for (int i = 1; i <= 6; i++) {
    digitalWrite(pinEnN[i- 1], LOW);
  }
  
Senast redigerad av hummel 6 augusti 2020, 20:43:50, redigerad totalt 1 gång.
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Re: Dynamiska variabler Arduino

Inlägg av arvidb »

Eller kanske ännu hellre:

Kod: Markera allt

#define ENN_PINS 6
int pinEnN[ENN_PINS] = {53, 51, 49, 47, 45, 43};

for (int i = 0; i < ENN_PINS; i++) {
    digitalWrite(pinEnN[i], LOW);
}
Användarvisningsbild
ffredrik
Inlägg: 341
Blev medlem: 20 oktober 2009, 17:52:18
Ort: Göinge

Re: Dynamiska variabler Arduino

Inlägg av ffredrik »

arvidb:s förslag är det enda acceptabla hittills med tanke på gängse regler o normer avseende C-programmering. :tumupp:
FormerMazda
Inlägg: 6076
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Dynamiska variabler Arduino

Inlägg av FormerMazda »

Att jag vill bryta mot lagen är för jag i just detta exempel har 6st IC vars enable ska styras.
Och då dessa 6 IC styr varsitt av rören som jag numrerat 1-6 så är det enklast för mig om variabeln motsvarar det faktiska röret den styr.

Så nej, det är inte snyggt som jag skriver, men logisk.

Men för kunskaps skull, varför är det bättre att skriva #define ENN_PINS 6 istället för att skriva 6 direkt i pinEnN?
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Dynamiska variabler Arduino

Inlägg av Mr Andersson »

> Men för kunskaps skull, varför är det bättre att skriva #define ENN_PINS 6 istället för att skriva 6 direkt i pinEnN?

Det är det inte, bägge är lika dåliga och kräver att du hela tiden kommer ihåg att uppdatera längden om du ändrar arrayen.

Kod: Markera allt

constexpr int pins[] = {53, 51, 49, 47, 45, 43};
for (auto pin : pins) {
    digitalWrite(pin, LOW);
}
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Re: Dynamiska variabler Arduino

Inlägg av arvidb »

FormerMazda skrev: 6 augusti 2020, 20:11:06 Men för kunskaps skull, varför är det bättre att skriva #define ENN_PINS 6 istället för att skriva 6 direkt i pinEnN?
Två saker: dels får du en naturlig dokumentation över vad sexan står för, men kanske viktigare är att det hindrar dig från att glömma att sexan faktiskt står på (minst) två ställen, som alltid måste ändas tillsammans. Du vill inte iterera utanför arrayen!

Mr Andersson: Jo visst är C bristfälligt på det sättet, men vettiga kompilatorer klagar i alla fall om du skriver in fler element än det finns plats för i deklarationen:

Kod: Markera allt

#include <stdio.h>

#define ENN_PINS 6
int pinEnN[ENN_PINS] = {53, 51, 49, 47, 45, 43, 99};

int main(void)
{
	for (int i = 0; i < ENN_PINS; i++) {
		printf("%d ", pinEnN[i]);
	}
	return 0;
}

Kod: Markera allt

$ gcc -Wall array-test.c -o array-test
array-test.c:4:49: warning: excess elements in array initializer
    4 | int pinEnN[ENN_PINS] = {53, 51, 49, 47, 45, 43, 99};
      |                                                 ^~
array-test.c:4:49: note: (near initialization for 'pinEnN')
Skriv svar