Arduino Forum

International => Deutsch => Topic started by: Muecke on Nov 20, 2014, 11:01 pm

Title: Verständnis frage --> pinMode
Post by: Muecke on Nov 20, 2014, 11:01 pm
Hallo miteinander,


ich habe da mal eine Verständnis frage zu dem Befehl "pinMode"

bisher mache ich im void setup() alle Definitionen von den
PINS also ob es ein Eingang oder ein Ausgang ist.

kann / darf ich den Befehl auch in meinem void loop () verwenden?
oder ist das so nicht vorgesehen und es könnte zu Probleme führen?
oder ist das Jake wie Hosse? wo ich das mache Hauptsache ich mache es bevor ich den PIN benutze?


Gruß
Mücke
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 20, 2014, 11:06 pm
Das geht überall. Es gibt Anwendung wo man Pins von Eingang auf Ausgang umschalten muss. Aber man muss aufpassen dass man da keinen Kurzschluss fabriziert.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 20, 2014, 11:08 pm
Danke,

Dann kann ich das überall verwenden. Wie du sagst aufpassen das ich nichts Kaputt mache dabei (Kurzschluss) wobei ich das echt gut kann ;-).

Danke.
Title: Re: Verständnis frage --> pinMode
Post by: uwefed on Nov 20, 2014, 11:41 pm
Man kann, wie gesagt, jederzeit ein Pin als Eingang oder Ausgang definieren. Dies wird zB bei Chalieplexing intensiv gemacht. ( ein Pin ist H ein anderes L und alle anderen Eingang (hochohmig). http://en.wikipedia.org/wiki/Charlieplexing auch bei I2C Bus auf der Datenleitung wird das praktiziert.

Es muß ein Kurzschluß verhindert werden (ein PIN HIGH und ein mt ihm verbundenes LOW) Es könenn Widerstände in Serie zu den Pins notwendig sein um einen etwaigen Kurzschlußstrom auf ungefährliche Werte zu begrenzen ( zB die 500 bzw 1000 Ohm Widerstände zwischen RX und TX des USB Adapters und dem Atmega-Controller).

Grüße Uwe
Title: Re: Verständnis frage --> pinMode
Post by: jurs on Nov 20, 2014, 11:43 pm
bisher mache ich im void setup() alle Definitionen von den
PINS also ob es ein Eingang oder ein Ausgang ist.

kann / darf ich den Befehl auch in meinem void loop () verwenden?
oder ist das so nicht vorgesehen und es könnte zu Probleme führen?
Du kannst das machen, wie es im Programm für die Schaltung "passt" und "notwendig ist".

Insbesondere durch das Setzen von "OUTPUT" mit falscher Beschaltung kannst Du allerdings auch fette Kurzschlüsse in Deiner Schaltung produzieren, die ohne eine entsprechende Schutzbeschaltung zur Zerstörung des Controllers führen können.

Kleines Beispiel:
Du hast eine Drahtverbindung zwischen einem INPUT und einem OUTPUT Pin. Jetzt kannst Du den OUTPUT wahlweise HIGH oder LOW setzen und am INPUT den Pegelwechsel messen. Schaltung OK, alles paletti.

Wenn Du jetzt aber den INPUT auch auf OUTPUT setzt, dann ist es nur noch paletti, wenn beide Pins auf denselben Pegel geschaltet sind. Also entweder beide OUTPUT auf LOW oder beide auf HIGH.

Falls sich die Pegel unterscheiden und ein OUTPUT auf LOW gesetzt ist und der andere auf HIGH während diese querverbunden sind, dann versucht der eine, so viel Strom wie möglich zu schlucken, um den Pegel auf LOW zu ziehen, und der andere versucht gleichzeitig, so viel Strom abzugeben, bis der Pegel auf HIGH wechselt. Die klassische Kurzschlußsituation.

Also:
Ohne jegliche äußere Beschaltung des Controllers ist es Jacke wie Hose, wie Du die Eingänge und Ausgänge setzt.

Aber mit Vorhandensein äußerer Beschaltung besteht beim falschen Setzen von OUTPUT die Gefahr eines Kurzschlusses in der Schaltung.

Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 20, 2014, 11:51 pm
LEDs als Fotodiode zu verwenden ist auch ein gutes Beispiel:
http://www.mikrocontroller.net/articles/Lichtsensor_/_Helligkeitssensor#LED

Man setzt den Pin erst auf Ausgang, High um die Sperrschicht aufzuladen. Dann setzt man ihn auf Eingang und misst die Zeit bis der Pin als Low erkannt wird. Die Zeit ist dann proportional zum Lichteinfall.

Es gibt Projekte die das mit normalen 8x8 LED Matrizen machen.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 12:07 am
OK, danke für die Ausführung,

bei mir geht es nicht so Tief in die mattierte ;-), habe heute meine 4 Weiteren Schieblehren erhalten, und habe ie heute auch gleich verlötet (Babel angebracht) leider sind das alles unterschiedliche :-(
und ich möchte alle 5 Schieblehren auslesen lassen, da wir das ja schon in einem Anderen Thema besprochen haben, möchte ich das jetzt für mich Übersichtlicher gestellten. 

Sprich alles was für die Schieblehre_1 an Code da ist in eine Funktion packen und nur den Wert zurück geben, in der Funktion möchte ich dann auch die Pins Definieren für die Schieblehre.

Das mache ich dann 5 mal und wenn ich dann meine Dehnungsmessstreifen endlich mal verstanden habe kommt der auch mit in eine Funktion.

Ja man könnte die  Funktion auch so machen das ich sie Öffners aufrufen kann und alle Schieber aus lesen lassen könnte, ja das geht, ich bekomme das nur nicht hin :-(. daher der weg so, das müsste ich eigentlich schon hin bekommen.

dafür habe ich das nachgefragt, nicht das ich was machen möchte was später zu Problemen führt.


Daher Danke für die Hinweise und die Erklärungen, so weit hatte ich noch gar nicht gedacht :-)
Danke.
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 12:13 am
setup() ist auch nicht viel mehr als eine normale Funktion. Die musst du halt haben und sie wird am Anfang einmal ausgeführt. Das macht die IDE im Hintergrund. Aber das ist nichts wirklich besonderes.
Title: Re: Verständnis frage --> pinMode
Post by: uwefed on Nov 21, 2014, 12:15 am
Jetzt habe ich nicht verstanden warum Du die Pins nur in der Funktion zum Auslesen einer Schieblehre brauchst und diese nicht standartmäßig definierst.
Grüße Uwe
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 12:26 am
Das ist so, ich habe da einmal die PIN Nr. Selber und dann auch noch das Register das direkt abgefragt wird von dem PIN, da ich das Register (mir nicht bekamt) in die Funktion übergeben muss ich für jede Schieblehre eine extra Funktion mir erstellen, da ich das Schöner finde möchte ich dann auch die Pin Nr. dort mit rein Schreiben, und ich in meine Sketch vorne, sonnst komm ich noch auf die Doofe ide das ich einfach nur die Nr. ändern muss und den Schieber wo anderes anschließen kann.




Ich habe aber jetzt ein Problem:

meine Datei: Funktionstest.ino
Code: [Select]
#include "Funktion.h"

int TasterPin = 2;                                                          // Taster zum Daten auslesen

void setup()
  {
    Serial.begin(9600);                                                     // Serielen Monitor Einstellung
    pinMode(TasterPin, INPUT);                                              // Pin für Taster Definiren (Eingang)
  }

void loop ()
  {
    Serial.println(Schieber5());

    while (digitalRead(TasterPin) == LOW) {}                                // Warten bis der taster zustand sich ändert
  }  // ENDE --> void loop



Meine Datei: Funktion.h

Code: [Select]
unsigned long temp_millis;


// ***********************************************************************************************
//                             Schieblehre 5 auslesen und Wert zurück geben
// ***********************************************************************************************
int Schieber5()
  {
    int Schieber_5_ClockPin = 24;  // Pin 24 das 2. Bit vom Port A (PINA PA2)
    int Schieber_5_DataPin  = 25;  // Pin 25 das 3. Bit vom Port A (PINA PA3)


    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);

    while (digitalRead(Schieber_5_ClockPin) == LOW) {}    // wenn CLOCK auf LOW, dann warten bis wieder HIGH
    temp_millis = millis();                               // aktuelle Zeitnahme
    while (digitalRead(Schieber_5_ClockPin) == HIGH) {}   // wenn CLOCK auf HIGH, warten bis wieder LOW
    if ((millis() - temp_millis) > 100)                   // wenn High-Pegel länger wie 100ms war, springe in 'decode' Funktion
      {

        long value = 0;
        byte SIGN_Bit = 0;                          // Vorzeichen Bit 21
     
          for (int i=0;i<24;i++)                    // 24 Durchläufe, 0 bis 23
            {           
              if ( PINA & ( 1 << PA3 ))             // wenn Data (Port.A Bit.3) HIGH ist,
                {                                   // eine 1 in die Variable 'value' an Bitnummer i
                  value |= 1UL << i;                // Syntax Hinweis aus dem Forum, wegen default 16 bit int Arithmetik
                }
                while ( !(PINA & (1 << PA2)))  { }  // solange warten bis Clock (Port.A Bit.2) wieder HIGH ist
                while (   PINA & (1 << PA2 ))  { }  // solange warten bis Clock (Port.A Bit.2) wieder LOW ist
            }  // for Schleifenende
   
           SIGN_Bit = (value >> 21) & B01;          // Vorzeichen Bit 21 separieren
           value = value & 0xFFFF;                  // nur Bit 0 bis Bit 15 behalten, den Rest davor nullen
           value = value >> 1;                      // und alles um ein Bit nach rechts schieben, Startsignal wird entfernt
           if (SIGN_Bit == 1)                       // wenn Vorzeichen-Bit gesetzt war, alles mit -1 multiplizieren
            { value = value * -1; }
           Serial.println((float)value / 100);      // Kommastelle setzen und man erhält den endgültigen Meßwert
//         return (float)value / 100;               // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)

//    int result;                                // Rückgabe wert Deklariren
//    result = 10 * 30;                          // Rückgabe berechnen
//    return result;                             // Rückgabe zurückgeben
  }



jetzt bekomme ich eine Fehlermeldung!!!
Quote
In file included from Funktionstest.ino:13:
Funktion.h: In function 'int Schieber5()':
Funktion.h:13: error: 'INPUT' was not declared in this scope
Funktion.h:13: error: 'pinMode' was not declared in this scope
Funktion.h:16: error: 'digitalRead' was not declared in this scope
Funktion.h:16: error: 'LOW' was not declared in this scope
Funktion.h:17: error: 'millis' was not declared in this scope
Funktion.h:18: error: 'digitalRead' was not declared in this scope
Funktion.h:18: error: 'HIGH' was not declared in this scope
Funktion.h:23: error: 'byte' was not declared in this scope
Funktion.h:23: error: expected `;' before 'SIGN_Bit'
Funktion.h:27: error: 'PINA' was not declared in this scope
Funktion.h:27: error: 'PA3' was not declared in this scope
Funktion.h:31: error: 'PINA' was not declared in this scope
Funktion.h:31: error: 'PA2' was not declared in this scope
Funktion.h:32: error: 'PINA' was not declared in this scope
Funktion.h:32: error: 'PA2' was not declared in this scope
Funktion.h:35: error: 'SIGN_Bit' was not declared in this scope
Funktion.h:35: error: 'B01' was not declared in this scope
Funktion.h:40: error: 'Serial' was not declared in this scope
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Arduino.h:23,
                 from Funktionstest.ino:15:
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/include/stdlib.h:54: error: expected unqualified-id before string constant
Funktionstest:29: error: expected `}' at end of input
verstehe ich nicht,

ich habe den gesamten Text vorher im void loop () gehabt da hat es funktioniert.

jetzt wollte ich das in eine Funktion packen damit es aufgeräumter ausschaut, und dann der Fehler :-(
Title: Re: Verständnis frage --> pinMode
Post by: sschultewolter on Nov 21, 2014, 12:32 am
Da solltest du aber noch was ändern! Das ist keinesfalls flexibel oder übersichtlich. Besser ist es, eine allgemeine Funktion zu schreiben. Dann die Pins mitteilen.


Code: [Select]

void func(int clkPin, int dataPin)
{
pinMode(clkPin, INPUT);
pinMode(dataPin, INPUT);
}



Nutzte anstatt eine *.h Datei die *.ino Endung. Hier ist die IDE etwas komisch im Verhalten.
Gibt der Messschieber den Clk vor? Wenn nein, warum clkPin als INPUT? Müsste dann OUTPUT sein. Des weiteren sollte in *.h Dateien nur die Funktionsrümpfe
Code: [Select]

void func(int clkPin, int dataPin);

stehen.

Dazu brauchst du dann noch eine *.c
Code: [Select]

#include "*.h"

void func(int clkPin, int dataPin)
{
// do
}
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 12:32 am
Das liegt einfach dran dass du in einem Header bist und dort die Arduino Definitionen nicht inkludiert sind. Dann kennt er selbstverständlich das Makro nicht.

Lösung:
#include <Arduino.h>



Siehe x:\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h

Da stehe am Anfang Dinge wie:
Code: [Select]

#define HIGH 0x1
#define LOW  0x0

#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 12:40 am
@sschultewolter: so wollte ich das zu beginn machen, jedoch wird weiter unten nicht mehr mit den Pin Nr. gearbeitet sondern mit den Registern selbst und die kann ich schlecht ableiten oder übergeben, dafür habe ich keine Lösung gefunden. :-(

was ist ein "Clk" ist kenne das Auto CLK doch das meinst du glaube ich nicht ;-)

das mit dem Auslesen des Schiebers 5 haben wir schon hier (http://forum.arduino.cc/index.php?topic=273445.0) geklärt.



LÖSUNG??
#include <Arduino.h>

!!! Das hatte ich auch gedacht doch wenn ich das mache (in der Datei Funktion.h) dann bekomme ich Fehlermeldungen in meiner Funktionstest.ino


EDIT: das mit der Endung .INO habe ich gerade probiert da bekomme ich aber eine Fehler beim der include dann, ...
Title: Re: Verständnis frage --> pinMode
Post by: sschultewolter on Nov 21, 2014, 12:43 am
mit clk meine ich einfach die ClockLeitung. Was meinst du mit deinem letzten Satz?

Wenn du die ino erstellt ist der #include nicht nötig. Das Problem wird sein, dass er dann die h-Datei mehrmals nutzen möchte ;)

Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 12:56 am
ich kann mir ganz grob vorstellen was eine "ClockLeitung" sein könnte, doch das ist da nicht vorhanden :-(

das mit dem "letzten Satz" du meinst mein EDIT. ja ich habe irgend was zerschossen, ... muss erst schauen und es wider auf Anfang Sätzen.


Quote
Wenn du die ino erstellt ist der #include nicht nötig. Das Problem wird sein, dass er dann die h-Datei mehrmals nutzen möchte ;)
Ach so du meinst ich soll die Funktion in der INO Datei drin lassen und in in eine Gesonderte Datei packen.


@sschultewolter: das ist gemein wenn du ein EDIT oben machst und ich das übersehe, ... ;-)
Das mit den Input und Output verstehe ich jetzt nicht, jedoch klapt das mit dem Lesen der Werte des Schiebers.

Habe ich das richtig verstanden. die Datei *.h beinhaltet die Deklaration der Funktionen und die Datei *.c hat die Funktion dann selber? 
das sollte das auch gehen was ich vorhabe?



ps. ja du hast recht Flexibel ist das überhaupt nicht, da ich aber keine Ahnung habe wie ich den Code Flexibel bekomme, schaue ich das ich so eine Lösung finde ;-).
Title: Re: Verständnis frage --> pinMode
Post by: sschultewolter on Nov 21, 2014, 01:06 am
Hab mir noch mal den Sketch oben angeschaut. CLK auf INPUT scheint richtig zu sein, wenn der Messschieber den Master spielt, was er hier ja scheinbar macht.

Bleib am besten bei der ino allgemein. Ich habe kein Plan, wie der Aufbau genau verunstaltet wird.


Code: [Select]

void setup()
{

}

void loop()
{

}


ist in AVR GCC nichts anderes als

Code: [Select]

#include <Arduino.h>

void setup(void)
{
//
}

void loop()
{
//
}




int main(void)
{
setup();

while(1)
{
loop();
}
return 0;
}
[code]
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 01:10 am
OK, ich packe das alles in die .INO Datei rein.

Hoffe das klappt dann. ;-)
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 01:10 am
Habe ich das richtig verstanden. die Datei *.h beinhaltet die Deklaration der Funktionen und die Datei *.c hat die Funktion dann selber? 
Korrekt.

Mehrfach-Inkludierungen sollte eigentlich durch Include-Guards verhindert werden, aber dadurch dass die Arduino Software da viel von sich aus im Hintergrund macht kann man da irgendwo reingelegt werden.

Probier mal in deiner .c/.cpp Datei deinen Header und Arduino.h zu inkludieren und dann inkludierst du deinen Header in der .ino Datei. Das ist der normale Weg.


Alles in .ino Datei zu packen geht bei Arduino natürlich auch. Dann übernimmt die IDE das zusammenkopieren der verschieden Dateien vor dem Kompilieren.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 01:28 am
Also ich versuche das jetzt alle in der INO Datei.


Doch ich bekomme das nicht hin :-(

1. versuch

Schieber 5 auslesen alles in (Loop) --> Klappt richtig :-) Heppy

also alles aus dem (Loop) nehmen und in die Funktion int Schiber5() packen
und in Loop dann Seriel.Print Schieber5() aufrufen.

jetzt klappt es nicht mehr, ich bekomme immer 0 angezeigt ab und an ist mal ein wert dabei.


Was zum Henker mache ich da Falsch?
ich versuche das jetzt erst mal nicht in eine Externe Datei zu packen sondern bleibe in der INO Datei.


Code wie es Richtig Klappt:
Code: [Select]
unsigned long temp_millis;

void setup()
  {
    Serial.begin(9600);
  }

void loop ()
  {
    int Schieber_5_ClockPin = 24;  // Pin 24 das 2. Bit vom Port A (PINA PA2)
    int Schieber_5_DataPin  = 25;  // Pin 25 das 3. Bit vom Port A (PINA PA3)


    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);

    while (digitalRead(Schieber_5_ClockPin) == LOW) {}    // wenn CLOCK auf LOW, dann warten bis wieder HIGH
    temp_millis = millis();                               // aktuelle Zeitnahme
    while (digitalRead(Schieber_5_ClockPin) == HIGH) {}   // wenn CLOCK auf HIGH, warten bis wieder LOW
    if ((millis() - temp_millis) > 100)                   // wenn High-Pegel länger wie 100ms war, springe in 'decode' Funktion
      {

        long value = 0;
        byte SIGN_Bit = 0;                          // Vorzeichen Bit 21
     
          for (int i=0;i<24;i++)                    // 24 Durchläufe, 0 bis 23
            {           
              if ( PINA & ( 1 << PA3 ))             // wenn Data (Port.A Bit.3) HIGH ist,
                {                                   // eine 1 in die Variable 'value' an Bitnummer i
                  value |= 1UL << i;                // Syntax Hinweis aus dem Forum, wegen default 16 bit int Arithmetik
                }
                while ( !(PINA & (1 << PA2)))  { }  // solange warten bis Clock (Port.A Bit.2) wieder HIGH ist
                while (   PINA & (1 << PA2 ))  { }  // solange warten bis Clock (Port.A Bit.2) wieder LOW ist
            }  // for Schleifenende
   
           SIGN_Bit = (value >> 21) & B01;          // Vorzeichen Bit 21 separieren
           value = value & 0xFFFF;                  // nur Bit 0 bis Bit 15 behalten, den Rest davor nullen
           value = value >> 1;                      // und alles um ein Bit nach rechts schieben, Startsignal wird entfernt
           if (SIGN_Bit == 1)                       // wenn Vorzeichen-Bit gesetzt war, alles mit -1 multiplizieren
            { value = value * -1; }
           Serial.println((float)value / 100);      // Kommastelle setzen und man erhält den endgültigen Meßwert
//         return (float)value / 100;               // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)
      }
  }  // ENDE --> void loop



Code wie ich es gerne hätte, doch nicht klappt
 
Code: [Select]
unsigned long temp_millis;

void setup()
  {
    Serial.begin(9600);
  }

void loop ()
  {
    Serial.println(Schieber5());
  }  // ENDE --> void loop







int Schieber5()
  {
    int Schieber_5_ClockPin = 24;  // Pin 24 das 2. Bit vom Port A (PINA PA2)
    int Schieber_5_DataPin  = 25;  // Pin 25 das 3. Bit vom Port A (PINA PA3)


    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);

    while (digitalRead(Schieber_5_ClockPin) == LOW) {}    // wenn CLOCK auf LOW, dann warten bis wieder HIGH
    temp_millis = millis();                               // aktuelle Zeitnahme
    while (digitalRead(Schieber_5_ClockPin) == HIGH) {}   // wenn CLOCK auf HIGH, warten bis wieder LOW
    if ((millis() - temp_millis) > 100)                   // wenn High-Pegel länger wie 100ms war, springe in 'decode' Funktion
      {

        long value = 0;
        byte SIGN_Bit = 0;                          // Vorzeichen Bit 21
     
          for (int i=0;i<24;i++)                    // 24 Durchläufe, 0 bis 23
            {           
              if ( PINA & ( 1 << PA3 ))             // wenn Data (Port.A Bit.3) HIGH ist,
                {                                   // eine 1 in die Variable 'value' an Bitnummer i
                  value |= 1UL << i;                // Syntax Hinweis aus dem Forum, wegen default 16 bit int Arithmetik
                }
                while ( !(PINA & (1 << PA2)))  { }  // solange warten bis Clock (Port.A Bit.2) wieder HIGH ist
                while (   PINA & (1 << PA2 ))  { }  // solange warten bis Clock (Port.A Bit.2) wieder LOW ist
            }  // for Schleifenende
   
           SIGN_Bit = (value >> 21) & B01;          // Vorzeichen Bit 21 separieren
           value = value & 0xFFFF;                  // nur Bit 0 bis Bit 15 behalten, den Rest davor nullen
           value = value >> 1;                      // und alles um ein Bit nach rechts schieben, Startsignal wird entfernt
           if (SIGN_Bit == 1)                       // wenn Vorzeichen-Bit gesetzt war, alles mit -1 multiplizieren
            { value = value * -1; }
//           Serial.println((float)value / 100);      // Kommastelle setzen und man erhält den endgültigen Meßwert
         return (float)value / 100;               // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)
        }
  }  // ENDE --> Schieber5



kann das sein das das an dem int liegt?
int Schieber5()
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 03:02 am
Nennt mich was Ihr wollt, doch für mich ist das nicht Logisch.

so klappt es jetzt, das der Auslese Code unten Extra in einer Funktion steht.


ich habe das jetzt so abgerufen:
Code: [Select]
    float Ergebnis;
    Ergebnis = Schieber5();
    Serial.println(Ergebnis);



Code: [Select]
unsigned long temp_millis;

void setup()
  {
    Serial.begin(9600);
  }

void loop ()
  {
    float Ergebnis;
    Ergebnis = Schieber5();
    Serial.println(Ergebnis);
  }  // ENDE --> void loop



float Schieber5()
  {
    int Schieber_5_ClockPin = 24;  // Pin 24 das 2. Bit vom Port A (PINA PA2)
    int Schieber_5_DataPin  = 25;  // Pin 25 das 3. Bit vom Port A (PINA PA3)


    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);

    while (digitalRead(Schieber_5_ClockPin) == LOW) {}    // wenn CLOCK auf LOW, dann warten bis wieder HIGH
    temp_millis = millis();                               // aktuelle Zeitnahme
    while (digitalRead(Schieber_5_ClockPin) == HIGH) {}   // wenn CLOCK auf HIGH, warten bis wieder LOW
    if ((millis() - temp_millis) > 100)                   // wenn High-Pegel länger wie 100ms war, springe in 'decode' Funktion
      {

        long value = 0;
        byte SIGN_Bit = 0;                          // Vorzeichen Bit 21
     
          for (int i=0;i<24;i++)                    // 24 Durchläufe, 0 bis 23
            {           
              if ( PINA & ( 1 << PA3 ))             // wenn Data (Port.A Bit.3) HIGH ist,
                {                                   // eine 1 in die Variable 'value' an Bitnummer i
                  value |= 1UL << i;                // Syntax Hinweis aus dem Forum, wegen default 16 bit int Arithmetik
                }
                while ( !(PINA & (1 << PA2)))  { }  // solange warten bis Clock (Port.A Bit.2) wieder HIGH ist
                while (   PINA & (1 << PA2 ))  { }  // solange warten bis Clock (Port.A Bit.2) wieder LOW ist
            }  // for Schleifenende
   
           SIGN_Bit = (value >> 21) & B01;          // Vorzeichen Bit 21 separieren
           value = value & 0xFFFF;                  // nur Bit 0 bis Bit 15 behalten, den Rest davor nullen
           value = value >> 1;                      // und alles um ein Bit nach rechts schieben, Startsignal wird entfernt
           if (SIGN_Bit == 1)                       // wenn Vorzeichen-Bit gesetzt war, alles mit -1 multiplizieren
            { value = value * -1; }
         return (float)value / 100;               // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)
        }
  }  // ENDE --> Schieber5



vorher war das ja so:
Code: [Select]
void loop ()
  {
    Serial.println(Schieber5());
  }  // ENDE --> void loop



wie gesagt Logisch ist das für mich nicht, aber gut. es tut jetzt :-).

jetzt mal schauen ob ich es schaffe das Teil in eine Extra Datei zu packen.
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 03:17 am
Die Funktion gibt nicht in allen Pfaden etwas zurück, oder täusche ich mich da? Wenn if ((millis() - temp_millis) > 100)  nicht zutrifft wird nichts zurück gegeben.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 03:23 am
habe gerade noch mal getestet, es klappt immer noch nicht, Arrrrrrr........


Die Funktion gibt nicht in allen Pfaden etwas zurück, oder täusche ich mich da? Wenn if ((millis() - temp_millis) > 100)  nicht zutrifft wird nichts zurück gegeben.
Öm ja, du hast recht, normalerweise wurde da das Ende vom void loop () erreicht und von vorne begonnen.

wie kann ich das abfragen? das wenn kein Wert zurück gegeben wird auch keine Ausgabe erfolgt?


EDIT: bzw. ich muss so lange in der Funktion kreisen bis ich einen Ruten Wert erhalte
also Packe ich alles in einen Loop mit der Bedingung wenn return was drin ist dann Funktion Ende

hmm, noch nie gemacht, ...
Title: Re: Verständnis frage --> pinMode
Post by: gsezz on Nov 21, 2014, 08:54 am
Eine Lösung hat dir sschultewolter ja schon gepostet, einfach die Pinnummern der Funktion übergeben anstatt fest hinein zu schrieben, dann brauchst du nur eine Funktion für alle Messschieber.
Ich würde gleich noch einen Schritt weiter gehen und eine Klasse anlegen, dann definierst du zu beginn alle deine Messschieber und hast bequeme Objekte mit denen du arbeiten kannst. Bspw kann man sie dann in ein Array ihres Typs stecken und alle Messwerte in einer Schleife abfragen.
Wenn das ganze dann schon in eigenen Header und Source Dateien steckt hast du quasi schon ein Lib das du später ganz fix in andere Projekte einbinden kannst.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 09:31 am
So gerne ich das auch machen würde kann ich das leider nicht wie schon erwähnt wird nicht nur die Pin Nr. genommen sondern auch das Register des PIN`s abgefragt und ich habe keinen Plan wie ich das Register übergeben soll.

Wenn jemand sagt das das machbar ist kann er das gerne umstellen, ich wäre Ihn sehr dankbar, doch ich kann es nicht und ich wies auch nicht wie das gehen soll mit meinem Wissensstand daher muss ich eine Lösung suchen die ich hin bekomme, mit dem Umstellen das ich das übergeben kann habe ich mich schon 4 Tage beschäftigt und ein andres Thema geöffnet gehabt da kam raus das das so nicht machbar ist.

z.B. das hier: (alles in der Fungieren später)

Code: [Select]
    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);

kann übergeben werden. --> JA !

Code: [Select]
              if ( PINA & ( 1 << PA3 ))             // wenn Data (Port.A Bit.3) HIGH ist, ...

wie übergebe ich das PINA?
-> das ist ein Register von Port A, aus Geschwindigkeits gründen wird hier direkt das Register Bit ausgelesen.
Wie übergebe ich das PA3?
--> das ist das Register Bit selbst

Hier habe ich keine Lösung gefunden, und aus dem Grund ist das für mich nicht machbar,
Daher suche ich die Lösung die für mich machbar ist.



daher die Frage ob ich prüfen kann ob etwas im Ruten drin oist oder nicht, oder ob man es auf Richtig / Falsch prüfen kann. oder einen Fehlerwert Sätzen kann, denn ich dann abfragen kann.
Title: Re: Verständnis frage --> pinMode
Post by: sschultewolter on Nov 21, 2014, 09:45 am
PAx zu übergeben bringt nichts. Das ist nur der Verweis, an welcher Stelle des Bytes (PORT) sich der Status befindet, der ausgelesen werden.

Warum hantierst du eigentlich überhaupt mit den Registers, was bei Arduino eher untypisch ist? DigitalRead nicht schnell genug??

Kann dir nachher eine Lösung schicken für die PORT,Pin Übergabe.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 09:57 am
wenn du mir eine Lösung für die Übergabe hast (für die PORT,Pin Übergabe) wäre ich dir dankbar.


Warum ich überhaupt damit arbeite, der Code ist vom Doc_Arduino ursprünglich verfasst worden da er schon solche Schieber ausgelesen hat. Ich habe den Code dann nur umgestellt und an meine Jetzige Situation angepasst.


Ich habe keinen Plan ob DigitalRead schnell genug ist.


Jedoch wenn ich die Daten übergebe bleibt immer noch das Problem das ich den return wert abfangen muss, sonst habe ich wider eine Leer Ausgabe, wie jetzt auch.
Title: Re: Verständnis frage --> pinMode
Post by: Doc_Arduino on Nov 21, 2014, 11:21 am
Hallo,

nein, digitalRead ist leider nicht schnell genug.
Wenn ich Dich richtig verstehe, möchtest Du jetzt mit dem Code statt einem alle 5 Meßschieber auslesen. Dazu müssen nur die angeschlossenen Pins der 5 Schieber der Funktion übergeben werden zum auslesen. Dafür müssen eigentlich nur die zur Zeit festen Pins durch Variablen ersetzt und beim Funktionsaufruf übergeben werden.

Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 11:35 am
so ähnlich.

ich möchte mir eine Tabelle ausgeben lassen über den Seriellen Monitor.

Eine neue Zeile soll bei einem tasten druck erstellt werden.
         
Schieber 1   Schieber 2   Schieber 3   Schieber 4   Schieber 5   Dehnungsmessstreifen
0.00 mm0.00 mm0.00 mm0.00 mm0.00 mm1.01 Kg
0.00 mm5.00 mm0.00 mm8.00 mm0.00 mm1.01 Kg
7.00 mm5.00 mm3.00 mm2.00 mm9.00 mm1.01 Kg



Jedoch wenn ich in die Funktion nur die PIN Nr. übergebe dann greife ich doch nicht auf das Richtige Register und das Register Bit zu.


Dazu kommt dann noch das du den Rückgabe wert immer per Serial.println(_Result); ausgegeben hast, sprich wenn es keinen gab dann aht er auch nichts ausgegeben, das muss ich nun abfangen sonst stimmt meine Tabelle ja nicht, ich muss einen Wert zurück bekommen sonst muss der Schieber noch mal abgefragt werden damit das richtige Ergebnis an der Richtigen Stelle der Tabelle steht.

Wenn z.B. Schieber 2 nicht ausgelesen wird bzw. keine Wert zurück gibt dann würde keine Ausgabe erfolgen und in der Tabelle bei Schieber 2 würde das Ergebnis vom Schieber 3 stehen etc.


ich hoffe das man versteht was ich gerne machen möchte.
und ihr erkennt mein Problem was ich gerade habe.



EDIT: mir würde es schon reichen wenn ich für jeden Schieber eine Funktion habe in der Fix die PIN Nr. und die Register drin stehen. jedoch ich immer einen Rückgabe wert bekomme, und nicht immer so viele 0.00 zurück bekomme nur weil die if ((millis() - temp_millis) > 100)  nicht zutrifft.
Title: Re: Verständnis frage --> pinMode
Post by: Doc_Arduino on Nov 21, 2014, 11:48 am
Hallo,

Tabelle, nicht alles auf einmal. Die Ausgabeformatierung kannste später machen.

Genau, weil Register-Bit nicht gleich Arduino Pin ist, muß das alles vorher definiert werden. Eben anders wie jetzt, damit es flexibel wird. Du hast doch einen Arduino Mega 2560? Dann könnten wir die Clock's der Schieber und die Data's der Schieber auf je getrennte Ports legen. Das dürfte die Sache vereinfachen, denke ich.

Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 11:52 am
ja ich habe eine Arduino Mega 2560

wir können das auf verschiedene Ports Sätzen das ist für mich kein Problem, wie oben im EDIT erwähnt muss das auch nicht wirklich Flexibel sein. ich kann ja 5 verschidene Funktionen erstellen ;-) für jeden Schieber eine.


Das Problem ist das die if ((millis() - temp_millis) > 100)  nicht zutrifft ich keinen Rückgabe wert habe, und das darf nicht sein, wenn das der Fall ist muss der Schieber weiter ausgelesen werden.

Title: Re: Verständnis frage --> pinMode
Post by: Doc_Arduino on Nov 21, 2014, 12:58 pm
Hallo,

aber alle Schieber einzeln mit "originalen Code"  funktionieren? Dann wird es nur am Code liegen. Dazu brauch ich etwas Ruhe ...

Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 01:20 pm
Ja alle, Schieber funktionieren mit dem von uns ausgearbeiteten Original Code.



so hatte ich mir das zu beginn mal gedacht:
Code: [Select]
#include "Schieber_auslesen.h"     // Datei mit allen Fungzionen für die Messschiber laden
                                   // *.h bzw. *.c jenachdem was da jetzt das richtige ist, ...

int i = 0;      // vortlaufende ID Nr. wird hochgetält bei asugabe einer Neuen Messwert Zeile

void setup()
  {
    Serial.begin(9600);                      // Serielen monitor Definiren  
       // ********* Tabellen Kopf ausgeben
       Serial.print("ID");
       Serial.print("\t");
       Serial.print("Schieber 1");
       Serial.print("\t");
       Serial.print("Schieber 2");
       Serial.print("\t");
       Serial.print("Schieber 3");
       Serial.print("\t");
       Serial.print("Schieber 4");
       Serial.print("\t");
       Serial.print("Schieber 5");
       Serial.print("\t");
       Serial.print("Dehnungsmessstreifen");
       Serial.print("\n");
  }

void loop ()
  {

    if (digitalRead(Taster)== HIGH)           // warten bis Taster betätigt wurde
     {
        i+ = 1;                               // vortlaufende ID Nr. hochzählen
       Serial.print(i);                       // vortlaufende ID Nr. Ausgaben  
       Serial.print("\t");                    // Tabulattor ausgeben  
       Serial.print(Schieber1());             // Schieber Nr. 1 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben  
       Serial.print(Schieber2());             // Schieber Nr. 2 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben  
       Serial.print(Schieber3());             // Schieber Nr. 3 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben  
       Serial.print(Schieber4());             // Schieber Nr. 4 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben  
       Serial.print(Schieber5());             // Schieber Nr. 5 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben  
       Serial.print(Dehnungsmessstreifen());  // Dehnungsmessstreifen auslesen und Wert zurückgeben
       Serial.print("\n");                    // Zeilenumbruch erstellen
     }  // ENDE --> digitalRead(Taster)

  }  // ENDE --> void loop


jedoch bekomme ich oft nur eine 0.00 zurück

Quote
Wenn if ((millis() - temp_millis) > 100)  nicht zutrifft wird nichts zurück gegeben.
Title: Re: Verständnis frage --> pinMode
Post by: Doc_Arduino on Nov 21, 2014, 01:36 pm
Hallo,

den bisherigen Code in eine Lib auslagern funktioniert nicht so einfach. Das habe ich auch noch nie gemacht. Sehe dafür aber auch keine Notwendigkeit. Dein Taster ist auch nicht entprellt.
Was Du vor hast mit Dehnungsmeßstreifen usw.  ist nicht zufällig ein Studium's Projekt? Oder doch für privates basteln?

Ansonsten muß ich mich da erst wieder reindenken ...
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 02:21 pm
mein Test Code habe ich nur mal grob runter geschrieben damit man versteht was ich machen möchte.


Wie gesagt für mich wäre es auch vollkommen OK wenn ich für Jeden Schieber eine separate Funktion habe,
wegen mir muss da keine PIN nr. etc übergeben werden.

Oh ne, ein Studium Projekt ist das nicht, ich Studiere nicht, ich bin im Vertrieb tätig, Beruflich habe ich mit dem Arduino oder mit Elektrik keine Berührungspunkte, das ist alles Privat was ich da mache.

wie gesagt der Code oben sollte nur veranschaulichen wie ich das umschreiben wollte.
dabei wurde mir dann her hinwies gegeben das es an der
Quote
Wenn if ((millis() - temp_millis) > 100)  nicht zutrifft wird nichts zurück gegeben.
Liegt, denn wenn das nicht zutrifft dann bekomme ich 0.00 zurück :-(

habe mir schon überlegt ob ich für Jedes Ergebnis eine Konstante erstelle, die Konstante hat dann das Ergebnis und die Fungzion gibt mir dann 0 bzw 1 zurück, so könnte ich die Fungzion auf True oder false prüfen und so lange die Fungzion aufrufen bis ich ein True bekomme und dann das Ergebnis ausgeben. 

Wäre das ein Ansatz? der in dir Richtige Richtung gehen würde?


oder ich kann dann in der Fungzion Prüfen ob ein Ergebnis erstellt wurde oder auch nicht,
wenn nicht dann wird die die Fungzion nochmal durchgearbeitet.
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 05:44 pm
Quote
habe mir schon überlegt ob ich für Jedes Ergebnis eine Konstante erstelle,
Eine Konstante kann man nicht ändern. Du meinst eine globale Variable. Das ist aber ein ganz schlechter Programmierstil. Wenn dann übergibt man bei sowas für das Ergebnis einen Zeiger oder Referenz als Parameter. Genauso wie bei bestimmten String Funktionen ein Puffer für das Ergebnis übergeben musst.


Das ist bei Float aber nicht nötig. Du kannst hier einfach NAN (not a number) zurückgeben. Das ist ein spezieller Wert, der von keiner richtigen Zahl belegt wird:
http://www.nongnu.org/avr-libc/user-manual/group__avr__math.html#ga8abfcc76130f3f991d124dd22d7e69bc

in math.h gibt es dann auch isnan() fertig:
http://www.nongnu.org/avr-libc/user-manual/group__avr__math.html#ga468be9ed380771eca5a18e812b2470d4
Das liefert 1/true wenn die Variable NaN ist


Den Test per Hand zu machen ist etwas seltsam. Man vergleicht die Zahl mit sich selbst:
if(num != num)

Das ist true nur für NaN
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 06:40 pm
ich verstehe was du meinst, ich bekomme es nur nicht zusammen :-(

mit den Links kann ich irgend wie nichts anfangen  :smiley-cry:  :smiley-cry:

daher habe ich mir einen Kleinen Test Code geschrieben:
Code: [Select]
// ******************************************************
//    NaN Prüfen in einer Funktion
// ******************************************************

#include "math.h"

int Taster = 3;                  // Taster PIN = Nr

void setup()
  {
    Serial.begin(9600);          // Seriele Einstellungen
    pinMode(Taster,  INPUT);     // Taster PIN = Eingang
  }

void loop()
  {
      while ( digitalRead(Taster)== LOW )  { }       // Waren bis Taster gedrückt wurde
      delay(100);                                    // kurze Pause machen damit sich nichts überschlägt
      while ( digitalRead(Taster)== HIGH)  { }       // Waren bis Taster gedrückt wurde

     if(isnan(NaN_Oder_Zahl()))
      {  Serial.println("Rückgabe ist NaN!");  }
      else
      {  Serial.println(NaN_Oder_Zahl());      }
  }
 
// ******************************************************
//         NaN Funktion
// ******************************************************   
 float NaN_Oder_Zahl()
  {
     return NaN;
  }


ich habe jetzt die "math.h" mit eingebunden, und kann somit auf NaN prüfen, die Frage ist nur wie kann ich das Definieren?

denn dabei bekomme ich eine Fehlermeldung:
Code: [Select]
     return NaN;
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 06:47 pm
Das Makro ist NAN nicht NaN. Normalerweise schreibt man NaN in normalem Text, aber solche Makro Konstanten schreibt man nun mal meistens durchgehend in Großbuchstaben. Also NAN.

So steht es hier doch in math.h
#define NAN   __builtin_nan("")
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 07:04 pm
Danke.

Jetzt klappt es:  8)

Danke.

Dann mache ich mich mal dran das in den Code der Schieblehre einzubauen.



ach so das ist der Test Code, der funktioniert:

Code: [Select]
// ******************************************************
//    NaN Prüfen in einer Funktion
// ******************************************************

#include "math.h"

int Taster = 3;                  // Taster PIN = Nr

void setup()
  {
    Serial.begin(9600);          // Seriele Einstellungen
    pinMode(Taster,  INPUT);     // Taster PIN = Eingang
  }

void loop()
  {
      while ( digitalRead(Taster)== LOW )  { }       // Waren bis Taster gedrückt wurde
      delay(100);                                    // kurze Pause machen damit sich nichts überschlägt
      while ( digitalRead(Taster)== HIGH)  { }       // Waren bis Taster gedrückt wurde

     if(isnan(NaN_Oder_Zahl()))
      {  Serial.println("Rückgabe ist NaN!");  }
      else
      {  Serial.println(NaN_Oder_Zahl());      }
  }
 
// ******************************************************
//         NaN Funktion
// ******************************************************   
 float NaN_Oder_Zahl()
  {
     return NAN;
//     return 100;
  }     
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 07:28 pm
Juhu, ich habe es hin bekommen, auch wenn ich der Meinung bin das ich bei der Abfrage von NAN noch was Falsch mache, doch es Klappt :-)

genial.

DANKE an euch alle.



das ist der Code mit einen Schieber.
muss jetzt erst mal noch weg, werde dann später die Anderen Schieber auch noch einbauen, und den Code hier veröffentlichen.

DANKE noch mal an euch alle.


Code: [Select]
#include "math.h"
unsigned long temp_millis;
int Taster = 3;                  // Taster PIN = Nr
int i = 0;

float Ergebnis_Schieber5 = NAN;

void setup()
  {
    Serial.begin(9600);          // Seriele Einstellungen
    pinMode(Taster,  INPUT);     // Taster PIN = Eingang

    // ********* Tabellen Kopf
       Serial.print("ID");
       Serial.print("\t");
       Serial.print("Schieber 1");
       Serial.print("\t");
       Serial.print("Schieber 2");
       Serial.print("\t");
       Serial.print("Schieber 3");
       Serial.print("\t");
       Serial.print("Schieber 4");
       Serial.print("\t");
       Serial.print("Schieber 5");
       Serial.print("\t");
       Serial.print("Dehnungsmessstreifen");
       Serial.print("\n");
    // ********* Tabellen Kopf
  }
 
void loop()
  {
      while ( digitalRead(Taster)== LOW )  { }       // Waren bis Taster gedrückt wurde
      delay(100);                                    // kurze Pause machen damit sich nichts überschlägt
      while ( digitalRead(Taster)== HIGH)  { }       // Waren bis Taster gedrückt wurde

        i = i + 1;                            // vortlaufende ID Nr. hochzählen
       Serial.print(i);                       // vortlaufende ID Nr. Ausgaben 
       Serial.print("\t");                    // Tabulattor ausgeben 
       Serial.print(Schieber1());             // Schieber Nr. 1 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben 
       Serial.print(Schieber2());             // Schieber Nr. 2 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben 
       Serial.print(Schieber3());             // Schieber Nr. 3 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben 
       Serial.print(Schieber4());             // Schieber Nr. 4 Auslesen udn Wert zurück geben
       Serial.print("\t");                    // Tabulattor ausgeben 
       
          while ( isnan(Ergebnis_Schieber5) )  { Ergebnis_Schieber5 = Schieber5(); }   // Schieber Nr. 5 Auslesen udn Wert zurück geben
          Serial.print(Ergebnis_Schieber5);
          Ergebnis_Schieber5 = NAN;

       Serial.print("\t");                    // Tabulattor ausgeben 
       Serial.print(Dehnungsmessstreifen());  // Dehnungsmessstreifen auslesen und Wert zurückgeben
       Serial.print("\n");                    // Zeilenumbruch erstellen

  }  // ENDE --> void loop



float Schieber1()
  {
   
  }  // ENDE --> Schieber1
 
float Schieber2()
  {
  }  // ENDE --> Schieber2   
 
float Schieber3()
  {
  }  // ENDE --> Schieber3

float Schieber4()
  {
  }  // ENDE --> Schieber4

float Schieber5()
  {
    int Schieber_5_ClockPin = 24;  // Pin 24 das 2. Bit vom Port A (PINA PA2)
    int Schieber_5_DataPin  = 25;  // Pin 25 das 3. Bit vom Port A (PINA PA3)

    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);

    while (digitalRead(Schieber_5_ClockPin) == LOW) {}    // wenn CLOCK auf LOW, dann warten bis wieder HIGH
    temp_millis = millis();                               // aktuelle Zeitnahme
    while (digitalRead(Schieber_5_ClockPin) == HIGH) {}   // wenn CLOCK auf HIGH, warten bis wieder LOW
    if ((millis() - temp_millis) > 100)                   // wenn High-Pegel länger wie 100ms war, springe in 'decode' Funktion
      {

        long value = 0;
        byte SIGN_Bit = 0;                          // Vorzeichen Bit 21
     
          for (int i=0;i<24;i++)                    // 24 Durchläufe, 0 bis 23
            {           
              if ( PINA & ( 1 << PA3 ))             // wenn Data (Port.A Bit.3) HIGH ist,
                {                                   // eine 1 in die Variable 'value' an Bitnummer i
                  value |= 1UL << i;                // Syntax Hinweis aus dem Forum, wegen default 16 bit int Arithmetik
                }
                while ( !(PINA & (1 << PA2)))  { }  // solange warten bis Clock (Port.A Bit.2) wieder HIGH ist
                while (   PINA & (1 << PA2 ))  { }  // solange warten bis Clock (Port.A Bit.2) wieder LOW ist
            }  // for Schleifenende
   
           SIGN_Bit = (value >> 21) & B01;          // Vorzeichen Bit 21 separieren
           value = value & 0xFFFF;                  // nur Bit 0 bis Bit 15 behalten, den Rest davor nullen
           value = value >> 1;                      // und alles um ein Bit nach rechts schieben, Startsignal wird entfernt
           if (SIGN_Bit == 1)                       // wenn Vorzeichen-Bit gesetzt war, alles mit -1 multiplizieren
            { value = value * -1; }
//         Serial.println((float)value / 100);      // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)
         return (float)value / 100;                 // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)
        }
        return NAN;                                 // Fehlerwert ausgeben
  }  // ENDE --> Schieber5
 
float Dehnungsmessstreifen()
  {
  }  // ENDE --> Dehnungsmessstreifen 
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 08:09 pm
Wieso übergibst nicht einfach den den Port und die Pin Nummer als Parameter?

So wie du das machen willst, verlierst du nämlich den eigentlich Sinn von Funktionen. Die Wiederverwertbarkeit von Code

Allgemeiner Test Code für die LED an Pin 13 (PB5):
Code: [Select]

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  blink(&PORTB, PB5);
  delay(500);
}

void blink(volatile byte* port, byte pin)
{
  *port ^= _BV(pin);   //Pin mit XOR invertieren
}



Könnte bei dir dann so aussehen:
Code: [Select]

float schieber(volatile byte* port, byte pin1, byte pin2)
{
}


Siehe auch hier:
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass

Das erzeugt aber auch etwas Overhead durch die indirekte Adressierung über Zeiger. Sollte aber hier noch kein Problem sein.


Das hier würde ich mir sparen:
Code: [Select]

int Schieber_5_ClockPin = 24;  // Pin 24 das 2. Bit vom Port A (PINA PA2)
int Schieber_5_DataPin  = 25;  // Pin 25 das 3. Bit vom Port A (PINA PA3)

pinMode(Schieber_5_ClockPin, INPUT);
pinMode(Schieber_5_DataPin,  INPUT);

Mach das entweder in setup() oder verwende das DDR Register. Den entsprechenden Pin im DDR Register auf 1 = Ausgang, 0 = Eingang.
Wobei das in setup() vollkommen reicht, da es sich nie ändert. Wieso das also bei jedem Funktionsaufruf neu machen?

Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 10:52 pm
oh mann, du machst mich noch fertig.

das muss ich mir in ruhe anschauen wenn ich wieder am pc bin, wäre schon cool wenn das mit einer Funktion gehen würde.

ps. ja ich weiss das wie ich es aktuell mache überhaupt nicht perfekt ist.
jedoch ist das mein aktueller wissen stand.
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 11:04 pm
Das ist eigentlich ganz einfach. Die Pin Nummer kannst du als Byte übergeben. Nichts ungewöhnliches daran.

Den Port musst du als Zeiger übergeben und dieser muss volatile sein, weil das Register so in der avr libc definiert ist. Daher einfach volatile byte* port als Parameter. Wenn man direkt PORTB als byte übergeben würden, hätte man den Inhalt des Registers!

Bei Aufruf übergibt man dann mit & die Adresse: &PORTB
Genauso wie bei Zeigern allgemein.

Und wenn du den Port ansprichst musst du den Zeiger mit * dereferenzieren:
*port =
Damit du das hast worauf der Zeiger zeigt und nicht etwas auf die Zeiger-Variable selbst zuweist.

Und bei PINA geht das genauso.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 21, 2014, 11:40 pm
du darfst nicht so schnell mit mir das machen, ... ich bin nicht vom Fach :-(


Kannst das Beispiel:
Quote
Allgemeiner Test Code für die LED an Pin 13 (PB5):
mal genauer erklären, .. ich komme da nicht ganz mit.
könnten wir da einen Test Code machen mit dem wir die LED 13 Blinken lassen über die Register ?
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 21, 2014, 11:57 pm
Quote
könnten wir da einen Test Code machen mit dem wir die LED 13 Blinken lassen über die Register ?
Das ist genau was der Code macht. Lediglich um den Ausgang zu setzen, habe ich pinMode() verwendet.

Was gibt es da groß zu erklären? Das sind doch nur drei Zeilen die was interessantes enthalten und die habe ich schon erklärt :s

Code: [Select]

void blink(volatile byte* port, byte pin)
{
  *port ^= _BV(pin);   //Pin mit XOR invertieren
}

Eine Funktion die einen Zeiger auf ein Port Register und eine Pin Nummer als Parameter hat.

^= ist ein Exlusiv-Oder:
http://de.wikipedia.org/wiki/Kontravalenz
Das invertiert wie der Kommentar sagt den Pin

_BV() steht für "bit value" und ist lediglich ein Makro für "1 << n"
Mann kann genauso *port ^= 1 << pin schreiben

Wichtig ist hier das * vor "port", da du den Inhalt der Adresse ansprechen willst und nicht die Adresse selbst.

Und beim Aufruf übergibt man wie gesagt mit & die Adresse (ein Zeiger ist nichts anderes als eine Adresse):
Code: [Select]

blink(&PORTB, PB5);



Du würdest es so ähnlich machen:
Code: [Select]

float schieber(volatile byte* port, byte clock, byte data)
{
    if ( *port & ( 1 << data ))
      ....
 
    while ( !(*port & (1 << clock)))  { }

   ....
}


Und so aufrufen:
Code: [Select]

float value = schieber(&PINA, PA2, PA3);


Sollte rein theoretisch funktionieren.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 22, 2014, 12:05 am
Wir bleiben bei dem Blinkenden Beispiel.


hier Blinkt meine LED an PIN 13
Code: [Select]
void setup()
  {
    pinMode(13, OUTPUT);
  }

void loop()
  {
    digitalWrite(13, HIGH);   
    delay(1000);             
    digitalWrite(13, LOW);   
    delay(1000);           
  }



bei deinem Code Blinkt die LED nicht
Code: [Select]

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  blink(&PORTB, PB5);
  delay(500);
}

void blink(volatile byte* port, byte pin)
{
  *port ^= _BV(pin);   //Pin mit XOR invertieren
}



du weist doch ich bin nicht der schnellste bei der Sache.
Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 22, 2014, 12:13 am
Moment. Du bist auf einem Mega, oder?  PB5 ist für den UNO. Auf dem Mega ist Pin 13 -> PB7

Im zweifelsfall nachsehen:
http://greentechhobby.com/images/Arduino/ArduinoMega.pdf
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 22, 2014, 12:16 am
ja ok das erklärt einiges,

jetzt habe ich eine Fungzion die ich untersuchen kann, mal schauen ob ich das jetzt in meinen Schieber Code dann auch übertragen bekomme.

Dann mache ich mal eine Neue Datei für den Schieber Test :-)
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 22, 2014, 12:45 am
Bis jetzt mache ich glaube ich gute Fortschritte :-)

die Originalzeile habe ich immer Auskommentiert und darunter die Neue Zeile mit dem Variablem Port Bezeichnung geätzt.

das ist der Bisherige Code:
Code: [Select]
#include "math.h"
unsigned long temp_millis;

void setup()
  {
    Serial.begin(9600);          // Seriele Einstellungen
  }
 
void loop()
  {
    float Ergebnis_Schieber = NAN;
//    while ( isnan(Ergebnis_Schieber) )  { Ergebnis_Schieber = Schieber(); }   // Schieber abfragen
    while ( isnan(Ergebnis_Schieber) )  { Ergebnis_Schieber = Schieber(&PINA, PA0, PA1); }   // Schieber abfragen

   
    Serial.println(Ergebnis_Schieber);                                        // Schieber Wert ausgeben
  }  // ENDE --> void loop



// float Schieber()
float Schieber(volatile byte* port, byte clock, byte data)
  {
    int Schieber_5_ClockPin = 22;  // Pin 22 das 0. Bit vom Port A (PINA PA0)
    int Schieber_5_DataPin  = 23;  // Pin 23 das 1. Bit vom Port A (PINA PA1)

    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);

//    while (digitalRead(Schieber_5_ClockPin) == LOW) {}    // wenn CLOCK auf LOW, dann warten bis wieder HIGH
    while ( !(*port & (1 << clock)) ) {}                    // wenn CLOCK auf LOW, dann warten bis wieder HIGH

    temp_millis = millis();                                 // aktuelle Zeitnahme
//    while (digitalRead(Schieber_5_ClockPin) == HIGH) {}   // wenn CLOCK auf HIGH, warten bis wieder LOW
    while ( *port & (1 << clock) ) {}                       // wenn CLOCK auf HIGH, warten bis wieder LOW

    if ((millis() - temp_millis) > 100)                     // wenn High-Pegel länger wie 100ms war, springe in 'decode' Funktion
      {

        long value = 0;
        byte SIGN_Bit = 0;                          // Vorzeichen Bit 21
     
          for (int i=0;i<24;i++)                    // 24 Durchläufe, 0 bis 23
            {           
//              if ( PINA & ( 1 << PA1 ))             // wenn Data (Port.A Bit.1) HIGH ist,
              if ( *port & ( 1 << data ))             // wenn Data (Port.A Bit.1) HIGH ist,
                {                                   // eine 1 in die Variable 'value' an Bitnummer i
                  value |= 1UL << i;                // Syntax Hinweis aus dem Forum, wegen default 16 bit int Arithmetik
                }
//                while ( !(PINA & (1 << PA0)))  { }  // solange warten bis Clock (Port.A Bit.0) wieder HIGH ist
                while ( !(*port & (1 << clock)))  { }  // solange warten bis Clock (Port.A Bit.0) wieder HIGH ist

//                while (   PINA & (1 << PA0 ))  { }  // solange warten bis Clock (Port.A Bit.0) wieder LOW ist
                while (   *port & (1 << clock ))  { }  // solange warten bis Clock (Port.A Bit.0) wieder LOW ist

            }  // ENDE --> for Schleife
   
           SIGN_Bit = (value >> 21) & B01;          // Vorzeichen Bit 21 separieren
           value = value & 0xFFFF;                  // nur Bit 0 bis Bit 15 behalten, den Rest davor nullen
           value = value >> 1;                      // und alles um ein Bit nach rechts schieben, Startsignal wird entfernt
           if (SIGN_Bit == 1)                       // wenn Vorzeichen-Bit gesetzt war, alles mit -1 multiplizieren
            { value = value * -1; }
         return (float)value / 100;                 // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)
        }
        return NAN;                                 // Fehlerwert ausgeben
  }  // ENDE --> Schieber




ich möchte jetzt aber noch den teil:
Code: [Select]
    int Schieber_5_ClockPin = 22;  // Pin 22 das 0. Bit vom Port A (PINA PA0)
    int Schieber_5_DataPin  = 23;  // Pin 23 das 1. Bit vom Port A (PINA PA1)

    pinMode(Schieber_5_ClockPin, INPUT);
    pinMode(Schieber_5_DataPin,  INPUT);


über die Register Sätzen.

Das müsste dann das Register DDRx sein.

und ich muss dann also
*port & clock = 0;


machen?

doch das macht eine Fehlermeldung, ... die Frage ist wie kann ich das Bit Sätzen?
ich dachte ich rufe das Register mit den Registerbit auf und sage das das Gleich 0 für Eingang ist.

Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 22, 2014, 01:56 am
Verwende halt pinMode() hier. Das muss doch nicht so schnell gehen

Ansonsten nimm am einfachsten die vordefinierten Makros um Bits zu setzen und zu löschen:
http://arduino.cc/en/Reference/BitSet
http://arduino.cc/en/Reference/BitClear

Code: [Select]
bitClear(DDRA, PA2);
bitClear(DDRA, PA3);


Und mach das in setup()!
Title: Re: Verständnis frage --> pinMode
Post by: sschultewolter on Nov 22, 2014, 02:31 am
und ich muss dann also
*port & clock = 0;

Was is das für eine Anweisung?


Wenn dann sowas in der Art

Code: [Select]

void func(volatile uint8_t *port, uint8_t mask)
{
 *port |= mask;
 
}

Title: Re: Verständnis frage --> pinMode
Post by: Serenifly on Nov 22, 2014, 03:04 am
Das ist um ein Bit zu setzten. Um es zu löschen muss man mit dem Inversen verunden. Gerade hier sollte man wirklich die vorhanden Makros verwenden, wenn man da genaue Syntax nicht kennt.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 22, 2014, 11:27 am
Was is das für eine Anweisung?
da ich nicht wusste wie man das macht war das eine für mich Logische Erklärung das ich so ein Bit im Register Sätzen kann :-)

Lag irgend wie daneben;  :-*  :-*

Verwende halt pinMode() hier. Das muss doch nicht so schnell gehen
Du hast recht das muss nicht schnell gehen, dachte mir nur das wenn ich jetzt clock udn data
schon übergebe dann könnte ich hier auch den Typ des Pin`s definieren,
und  pinMode deshalb nicht da ich ja die Nr. nicht übergebe.
aus dem Grund dachte ich das ich das auch über das Register machen könnte.

Und mach das in setup()!
ist das Schlimm wenn ich die x mal hintereinander neu Sätze?
ich dachte mir das ich so keinen PIN vergessen kann ihn zu Sätzen, wenn
ich das in der Funktion habe.
ich muss jetzt noch das DDRA mit übergeben.
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 22, 2014, 11:48 am
so ich habe das gerade mal mit zwei Schiebern getestet :-)

und ich bin begeistert, DANKE DANKE DANKE

das ist echt genial.


hier mein Code.
Werde denn jetzt noch etwas Mehr an Kommentaren geben das ich auch später noch wies was ich wo eingeben muss.  :smiley-mr-green:


Code: [Select]
#include "math.h"
  unsigned long temp_millis;
  float Ergebnis_Schieber = NAN;                                  // Ergebnis der Schieblehre nullen

void setup()
  {
    Serial.begin(9600);          // Seriele Einstellungen

       Serial.print("Schieber 4");
       Serial.print("\t");
       Serial.println("Schieber 5");

  }
 
void loop()
  {
// Schiber 4 Ausgeben     --> PIN 24 & 25
    Ergebnis_Schieber = NAN;                                        // Ergebnis der Schieblehre nullen
    while ( isnan(Ergebnis_Schieber) )                              // Plausibilitätskontrolle
      { Ergebnis_Schieber = Schieber(&DDRA, &PINA, PA2, PA3); }     // Schieber abfragen
    Serial.print(Ergebnis_Schieber);                                // Schieber Wert ausgeben

       Serial.print("\t");

// Schiber 5 Ausgeben     --> PIN 22 & 23
    Ergebnis_Schieber = NAN;                                        // Ergebnis der Schieblehre nullen
    while ( isnan(Ergebnis_Schieber) )                              // Plausibilitätskontrolle
      { Ergebnis_Schieber = Schieber(&DDRA, &PINA, PA0, PA1); }     // Schieber abfragen
    Serial.println(Ergebnis_Schieber);                              // Schieber Wert ausgeben
  }  // ENDE --> void loop



float Schieber(volatile byte* DDRport, volatile byte* PINport, byte clock, byte data)
  {
   
    bitClear(*DDRport, clock);                            // PIN auf eingang sätzen
    bitClear(*DDRport, data);                             // PIN auf eingang sätzen
   
    while ( !(*PINport & (1 << clock)) ) {}               // wenn CLOCK auf LOW, dann warten bis wieder HIGH

    temp_millis = millis();                               // aktuelle Zeitnahme
    while ( *PINport & (1 << clock) ) {}                  // wenn CLOCK auf HIGH, warten bis wieder LOW

    if ((millis() - temp_millis) > 100)                   // wenn High-Pegel länger wie 100ms war, springe in 'decode' Funktion
      {

        long value = 0;
        byte SIGN_Bit = 0;                                // Vorzeichen Bit 21
     
          for (int i=0;i<24;i++)                          // 24 Durchläufe, 0 bis 23
            {           
              if ( *PINport & ( 1 << data ))              // wenn Data (Port.A Bit.1) HIGH ist,
                {                                         // eine 1 in die Variable 'value' an Bitnummer i
                  value |= 1UL << i;                      // Syntax Hinweis aus dem Forum, wegen default 16 bit int Arithmetik
                }
                while ( !(*PINport & (1 << clock)))  { }  // solange warten bis Clock (Port.A Bit.0) wieder HIGH ist

                while (   *PINport & (1 << clock ))  { }  // solange warten bis Clock (Port.A Bit.0) wieder LOW ist

            }  // ENDE --> for Schleife
   
           SIGN_Bit = (value >> 21) & B01;                // Vorzeichen Bit 21 separieren
           value = value & 0xFFFF;                        // nur Bit 0 bis Bit 15 behalten, den Rest davor nullen
           value = value >> 1;                            // und alles um ein Bit nach rechts schieben, Startsignal wird entfernt
           if (SIGN_Bit == 1)                             // wenn Vorzeichen-Bit gesetzt war, alles mit -1 multiplizieren
            { value = value * -1; }
         return (float)value / 100;                       // Kommastelle setzen und man erhält den endgültigen Meßwert  (Rückgabe wert)
        }
        return NAN;                                       // Fehlerwert ausgeben
  }  // ENDE --> Schieber
Title: Re: Verständnis frage --> pinMode
Post by: Doc_Arduino on Nov 22, 2014, 12:15 pm
Hallo,

oh, hier ging es ja schon rege weiter. Sehr schön. Jetzt weis ich gar nicht ob mein Vorschlag noch benötigt wird. Ich stell ihn dennoch zur Verfügung. Vielleicht für Anregungen. Einmal mit 5 Funktionsaufrufen für die 5 Meßschieber. Und einmal in einer for Schleife zusammengefasst und einen Notausstieg falls bei einem Meßschieber das Clocksignal fehlt, wegen Kabelbruch oder sonstigen. Kannste ja mal testen.

Edit:
im zweiten Code "c" Fehler korrigiert, Notaus Variable für zweite Verwendung wurde nicht genullt
Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 22, 2014, 01:01 pm
Hey Doc,

ja es hat sich einiges getan, es ist wirklich Sau doof das die Benachrichtigungen immer noch nicht gehen vom Forum (Hoffe das es bald wider geht).


Natürlich werde ich deinen Code noch testen und vilecht kann man das dann verbinden. 
denn einen Notausstieg habe ich nicht bei mir :-)

 

Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 23, 2014, 02:13 pm
so ich habe meinen Code zusammen geschrieben und auch alle Kommentare eingefügt,
die Funktion habe ich in eine *.h Datei ausgelagert (warum auch immer die ohne eine *.c Datei auskommt).

Leider habe ich noch keinen Idee wie ich das NAN aus der Funktion raus bekomme,
am besten wäre ein GOGO Anfang (ducken und weg hier... ) da man so was jedoch nicht schreibt verwende ich das nicht, es gibt bestimmt noch meine andere Lösung wie man das machen kann, jedoch ist mir bisher noch keine bekannt dafür :-(.

So klappt es aber schon sehr gut :-) und ich bin sehr zufrieden, bzw. das ist schon viel mehr als ich jemals erhofft habe hin zu bekommen.

Danke an alle die mitgewirkt haben.
Ich werde das auch noch mal im eigentlichen Thema der "Schieblehre - Arduino Versuchsaufbau (http://forum.arduino.cc/index.php?topic=273445.new#new)" Verlinken.
Title: Re: Verständnis frage --> pinMode
Post by: Doc_Arduino on Nov 23, 2014, 03:13 pm
Hallo,

die .h wird, denke ich, deshalb funktionieren, weil das eine reine Funktion ist die ausgelagert wurde. Macht aus meiner Sicht keinen Sinn. Deine 5 Meßschieber sind doch alle angeschlossen? Warum definierst Du die Eingänge mit jeden Funktionsaufruf neu? Das gehört einmalig in setup rein. Ansonsten, wenn's funktioniert ...

Title: Re: Verständnis frage --> pinMode
Post by: Muecke on Nov 23, 2014, 06:00 pm
das ausgelagerte verschafft mir mehr übersieht in meiner *.ino Datei so habe ich das Gefühl des Überblick wider.
Du weist doch alles muss seine Ordnung haben, ... ;)


das ist richtig: definieren der Eingänge, wird im Setup vorgenommen,
aus "Angst" eine nicht zu definieren habe ich das in die Funktion mit rein gepackt.


ich möchte den !Notausteig! von dir noch mit einbauen, das finde ich genial.