Variable Variable geht so was?

Hallo miteinander,

habe da mal eine Doofe Frage kann man beim Arduino Code eine Variable Variable erstellen?

ich habe mir ein Kleines Muster erstellt:

int    Taster       = 23;        // hier ist ein taster angeschloßen
int    Arduino_Pin  = 22;        // Echter Pin auf dem Arduino Mega Bord
String Port         = "A";       // Port für den Arduino Pin 
String Register_bit = "PA0";     // Bezeichnung des register Bit`s des Arduino`s Pin


void setup() 
  {
    Serial.begin(9600);                  // Serielle Schnittstellen geschwindigkeit
    pinMode(Arduino_Pin, INPUT);         // Arduino Pin Zustand zuweisen 
    pinMode(Taster, INPUT);              // Arduino Pin Zustand zuweisen 
  }
  
void loop()
  {
    Serial.print("Arduino PIN = ");
    Serial.println(Arduino_Pin);
    Serial.print("Hat den Port = ");
    Serial.println(Port);
    Serial.print("Und das Register Bit = ");
    Serial.println(Register_bit);

    Serial.print("Der Aktuelle wert ist = ");
    Serial.println( PINA & (1<<PA0));      
    
    while (digitalRead(Taster) == LOW) {}    // Warten bis eine taste gedrückt wirde damit man auch was Lesen kann auf auf der Ausgabe
  }

das Klappt auch alles so wie ich es mir vorstelle, und das beste ist es kommt auch das Ergebnis was ich erwarte :D.

SO jetzt aber zu meiner Frage, ich möchte an der Stelle:

Serial.println( PINA & (1<<PA0));

gerne die Variablen von Oben verwenden:
also so ungefähr:

Serial.println( PIN+Port & (1<<Register_bit));

ich möchte da eine Funktion erstellen und in die möchte ich die Variablen Port & Register_bit übergeben,
doch dazu muss ich dann auch darauf so zugreifen können.

Daher meine Frage ist das Möglich? so ein vorhaben?
ich wies das es so was im PHP existiert, ich wies aber auch das nur weil etwas in einer anderen Sprache Existiert das hier nicht so sein muss, daher bitte ich um Hilfe.
habe keinen Plan nach was ich suchen soll, oder wie ich da weiter kommen könnte.

Gruß
Mücke

Die einfache Antwort ist : "Nein"

Die komplizierte Antwort wird dir nicht gefallen.

Nein ist nicht sonderlich Komplex ... zumindest nicht für mich.
wenn es nicht machbar ist dann ist das so.

Schade. muss ich mit leben.

Danke dennoch.

Ich hatte bei meinem Projekt so ziemlich das selbe Problem.
Ich hab das dann mit einem Array gelöst.
Ich hab aus

schuetze_a[] = { 0, 0, 0, 0, 0, 0, 0, 0 }

schuetzte_welcher[1];

hab ich

schuetze[][8] = {
  { 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0 }}
schuetzte_welcher = 0;

schuetze[schuetze_welcher][5];

gemacht.
Vllt. kannst du so ja an die Lösung rangehen?

LG

Fipsi

michael_x:
Die komplizierte Antwort wird dir nicht gefallen.

Makros konkatenieren?

Hmm, das mit dem Array verstehe ich glaube ich nicht ganz richtig,
bzw. sagen wir so, ich habe keine Ahnung was du mit dem Code da machst, aber ich verstehe die heran Gehens weise. und kann mir daraus was Basteln.

oder?? ne ;( ich glaube ich habe einen Denkfehler. hmm, .... arrrrr.... ne das ist nicht das richtige glaube ich für mich.

Makros konkatenieren?

hmm das hört sich gut an, jedoch glaube ich das das nicht so leicht für mich ist, ich wies was "konkatenieren" ist jedoch habe ich keinen Plan was ein Makro auf einem Arduino ist, ich kenne nur ein Makro aus dem MS Excel und da versteh ich schon den Inhalt mal zu 100% nicht.

bleibt wohl doch beim NEIN

Also dann noch mal zur Erklärung wegen meinem^^:

Ich habe 4 Schützen. Jeder Schütze kann bis zu 6 Pfeile haben. Dazu die zwei innersten Ringe zusammen gezählt. Ergibt 8 Variablen. Es können sozusagen zu jeder Zeit alle 4 Schützen ihre Pfeile eingeben. Deswegen hab ich ein Array schuetze_welche. 1 = A, 2 = B, 3 = C, 4 = D. Zugewiesen wird das über je eine Taste um mein Display. Zudem wird ein Pfeil nach dem anderen geschrieben. Damit ich weiß, welcher Pfeile geschrieben wird, hab ich den Array schuetze_schreiben_ringe. Hier steht der Index 0 für den Schützen A, Index 1 für den Schützen B, usw
(

 schuetze_schreiben_ringe[schuetze_welcher -1] = stelle;

)
Wenn ich jetzt einen neuen Pfeil aufschreib, hab ich diesen Code:

int ringe[][8] =  { { 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0 }};
int schuetze_welcher = 1;
int schuetze_schreiben_ringe[4] = { 1, 1, 1, 1 };

void loop()
{
  if (bla)
  {
    ringe[schuetze_welcher - 1][schuetze_schreiben_ringe[schuetze_welcher -1]] = ring;
  }
}

Das nur bisschen vereinfacht zur Erklärung, falls du mit dem ganzen Code besser zurecht kommst:

int write_schuetze = 1;
int write_schuetze_ring[] = { 1, 1, 1, 1 };

unsigned char ringe[][8] = { 
  { 0, 0, 0, 0, 0, 0, 0, 0 },  // Schütze A
  { 0, 0, 0, 0, 0, 0, 0, 0 },  // Schütze B
  { 0, 0, 0, 0, 0, 0, 0, 0 },  // Schütze C
  { 0, 0, 0, 0, 0, 0, 0, 0 }}; // Schütze D
int ergebnisse[4] = { 0, 0, 0, 0 };

  char key = kpd.getKey();
  if ((key) && ((do_status == 1) || (do_status == 5)))
  {
    switch(key)
    {
    case 'A':
      if (schuetze_1_da == 1)
        write_schuetze = 1;
      display_new = 1;
      break;
     case 'B':
      if (schuetze_2_da == 1)
        write_schuetze = 2;
      display_new = 1;
      break;
     case 'C':
      if (schuetze_3_da == 1)
        write_schuetze = 3;
      display_new = 1;
      break;
     case 'D':
      if (schuetze_4_da == 1)
        write_schuetze = 4;
      display_new = 1;
      break;

    case 'R':
      display_status = 4;
      break;
     case 'M':
      CountRingWriter('M');
      display_new = 1;
      break;
     case 'X':
      if (gibt_x == 1)
      {
        CountRingWriter('M');
        display_new = 1;
      }
      break;

     case 'Cl':
      if (write_schuetze_ring[write_schuetze - 1] > 1)
        write_schuetze_ring[write_schuetze - 1] -= 1;
      display_new = 1;
      break;
  }

  if ((key >= 1) && (key <= 10))
  {
    CountRingWriter(key);
    display_new = 1;
  }

void CountRingWriter(char ring)
{
  int ring_ = 0;
  if ((ring >= 1) && (ring <= 10))
  {
    ring_ = ring;
  }
  else if (ring == 'M')
  {
    ring_ = 0;
  }
  else if (ring == 'X')
  {
    ring_ = 10;
  }

  ringe[write_schuetze - 1][write_schuetze_ring[write_schuetze - 1] + 1] = ring;
  ergebnisse[write_schuetze - 1] += ring_;
  if (gibt_x == 1)
  {
    if (ring == 'X')
      ringe[write_schuetze - 1][0] += 1;
    if (ring == 10)
      ringe[write_schuetze - 1][1] += 1;
  }
  else if (gibt_x == 0)
  {
    if (ring == 10)
      ringe[write_schuetze - 1][0] += 1;
    if (ring == 9)
      ringe[write_schuetze - 1][1] += 1;
  }

  if (write_schuetze_ring[write_schuetze - 1] + 1 <= anzahl_pfeile)
    write_schuetze_ring[write_schuetze - 1] += 1;
}

Ich weiß, ich hab jetzt hier die Variablen ein wenig anders benannt und ringe ist bei mir ein char, weil ich auch Buchstaben brauch.

LG

Fipsi

soweit schon klar,

ich schreibe nur nichts in die Variable, "PINA" bzw. "PIN+Port" sondern lese den zustand eines PIN`s am Arduino aus.

daher weis ich gerade nicht wie mir das weiter helfen soll, sorry ich komme da nicht ganz mit :frowning:

Achso, jetzt versteh ich, was du meinst.
Sorry, das hatte ich dann falsch verstanden.
Da kann ich dir dann auch nicht helfen, sorry :X

LG

Fipsi

Sowas?

uint8_t read_port(uint8_t pin, uint8_t bit)
{
	if(pin & (1<<bit)) return 1;
	else return 0;
}

Serial.print(read_port(PINA, 1);

Alternativ, wobei auch besser,

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)

for(int i = 0; i < 8; i++)
{
	uart_putc(bitRead(PIND, i)+'0');
}

bitRead müsste in der IDE bereits integriert sein. Ansonsten wie oben defenieren.

Ich glaube, Muecke möchte zur Laufzeit einen Text, der den Inhalt "PORTB" hat, hernehmen und daraus den Wert von PORTB bilden.

Wenn der Text den Inhalt "PORTC" hat, soll der Wert von PORTC genommen werden.

Und bei "Zaehler" den Inhalt der Variable Zaehler, falls es so eine gibt.

Und der DatenTyp der Variable soll egal sein.
Und falls es die Variable nicht gibt, soll nichts Schlimmes passieren.

Ich könnte mir Objekte vorstellen die, als String verwendet, ihren Namen liefern, und ansonsten einen Wert.
Aber in der Praxis hat da keiner was von, und ist nur kompliziert.
Und so ganz ist das auch nicht das, was Muecke will.

Makros und Funktionen zur Bitmanipulation haben wir schon. Das ist zu einfach :wink:

das von sschultewolter, muss ich in ruhe durchgehen, da komm ich mal wider nicht ganz mit, ist aber nicht schlimm, ich habe ja zeit mich einzuarbeiten :slight_smile:

michael_x, bei mir geht es immer noch um die Schieblehre ;D, da ich die Bestellung der Schieblehre noch nicht fertig habe, dachte ich mir das ich mir eine Funktion baue mit der ich Später die Schieblehre bequem abfragen kann.

Da ich 5 Schieblehre verwenden möchte und jede zwei Pin`s belegt macht das bei mir 10 Pins, da ich pro Port immer nur 8Pins auf ein mal ansprechen / abfragen / Sätzen kann muss ich einen zweiten Port einbeziehen,

aus dem Grunde möchte ich das Port Register zusammen Sätzen lassen aus einem Text und einer Variablen.

denn ein mal arbeite ich mit dem Port A und wahrscheinlich mit PORT C wenn ich das richtig gelesen habe.

und ich dachte an eine Funktion z.B.

Schieber(PIN_Arduino, Port, Register_bit)

also Antwort bekomme ich dann was aktuell auf dem Schieber stand / steht

doch so einfach scheint das nicht zu sein. :zipper_mouth_face:

Man kann beim Compilieren Text zusammenfügen:

Oder auf Deutsch Punkt 10.10. hier:
http://public.beuth-hochschule.de/~kempfer/skript_c/Kap10.html

Dafür ist der ## des Präprozessors da. Damit kann man auch die Namen von richtigen Variablen zusammensetzen (nicht nur ein anderes Makro wie PORTC).

Würde ich Mücke aber nicht empfehlen, da er sich damit nicht wirklich auskennt. Und die Fehler die bei Makros ausgespuckt werden können wenn die Syntax nicht korrekt ist sind meistens noch kryptischer als normal.

Nur noch so nebenbei um das Thema zu vervollständigen.

#define Schieber(Port, Register_bit) \
  (PIN##Port & (1<<Register_bit))

uint8_t test = Schieber(B, PB0);

Das ## dient im Makro als Verbindung zwischen zwei Variablen, sprich man kann damit variable Variablen für den Präprozessor generieren, NICHT im laufenden Programm.
Sobald man nun aber seine Makros geschickt definiert, lassen sich auch Schleifen mit einer festen Zahl N definieren und Quellcode geschickt generieren.

@Serenifly
Mist, nun hab ich den ganzen Tag gearbeitet und gehofftmeine Antwort hier schreiben zu können, sobald ich Zuhause bin und du klaust mir 3 Minute zuvor davor die Antwort ... :wink:

hmm, ja ne ist klar, ...

irgend wie habe ich mich mit der Antwort von michael_x --> NEIN, schon abgefunden.

hmm, ...

Danke euch allen die mir hier antworten doch irgend wie ist das gerade etwas zu viel für mich, ...
vielleicht komme ich da irgend wann mal wider drauf zurück, ..

Hab ich beim Stichwort "Variable Variable" zu kompliziert gedacht.

Ich weiss zwar nicht, was an den Schieblehren so schnell ist, dass man einen Vorteil von
direkter Port-Adressierung hat anstelle von Arduino Pin - Nummern.
Das hat, glaub ich, Doc nur aus Spass im reply#90 eingeführt

Aber die Makro - Geschichte von Jomelo / Serenifly / SSchultewolter solltest du dir angucken, ausprobieren, insbesondere wenn du eh LangeweileZeit hast bis die Dinger ankommen.

Viel Spaß

ich gehe mal davon aus das die Frequenz zwischen low und high zu schnell ist.

ich muss erst mal raus finden was ein Makro auf dem Arduino ist. :roll_eyes:

und dann kann ich glaube ich weiter schauen.

Danke Serenifly,

habe mir das jetzt alles durchgelesen und zwischen drin habe ich gedacht ich habe verstanden was was ein Makro ist, doch dann wider nicht, ...

habe ich das Richtig verstanden?

wenn ich "#define ...." schreibe dann Sage ich das ich ein Makro habe?
oder hat ein Makro immer # als erstes zielen zeichne vorne dran stehen?

Ja, aber ob du dazu jetzt "Makro" oder was anderes sagst ist erst mal nicht so wichtig

Du musst verstehen was gemacht wird. Bei den ganzen Prä-Prozessor Befehlen handelt es sich um Text-Ersetzungen vor dem Kompilieren.

Wenn du #define x y schreibst, wird x durch y ersetzt. Das sind keine Variablen! Das Programm ersetzt einfach stur den Text und versucht das danach zu kompilieren.
Ähnlich kann mit ## Text-Teile aneinanderhängen.

zeigt dir das sich um einen Prä-Prozessor Befehl handelt. Da gibt es nicht nur Makros, sondern eine ganze Reihe Sachen:

http://public.beuth-hochschule.de/~kempfer/skript_c/Kap10.html
#include kennst du da schon
#if oder #ifdef ist dir vielleicht auch schonmal irgendwo über den Weg gelaufen