Arduino / pinMode

Hallo,

für eine Erweiterungs Karte muss ich die Pins mithilfe von PinMode im Void Loop ändern. Aber egal was ich versuche. Der Arduino weigert sich hartnäckig. Ich habe den Verdacht das PinMode im VoidLoop garnicht funktioniert. Weis da jemand was genaueres oder gibt es da einen Trick?

Gruss Turgut

hallo,
poste mal bitte deinen Code, ohne das kann man kaum was sagen, was falsch läuft.
Außerdem wären die wortwörtliche Formulierung der Anleitung und ein paar Infos über die Karte (abgetippt oder gepasted) gut.

No tricks are needed, and it works all the time.

pinMode (2, OUTPUT);  // set as output, default will be low
digitalWrite (2, HIGH);  // make output high
delay (1000);
pinMode (2, INPUT);  // set pin as input

temucin:
für eine Erweiterungs Karte muss ich die Pins mithilfe von PinMode im Void Loop ändern.

Bei welcher Erweiterungskarte?

temucin:
Aber egal was ich versuche. Der Arduino weigert sich hartnäckig.

Nein, ein Arduino-Board ist kein Revoluzzer mit Verweigerungshaltung.

temucin:
Ich habe den Verdacht das PinMode im VoidLoop garnicht funktioniert.

Falsch.

temucin:
gibt es da einen Trick?

Nein. Höchstens wenn Du den pinMode extrem schnell umschalten müßtest, oder der pinMode an mehreren Pins eines Portregisters in genau derselben Nanosekunde gleichzeitig statt nacheinander geändert werden soll, könnte man anstelle von pinMode direkt die Register des Controllers programmieren, falls Du das als "Trick" bezeichnen möchtest.

Hallo,

die Karte baue ich gerade und teste die Technischen Möglichkeiten.

/*
  Programm : I/O Verstärker
  Einen I/O als Eingang und als Ausgang
  verwenden.
  Code by Temucin LE at 2014
*/

// Programm Spezifische Variablen

String PROGRAMM = "I/O Verstärker" ;

//-------------------------------

int IO_1 = 12;           
int IO_1_Status;
int IO_1_Mode;

int led = 13;
int led_t =0;
long timer = 0;

unsigned long mil_1 =0;
unsigned long mil_2 =0;
int timer_div =0;

int inByte = 0;
String comand ;
long wert = 0;
String pars ;
int par_count;
int parstep;
String param ;
byte par1;
byte par2;
byte par3;
byte par4;
byte par5;
byte par6;
int intstep;

// the setup routine runs once when you press reset:
void setup() {                
  
  // initialize the digital pin 
  
  Serial.begin(57600);
  
  pinMode(led, OUTPUT);
  
  pinMode(IO_1, INPUT); 
  digitalWrite(IO_1,HIGH);
  IO_1_Mode=0;
  
}

// the loop routine runs over and over again forever:
void loop() {
  
  // --------------------------------------------------------------------------  
  // millis() count und überlauf prüfung, in timer_div steht die anzahl verstrichener millis
  
  mil_2 = mil_1;
  mil_1 = millis(); // da sich der überlauf der millis auch innerhalb eines loops an einer zufälligen stelle ereignen kann, wird dieser zwischen gespeichert.  
  if (mil_1<mil_2) //  das neue mil ist kleiner wie das alte, dann muss ein überlauf stadt gefunden haben
  {
    timer_div=1;
  }
  else
  {
    timer_div=mil_1-mil_2;    
  }
  
  // --------------------------------------------------------------------------  
  // Lebenslicht Blinker 
  
  if (timer>0)
  {
    timer=timer-timer_div; 
    if (timer<0) timer=0; 
  }
  if (timer==0) // Lebenslicht des Programms
  {
    timer=1000;
    
    if (led_t==0)
    {
      led_t=1;
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      //digitalWrite(IO_1, HIGH);
    }
    else
    {
      led_t=0;
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      //digitalWrite(IO_1, LOW);
    }
  }
 
  // ---------------------------------------------------------------------------
  // Serielle Komunikation
  
 
    // send data only when you receive data:
    if (Serial.available() > 0) {
      // read the incoming byte:
      comand="";
      wert=0;
      param="";
      pars="";
      inByte = Serial.read();
      
      if (inByte == 47)
      {
        delay (5);
                
        for (int x = 0 ; x<15 ; x++)
        {
          inByte = Serial.read();
          if (inByte>31 && inByte<128)
          {
            pars=pars+char(inByte);
          }
        }
        
        comand=pars;
        
        if (comand=="info")
        {
          Serial.print  ("PROGRAMM : ");
          Serial.println(PROGRAMM); 
          Serial.println("Temucin LE / SPS-12"); 
          Serial.println(""); 
           
        }
        if (comand=="set")
        {
          Serial.println("SET: "+param);
        }
      }
    }

  
  // ---------------------------------------------------------------------------
  // Funktionen
  
  IO_1_Status=digitalRead(IO_1);
  if(IO_1_Status==LOW && IO_1_Mode==0){
    
   Serial.println("IO_1 = LOW");    
   
   pinMode(IO_1, OUTPUT);
   digitalWrite(IO_1, HIGH);
   IO_1_Mode=1;
   
  } 
  
}

Das ist das Test Programm. Der IO wird als Eingang Inizialisiert und der PullUp aktiviert.
Dann warte ich bis der IO auf Low runter gezogen wird.
Dann sollte der selbe Auf OUTPUT gestellt werden und Auf High damit der Asugang Aktiv ist.

Soweit die Teorie.

Hier noch ein improvisiertes Schaltbild.

You can use INPUT_PULLUP

I don't understand the drawing (schaltbild) at all. Is there an Arduino in there ?
Did you use 24V near the Arduino ? Perhaps that pin is damaged.

temucin:
die Karte baue ich gerade und teste die Technischen Möglichkeiten.

Was soll das werden, wenn es fertig ist?

Ich sehe da einen "Taster" an Minus und eine "Last" an Plus.
Wenn der "Taster" geschlossen ist, ist die "Last" eingeschaltet.
Wenn der "Taster" offen ist, ist die "Last" ausgeschaltet.

Alles weitere in der Schaltung sieht mir nach reinem Tinnef ohne Funktion aus.

Wo soll der Arduino mit seinem Input angeschlossen sein, der ist nirgends im Schaltbild zu sehen?! Ich vermute mal, unten das grüne offene Ende zwischen den beiden 10 K Widerständen soll zum Arduino Eingang führen? Aber was möchtest Du bezwecken?

Peter_n:
I don't understand the drawing (schaltbild) at all.
Is there an Arduino in there ?

I'm in your opinion. No Arduino.

Bitte poste ein richtiges Schaltbild.

Hallo,

Ich möchte den Pin des Arduino in beiden Richtungen Galvanisch trennen. Das ist der Kern der Bemühung. Aber ich denke ich habe da ein grundsätzliches Verständniss Problem.

nu kommt schon .... so schlecht ist das Schaltbild nu auch wider nicht. Unten der Blaue Rahmen Representirt den Arduino Pin wo die PullUp and Down Widerstände zugeschaltet werden können.

Wenn der Taster betätigt wird, wird die Last geschaltet und der Optokoppler zieht den Pin auf LOW. Durch den PullUp ist er normalerweise High.

das erkennen des Tasters funktioniert.

Erkennt der Sketsh das der Eingang auf low herunter gezogen wird. Dann wechselt er den Pin Mode und schaltet diesen auf HIGH.
Nun Sollte der Linke Optokoppler die Last übernehmen da er ja jetzt direkt das High vom Pin und nicht über den PullUp bekommt. Macht er aber nicht.

Gruss Turgut

PS: Jeder hat mal klein angefangen :slight_smile:

Wenn ich jede Richtung separat teste funktioniert es .... aber zusammen ist der Wurm drin.

temucin:
nu kommt schon .... so schlecht ist das Schaltbild nu auch wider nicht. Unten der Blaue Rahmen Representirt den Arduino Pin wo die PullUp and Down Widerstände zugeschaltet werden können.

Ein Arduino hat zwar einen schaltbaren eingebauten PullUp-Widerstand.

Aber es gibt keinen schaltbaren PullDown-Widerstand.
PullDown-Widerstände können nur "extern" fest verbaut werden.
Ein mit pinMode INPUT geschalteter Eingang ist immer "schwebend", d.h. dieser Eingang kann wahlweise zwischen HIGH und LOW hin und her pegeln, je nachdem, welche zufälligen Störungen er auffängt.

temucin:
Ich möchte den Pin des Arduino in beiden Richtungen Galvanisch trennen. Das ist der Kern der Bemühung. Aber ich denke ich habe da ein grundsätzliches Verständniss Problem.

Aber was soll das werden, wo soll geschaltet werden und wo sollen Signale ankommen?

Möchtest Du die "Last" manuell am "Schalter" ein und aus schalten und der Arduino soll ein Signal am Eingang erhalten, ob die Last ein- oder ausgeschaltet ist?

Oder möchtest Du mit einen "Schalter" einen Arduino-Eingang HIGH/LOW setzen und der Arduino soll daraufhin eine "Last" schalten?

Hallo,

ich habe hier einige Bücher die was anderes erzählen. Wenn dem so ist, erklärt das natürlich einiges.

Wie oben schon angedeutet soll die Schaltung folgendes machen.

Wenn der Taster betätigt wird soll die Last für eine Zeit X vom Arduino gehalten werden.
Der knackpunkt ist ...... Galvanisch getrennt und über einen Pin.

LG Turgut

PS : alle anderen Varianten kenne ich schon.

Warum muss es ein Pin sein?

Hallo,

zum einen weil es Pins Spart, wenn Eingänge mit feedback verwendet werden. So kann ich zum beispiel einen Taster zum einschalten einer Maschine mit einer Lampe koppeln die solange Leuchtet wie die Maschine läuft. Ich arbeite in der Lift Technik und dort ist das Standart.

LG Turgut

PS: Bei 30 Motoren macht das schon einen Unterschied ob ich 30 oder 60 Pins brauche.

Pins sparen braucht man bei µC im Gegensatz zu den meisten SPS nicht. Hier heißt es nicht, wenn 5 Eingänge mehr benötigt werden, einmal bitte 100€ für die nächste Karte.

Mittels Port Expander, Shiftregister hönnen die Ausgänge/ Eingänge fast beliebig erweitert werden.
Ich finde es sinnvoller Ausgänge von Eingängen zu trennen.
Grüße Uwe

temucin:
Wenn der Taster betätigt wird soll die Last für eine Zeit X vom Arduino gehalten werden.
Der knackpunkt ist ...... Galvanisch getrennt und über einen Pin.

Oh, oh. Das mit dem "nur über einen Pin" ist so gar nicht typisch für Mikrocontrollerschaltungen.

Denn Deine "Selbsthaltung", die Du mit dem Schalter programmieren möchtest, kann dann hinterher nicht mehr mit demselben Schalter wieder aufgehoben/ausgeschaltet werden. Das kann dann bei Deinem Vorhaben nur noch der Mikrocontroller von sich aus machen.

Vom Prinzip her müßte es aber ungefähr so möglich sein, wie Du es Dir vorstellst: Mit zwei Optokopplern.
Eine fertige Schaltung habe ich nicht für Dich, aber einige Anregungen. Im folgenden bezeichne ich den mit dem Schalter betätigten Optokoppler mal 24V-Optokoppler und den vom Mikrocontroller betätigten nenne ich 5V-Optokoppler.

  1. Da ein Optokoppler mit 24V und der andere mit 5V geschaltet wird, müßtest Du bei der Berechnung des Vorwiderstands eigentlich zwei verschiedene Widerstandswerte herausbekommen, so dass es an einer korrekt berechneten Schaltung nicht sein kann, dass sowohl am 24V Optokoppler als auch am 5V Optokoppler ein 2K Widerstand verwendet wird.

  2. Optokoppler können am Ausgang ein "Signal" abgeben, aber keine großen Leistungen schalten. Der 24V-Optokoppler kann dann zwar problemlos dem Mikrocontroller ein Signal senden, dass der Schalter betätigt wurde, aber mit dem 5V-Optokoppler kannst Du vermutlich nicht direkt den notwendigen Laststrom halten/schalten. Ich nehme mal an, Deine "Last" soll irgendwie ein Relais sein, dann würde der 5V-Optokoppler am Ausgang noch eine Transistorschaltstufe benötigen, um den Laststrom (= Relais-Spulenstrom) zu schalten.

  3. Im Schaltbild fällt mir auf, dass Du an den Optokopplerausgängen mal Plus oben und Minus unten und mal umgekehrt angeschlossen hast. Das ist an den meisten existierenden Optokopplern nicht erlaubt, sondern je nach Typ des Optokopplers muss der Ausgang richtig gepolt am Optokoppler angeschlossen sein. Nur bei ganz wenigen bipolaren Optokopplern ist es egal, wie herum die Polung am Ausgang angeschlossen ist.

Soweit meine Ideen dazu.

Hallo,

danke für deine Anregung. Der Optokoppler rechts, für das erkennen des Tastendruck ist ein gewöhnlicher PC817. Der Last Treiber links, ist ein AQV212 der Speziell in der Telefontechnik Verwendung findet. Mitlerweile habe ich das Problem eingrenzen können. Der Hinweis mit der Berechnung hat zwar den Ausschlag ..... aber nicht das ergebniss geliefert. Der Vorwiderstand für den Treiber hat nicht funktioniert. Egal welchen ich genommen habe. Erst die Leucht Diode bringt das ganze zum Funktionieren. Ich weis aber nicht warum. Fileicht kann mir ja jemand den Geistes Blitz vermitteln.

was auch noch wichtig war, ist das Delay 2 oder grösser und das vorherige Auf LOW setzen vor dem Umschalten.

/*
  Programm : I/O Verstärker
  Einen I/O als Eingang und als Ausgang
  verwenden.
  Code by Temucin LE at 2014
*/

// Programm Spezifische Variablen

String PROGRAMM = "I/O Verstärker" ;

//-------------------------------

int IO_1 = 12;           
int IO_1_Status;
int IO_1_Mode;

long ser_timer;
long IO_1_timer;

int led = 13;
int led_t =0;
long timer = 0;

unsigned long mil_1 =0;
unsigned long mil_2 =0;
int timer_div =0;

int inByte = 0;
String comand ;
long wert = 0;
String pars ;
int par_count;
int parstep;
String param ;
byte par1;
byte par2;
byte par3;
byte par4;
byte par5;
byte par6;
int intstep;

// the setup routine runs once when you press reset:
void setup() {                
  
  // initialize the digital pin 
  
  Serial.begin(57600);
  
  pinMode(led, OUTPUT);
  
  pinMode(IO_1, INPUT); 
  digitalWrite(IO_1,HIGH);
  IO_1_Mode=0;
  
}

// the loop routine runs over and over again forever:
void loop() {
  
  // --------------------------------------------------------------------------  
  // millis() count und überlauf prüfung, in timer_div steht die anzahl verstrichener millis
  
  mil_2 = mil_1;
  mil_1 = millis(); // da sich der überlauf der millis auch innerhalb eines loops an einer zufälligen stelle ereignen kann, wird dieser zwischen gespeichert.  
  if (mil_1<mil_2) //  das neue mil ist kleiner wie das alte, dann muss ein überlauf stadt gefunden haben
  {
    timer_div=1;
  }
  else
  {
    timer_div=mil_1-mil_2;    
  }
  
  // --------------------------------------------------------------------------  
  // Lebenslicht Blinker 
  
  if (timer>0)
  {
    timer=timer-timer_div; 
    if (timer<0) timer=0; 
  }
  if (timer==0) // Lebenslicht des Programms
  {
    timer=1000;
    
    if (led_t==0)
    {
      led_t=1;
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      //digitalWrite(IO_1, HIGH);
    }
    else
    {
      led_t=0;
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      //digitalWrite(IO_1, LOW);
    }
  }
  // ---------------------------------------------------------------------------
  // Data to Ser
 
  if (ser_timer>0)
  {
    ser_timer=ser_timer-timer_div;
    if (ser_timer<0) ser_timer=0;
  } 
  if (ser_timer==0)
  {
    ser_timer=250;
    Serial.print("IO_1: ");
    Serial.println(digitalRead(IO_1));    
  } 
  // ---------------------------------------------------------------------------
  // IO Kontrolle
  
  if (IO_1_timer>0)
  {
    IO_1_timer=IO_1_timer-timer_div;
    if (IO_1_timer<0) IO_1_timer=0;
  }  
  if (IO_1_timer==0&&IO_1_Mode==1)
  {
    Serial.println("IO_1: Set In");
    digitalWrite(IO_1, LOW);
    delay (2);
    pinMode(IO_1, INPUT);
    digitalWrite(IO_1, HIGH);
    delay (2);
    IO_1_Mode=0;
  }
  else
  {
    IO_1_Status=digitalRead(IO_1);
    if(IO_1_Status==0 && IO_1_Mode==0){
      
     //Serial.println("IO_1 = LOW");    
     Serial.println("IO_1: Set Out");
     digitalWrite(IO_1, LOW);
     delay (2);     
     pinMode(IO_1, OUTPUT);
     digitalWrite(IO_1, HIGH);
     delay (2);
     IO_1_Mode=1;
     IO_1_timer=5000;
     
    }     
  }
  // ---------------------------------------------------------------------------
  // Serielle Komunikation
  
 
    // send data only when you receive data:
    if (Serial.available() > 0) {
      // read the incoming byte:
      comand="";
      wert=0;
      param="";
      pars="";
      inByte = Serial.read();
      
      if (inByte == 47)
      {
        delay (5);
                
        for (int x = 0 ; x<15 ; x++)
        {
          inByte = Serial.read();
          if (inByte>31 && inByte<128)
          {
            pars=pars+char(inByte);
          }
        }
        
        comand=pars;
        
        if (comand=="info")
        {
          Serial.print  ("PROGRAMM : ");
          Serial.println(PROGRAMM); 
          Serial.println("Temucin LE / SPS-12"); 
          Serial.println(""); 
           
        }
         
        if (comand=="set")
        {
          Serial.println("SET: "+param);
        }
      }
    }

}

Auf jeden Fall danke für die Hilfe.

You have two resistors of 10k inside the Arduino, but they are not there.
There is one internal pullup resistor of about 50k, but there is no pulldown resistor at all.

Hallo,

i have corrected the plan. Sorry my english are little bit.

Hallo,

ich denke es funktioniert mit einem Widerstand nicht. Weil dieser nur bis 7,5 K an dem AQV212 funktioniert. Und das würde aber im Umkehrschluss bedeuten das ich ein LOW auf den Pin lege.