aktuell definierten pinmode eines pins abfragen?

hallo, gibt es eine Möglichkeit, den aktuell definierten pinmode eines pins abzufragen? in der Art

byte mypinMode(byte mypin) {
  //..?..
}


byte bitval;
If(mypinMode(digiPin[i])==OUTPUT) {bitval=digitalRead(digiPin[i]); }

Man kann das entsprechende DDRn (Data Direction) Register auslesen und davon das entsprechende Bit: http://www.arduino.cc/en/Reference/PortManipulation

Dann arbeitet man aber nicht mehr mit den Arduino Pin Nummern, sondern mit den Bezeichnungen des Prozessors.

hallo,
danke, das ging ja super schnell! :slight_smile:

Also muss ich DDRD und DDRB abfragen
meinst es geht so in dieser Art (ausführliche Version):

#define PinModeIN  0
#define PinModeOUT 1

byte mypinMode(byte mypinnumber) {
  byte bitbyte=-1, value=-1;  // undefined
  bitbyte=1<<mypinnumber;
  value=bitbyte&DDRD;   // pins 0..7
  if(value==1) return PinModeOUT;
  else return PinModeIN;
}

klappt irgendwie nicht, gibt immer nur 0 aus.
Denkfehler?

/
#include <Wire.h>       

#define NOPIN     129  // void pin address

//*************************************************************************

byte digiPin[16];      // stores 16 digital pin numbers to be polled

void setup()
{   
  // default settings  
  byte digiPin[16];      // stores 16 digital pin numbers to be polled
  
  pinMode(digiPin[ 0],  OUTPUT);
  pinMode(digiPin[ 1],  INPUT);
  pinMode(digiPin[ 2],  OUTPUT);
  pinMode(digiPin[ 3],  INPUT);
  pinMode(digiPin[ 4],  OUTPUT);
  pinMode(digiPin[ 5],  INPUT);
  pinMode(digiPin[ 6],  OUTPUT);
  pinMode(digiPin[ 7],  INPUT);
  pinMode(digiPin[ 8],  OUTPUT);
  pinMode(digiPin[ 9],  INPUT);
  pinMode(digiPin[10],  OUTPUT);
  pinMode(digiPin[11],  INPUT);
  pinMode(digiPin[12],  OUTPUT);
  pinMode(digiPin[13],  INPUT);
  pinMode(digiPin[14],  OUTPUT);
  pinMode(digiPin[15],  INPUT);
  
  Serial.begin(9600);
  Serial.println("Checking pin modes...");
   

}

//*************************************************************************



//*************************************************************************

byte digiMuxByte13, digiMuxByte14; // stores all digital pin bits, 0..7, 8..15

#define PinModeIN  0
#define PinModeOUT 1

byte mypinMode(byte mypinnumber) {
  byte bitbyte=-1, value=-1;          // undefined
  bitbyte=1<<mypinnumber;
  value=bitbyte&DDRD;                 // pins 0..7
  if(value==1) {return PinModeOUT;}
  else {return PinModeIN;}
}

void MuxDigiPins() {
   byte i, bpattern, bitval;
   
   for(i=0;i<8;++i) {
 
        Serial.print(i);
        Serial.print("= ");
        Serial.print(mypinMode(i));
        Serial.println();

   }  
}


//*************************************************************************

void loop()
{
  int value;
    
  MuxDigiPins();

  while(1);
}
value=bitbyte&DDRD;   // pins 0..7
if(value==1) ....

Du musst glaube ich auf >= 1 abfragen

Mal angenommen deine Bitmaske ist 0001 0000 und das entsprechende Bit ist im Register gesetzt. Dann kommt da 16 raus. Und nicht 1.

Oder frage ab ob "value == true". True ist nämlich genauso definiert. 0 ist false. Und alles unterschiedlich 0 ist true.

Du kannst auch mal value auf Serial ausgeben. Am besten binär oder hex. Dann merkst du schon was da abläuft.

Mhh, seltsam. Du kannst mal bitRead(DDRD, mypinnumber) machen.

Die Arduino IDE hat da schon ein paar Makros dafür (ist keine Funktion!): http://arduino.cc/en/Reference/BitRead

verstehe ich jetzt noch nicht, die Makros.

habs nochmal geändert - aber keine Chance:
immer null, value ist auch Null:

#include <Wire.h>       

#define NOPIN     129  // void pin address

//*************************************************************************

byte digiPin[16];      // stores 16 digital pin numbers to be polled

void setup()
{   
  // default settings  
  byte digiPin[16];      // stores 16 digital pin numbers to be polled
  
  pinMode(digiPin[ 0],  OUTPUT);
  pinMode(digiPin[ 1],  INPUT);
  pinMode(digiPin[ 2],  OUTPUT);
  pinMode(digiPin[ 3],  INPUT);
  pinMode(digiPin[ 4],  OUTPUT);
  pinMode(digiPin[ 5],  INPUT);
  pinMode(digiPin[ 6],  OUTPUT);
  pinMode(digiPin[ 7],  INPUT);
  pinMode(digiPin[ 8],  OUTPUT);
  pinMode(digiPin[ 9],  INPUT);
  pinMode(digiPin[10],  OUTPUT);
  pinMode(digiPin[11],  INPUT);
  pinMode(digiPin[12],  OUTPUT);
  pinMode(digiPin[13],  INPUT);
  pinMode(digiPin[14],  OUTPUT);
  pinMode(digiPin[15],  INPUT);
  
  Serial.begin(9600);
  Serial.println("Checking pin modes...");
   

}

//*************************************************************************



//*************************************************************************

byte digiMuxByte13, digiMuxByte14; // stores all digital pin bits, 0..7, 8..15

#define PinModeIN  0
#define PinModeOUT 1

byte mypinMode(byte mypinnumber) {
  byte bitbyte=-1, value=-1;          // undefined
  bitbyte=1<<mypinnumber;
  value=bitbyte&DDRD;                 // pins 0..7
  Serial.println(value);
  if(value>=1) {return PinModeOUT;}
  else {return PinModeIN;}
}

void MuxDigiPins() {
   byte i, bpattern, bitval;
   
   for(i=0;i<8;++i) {
 
        Serial.print(i);
        Serial.print("= ");
        Serial.print(mypinMode(i));
        Serial.println();

   }  
}


//*************************************************************************

void loop()
{
  int value;
    
  MuxDigiPins();

  while(1);
}

Hallo HaWe,

der setup bringt so nichts! Du möchtest dort mit pinMode die entsprechenden Pins als Aus- bzw. Eingang deklarieren, jedoch sollte dir hier bewusst sein, dass deine Werte aus dem Array digiPin alle 0 sind! Es müssen schon andere Werte ausser 0 drinstehen ;)

ARG! Jetzt siehe ich es auch :slight_smile: Eigentlich offensichtlich.

Man könnte das auch einer for-Schleife machen:

for(int i = 0; i <= 13; i++)
{
     if(i % 2 == 0)
        pinMode(i, OUTPUT);
     else
         pinMode(i, INPUT);
}

Wobei man da eigentlich erst bei 2 anfangen sollte, da die serielle Schnittstelle auf 0 und 1 verwendet wird. Oder wenigstens 1 (TX) weglassen

jo, ich glaub da habt ihr Recht... :blush:

klappt, danke an euch :slight_smile:

#include <Wire.h>       

#define NOPIN     129  // void pin address

//*************************************************************************

void setup()
{   
  // default settings  
 
  pinMode( 0,  INPUT);   // TX
  pinMode( 1,  INPUT);   // RX
  pinMode( 2,  INPUT);
  pinMode( 3,  OUTPUT);  // pwm
  pinMode( 4,  INPUT);
  pinMode( 5,  OUTPUT);  // pwm
  pinMode( 6,  OUTPUT);  // pwm
  pinMode( 7,  INPUT);
  pinMode( 8,  INPUT);
  pinMode( 9,  OUTPUT);  // pwm
  pinMode(10,  OUTPUT);  // pwm
  pinMode(11,  OUTPUT);  // pwm
  pinMode(12,  INPUT);
  pinMode(13,  OUTPUT);  // LED internal
  pinMode(14,  INPUT);   // NOPIN
  pinMode(15,  INPUT);   // NOPIN
  
  Serial.begin(9600);
  Serial.println("Checking pin modes...");
   

}

//*************************************************************************



//*************************************************************************

byte digiMuxByte13, digiMuxByte14; // stores all digital pin bits, 0..7, 8..15

#define PinModeIN  0
#define PinModeOUT 1

byte mypinMode(byte mypinnumber) {
   if(mypinnumber<8)  
    return ((DDRD & (1<<mypinnumber))!=0);
  else     
    return ((DDRB & (1<<(mypinnumber-8)))!=0);
}


void MuxDigiPins() {
   byte i, bpattern, bitval;
   
   for(i=0;i<16;++i) {
 
        Serial.print(i);
        Serial.print("= ");
        Serial.print(mypinMode(i));
        Serial.println();

   }  
}


//*************************************************************************

void loop()
{
  int value;
    
  MuxDigiPins();

  while(1);
}

kurze Anschlussfrage:
darf man während der Laufzeit die Einstellungen INPUT vs. OUTPUT beliebig ändern oder gibt das errors?

Theoretisch kann man das beliebig umschalten. Du musst natürlich aufpassen was extern dran hängt. Wenn von außen Spannung anliegt ist es z.B. tödlich einen Pin auf OUTPUT, LOW zu schalten.

Und das hier sind die Analog-Pins A0 und A1:

  pinMode(14,  INPUT);   // NOPIN
  pinMode(15,  INPUT);   // NOPIN

o, danke, das war wichtig !

wen es interessiert:
habe jetzt auch die Funktionen geschrieben, um einzelne Bits in Bytes auf 0 oder 1 zu setzen und entsprechend auszulesen:

//*************************************************************************

byte SetByteBit(byte source, byte bitval, byte bitnr) {
  source &= ~( 1 << bitnr) ;                // clear single bitval at pos bitnr
  source |= bitval << bitnr;                // set bitval to 0 or 1	 
  return source;
}

byte GetByteBit(byte source, byte bitnr) {  
  return (source & (1 << bitnr) ) != 0;     // read bitval at pos bitnr  
  
}

//*************************************************************************

share and enjoy! :sunglasses:

HaWe: habe jetzt auch die [u]Funktionen[/u] geschrieben, um einzelne Bits in Bytes auf 0 oder 1 zu setzen und entsprechend auszulesen: share and enjoy! 8-)

Schön für dich,ehrlich! 8) Generell ist es aber besser, bereits vorhandene Funktionen zu nutzen: http://arduino.cc/en/Reference/BitWrite etc.

widerspreche ich!
woher nimmst du die Überheblichkeit, behaupten zu wollen, es wäre “generell besser”?
erstens ist nicht auf den ersten Blick ersichtlich, was da genau passiert,
und zweitens ist die verlinkte Version wohl ein Makro, keine Funktion - d.h. es können weniger universell auch z.B. Funktionen und Bezeichner als Parameter eingesetzt werden.

woher nimmst du die Überheblichkeit, behaupten zu wollen, es wäre “generell besser”?

Kein Problem Überheblichkeit hervorzukramen, die hab ich griffbereit :wink: :wink: :stuck_out_tongue:
Mit “generell” meine ich übrigens “im Allgemeinen”, nicht “unter allen Umständen”.

Ein Makro ist übrigens auch “generell besser” als eine Funktion, wenn man nicht auf z.B. Datentypsicherheit als relevanten Vorteil Wert legt, in der Funktion auch keine Fehlerprüfung drin hat, und eher auf kleinen RAM und Geschwindigkeit, als auf kleinen Flash-Speicherbedarf optimiert.

Wenn dir bewusst ist, dass du das Rad neu erfunden hast, kannst du ja die Vorzüge deiner Erfindung gegenüber dem Standard erwähnen. Dass dir das bewusst war, konnte ich deinem Post nicht entnehmen, sorry.

es können weniger universell auch z.B. Funktionen und Bezeichner als Parameter eingesetzt werden.

Das “weniger universell” verstehe ich vermutlich nicht …
Sowohl in deiner Funktion wie in den Arduino-Makros können die Parameter Konstante, Variable und Funktionsaufrufe bzw. deren Ergebnisse sein.
Bei dir müssen sie als byte darstellbar sein, beim Arduino kann man auch in einem long einzelne Bits lesen oder setzen.

michael_x: Ein Makro ist übrigens auch "generell besser" als eine Funktion, wenn man nicht auf z.B. Datentypsicherheit als relevanten Vorteil Wert legt

Wobei man mit inline Funktionen die Vorteile von beiden kombinieren kann :)

Wobei man mit inline Funktionen die Vorteile von beiden kombinieren kann

Auch Richtig! ;)

Nochmal Widerspruch, Euer Ehren! 8-) bei Inline Funktionen sind die Datentypen ebenfalls festgelegt, wie bei "normalen" Funktionen, also eigentlich kein Vorteil.

Ein Vorteil wäre in beiden Fällen die Thread-Sicherheit bei MT-Zugriff (entfällt bei Arduinos), das umgehe ich aber in diesen anderen Umgebungen durch Mutexe, aber der größte Nachteil ist aus meiner Sicht, bei begrenztem Programmspeicher wie bei allen Arduinos vom Uno bis zum Due: wenn ich beide Funktionen in meinem Programm je 50x getrennt aufrufe, habe ich sie bei Makros und inline Funktionen je 50x in meinem Code stehen, bei "normalen" Funktionen aber nur 1x.

Aber das ist hier sicher etwas off-topic... :roll_eyes: