Go Down

Topic: Wo definiert man sauber Variablen ? (Read 2678 times) previous topic - next topic

kimmi

Jun 29, 2009, 10:04 pm Last Edit: Jun 29, 2009, 10:09 pm by oren Reason: 1
Mir ist aufgefallen, dass man Variablen im Void Setup und im Void Loop definieren kann.
Nun dachte ich, dass alle Variablen, die ich im Setup definiert habe auch für den Loop und die Funktionen definiert sind, ich bekommen allerdings regelmäßig Probleme damit.
Wann muss den eine Variable im Loop und wann im Void definiert werden?

Zum zweiten stelle ich fest, dass in der Literatur Variablen manchmal mit #define VARIABLE WERT und manchmal einfach mit int VARIABLE = WERT; definiert werden, was ist denn da der Unterschied?

kimmi

Hier ein Beispiel bei dem ich eine Fehlermedlung bekommen:
Code: [Select]
// Selbsttest//
// Pinbelegung//
// analog 0 = PIR, analog 1 = Fotodiode, analog 2 = Thermistor //
// digital 13 = Led, digital 12 = Vibrationsmotor, digital 2-6 = Transceiver //

void setup (){
 pinMode (13, OUTPUT);
 pinMode (12, OUTPUT);
 // analog Pins brauchen nicht defineirt zu werden, da immer Output //
 
 int sensorpin = 0; // Sensorpin der ausgelesen wird //
 int sensorwert = 0; // Sensorwert der ausgelesen wird //
 int senorcut = 0; //  Filter-Wert der vom Sensorwert abgezogen wird um Rauschen zu unterdrücken //
 int sensormulti = 0; // Filter-Multiplikator zur Verstärkung //
 int sensorteiler = 0; // Filter-Aufteilungswert um auf ein Byte - 0-255 - fürs funken zu kommen //
 int sensorclean = 0; // Wert der nach der Berechung von der Funktion zurückgegeben wird //
 
 int sensor0 = 0; // Speichervariable für Sensor Pin 0 //
 int sensor1 = 0; // Speichervariable für Sensor Pin 1 //
 int sensor2 = 0; // Speichervariable für Sensor Pin 2 //
 
}

void loop () {
 
 // Sensor 0, PIR der PIR sendet nur 0 oder 683/684, kann auch an einen digital Eingang, die werden aber knapp //
 sensorpin = 0; // der PIR ist an analog 0 //
 sensorcut = 0; // braucht keine Filter //
 sensormulti = 0; // braucht keinen Filter //
 sensorteiler = 10; // dann kommt ca 6 raus //
 
 int sensor0 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 
 // Sensor 1, Fotodiode Werte zwischen 30(dunkel) und 1000 (Taschenlampe direkt) //
 sensorpin = 1; // der Fotodiode ist an analog 1 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 3-100 //
 
 int sensor1 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 
 // Sensor 2, Thermistor Werte zwischen 477(Eiswürfel) 340 (ca 20°) 240 (ca 37°) //
 sensorpin = 2; // der Thermistor ist an analog 2 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 48-24 //
 
 int sensor2 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 }
 
 // Funktion Sensorlies //
 int Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler){
   sensorwert = digitalRead (sensorpin); // sensorwert wurde schon global definiert, ob das geht ? //
   sensorclean = ((sensorwert - sensorcut) * sensormulti) / sensorteiler; // Filter auf sensowert anweden //
  return sensorclean; // sensorclean zurückgeben //
  }


Fehlermeldung:

Code: [Select]
error: 'sensorpin' was not declared in this scope In function 'void loop()':
At global scope:


kimmi

Dann habe ich es geändert und die Variablen im Loop definiert und siehe da:

Code: [Select]
// Selbsttest//
// Pinbelegung//
// analog 0 = PIR, analog 1 = Fotodiode, analog 2 = Thermistor //
// digital 13 = Led, digital 12 = Vibrationsmotor, digital 2-6 = Transceiver //

void setup (){
 pinMode (13, OUTPUT);
 pinMode (12, OUTPUT);
 // analog Pins brauchen nicht defineirt zu werden, da immer Output //
 
 int sensorpin = 0; // Sensorpin der ausgelesen wird //
 int sensorwert = 0; // Sensorwert der ausgelesen wird //
 int senorcut = 0; //  Filter-Wert der vom Sensorwert abgezogen wird um Rauschen zu unterdrücken //
 int sensormulti = 0; // Filter-Multiplikator zur Verstärkung //
 int sensorteiler = 0; // Filter-Aufteilungswert um auf ein Byte - 0-255 - fürs funken zu kommen //
 int sensorclean = 0; // Wert der nach der Berechung von der Funktion zurückgegeben wird //
 
 int sensor0 = 0; // Speichervariable für Sensor Pin 0 //
 int sensor1 = 0; // Speichervariable für Sensor Pin 1 //
 int sensor2 = 0; // Speichervariable für Sensor Pin 2 //
 
}

void loop () {
 
 int sensorpin = 0; // Sensorpin der ausgelesen wird //
 int sensorwert = 0; // Sensorwert der ausgelesen wird //
 int senorcut = 0; //  Filter-Wert der vom Sensorwert abgezogen wird um Rauschen zu unterdrücken //
 int sensormulti = 0; // Filter-Multiplikator zur Verstärkung //
 int sensorteiler = 0; // Filter-Aufteilungswert um auf ein Byte - 0-255 - fürs funken zu kommen //
 int sensorclean = 0; // Wert der nach der Berechung von der Funktion zurückgegeben wird //
 
 int sensor0 = 0; // Speichervariable für Sensor Pin 0 //
 int sensor1 = 0; // Speichervariable für Sensor Pin 1 //
 int sensor2 = 0; // Speichervariable für Sensor Pin 2 //
 
 // Sensor 0, PIR der PIR sendet nur 0 oder 683/684, kann auch an einen digital Eingang, die werden aber knapp //
 sensorpin = 0; // der PIR ist an analog 0 //
 sensorcut = 0; // braucht keine Filter //
 sensormulti = 0; // braucht keinen Filter //
 sensorteiler = 10; // dann kommt ca 6 raus //
 
 int sensor0 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 
 // Sensor 1, Fotodiode Werte zwischen 30(dunkel) und 1000 (Taschenlampe direkt) //
 sensorpin = 1; // der Fotodiode ist an analog 1 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 3-100 //
 
 int sensor1 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 
 // Sensor 2, Thermistor Werte zwischen 477(Eiswürfel) 340 (ca 20°) 240 (ca 37°) //
 sensorpin = 2; // der Thermistor ist an analog 2 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 48-24 //
 
 int sensor2 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 }
 
 // Funktion Sensorlies //
 int Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler){
   sensorwert = digitalRead (sensorpin); // sensorwert wurde schon global definiert, ob das geht ? //
   sensorclean = ((sensorwert - sensorcut) * sensormulti) / sensorteiler; // Filter auf sensowert anweden //
  return sensorclean; // sensorclean zurückgeben //
  }


wieder falsch:
Code: [Select]
error: 'sensorpin' was not declared in this scope In function 'void loop()':
At global scope:

kimmi

Also wo ist denn bloß der Fehler?

madworm

#4
Jun 30, 2009, 12:55 am Last Edit: Jun 30, 2009, 01:15 am by madworm Reason: 1
Code: [Select]
// Selbsttest//
// Pinbelegung//
// analog 0 = PIR, analog 1 = Fotodiode, analog 2 = Thermistor //
// digital 13 = Led, digital 12 = Vibrationsmotor, digital 2-6 = Transceiver //

void setup (){
 pinMode (13, OUTPUT);
 pinMode (12, OUTPUT);
 // analog Pins brauchen nicht defineirt zu werden, da immer Output //
}

void loop () {
 int sensorpin = 0; // Sensorpin der ausgelesen wird //
 int sensorwert = 0; // Sensorwert der ausgelesen wird //
 int sensorcut = 0; //  Filter-Wert der vom Sensorwert abgezogen wird um Rauschen zu unterdrücken //
 int sensormulti = 0; // Filter-Multiplikator zur Verstärkung //
 int sensorteiler = 0; // Filter-Aufteilungswert um auf ein Byte - 0-255 - fürs funken zu kommen //

 int sensor0 = 0; // Speichervariable für Sensor Pin 0 //
 int sensor1 = 0; // Speichervariable für Sensor Pin 1 //
 int sensor2 = 0; // Speichervariable für Sensor Pin 2 //

 // Sensor 0, PIR der PIR sendet nur 0 oder 683/684, kann auch an einen digital Eingang, die werden aber knapp //
 sensorpin = 0; // der PIR ist an analog 0 //
 sensorcut = 0; // braucht keine Filter //
 sensormulti = 0; // braucht keinen Filter //
 sensorteiler = 10; // dann kommt ca 6 raus //

 sensor0 = Sensorlies(sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //

 // Sensor 1, Fotodiode Werte zwischen 30(dunkel) und 1000 (Taschenlampe direkt) //
 sensorpin = 1; // der Fotodiode ist an analog 1 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 3-100 //

 sensor1 = Sensorlies(sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //

 // Sensor 2, Thermistor Werte zwischen 477(Eiswürfel) 340 (ca 20°) 240 (ca 37°) //
 sensorpin = 2; // der Thermistor ist an analog 2 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 48-24 //

 sensor2 = Sensorlies(sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //

 }

 // Funktion Sensorlies //
 int Sensorlies(int sensorpin, int sensorcut, int sensormulti, int sensorteiler){
   int sensorwert = digitalRead (sensorpin); // sensorwert wurde schon global definiert, ob das geht ? //
   int sensorclean = ((sensorwert - sensorcut) * sensormulti) / sensorteiler; // Filter auf sensowert anweden //
  return sensorclean; // sensorclean zurückgeben //
  }


es gab ein paar schreibfehler und du hattest in der funktions-deklaration von Sensorlies vergessen, den datentyp der eingangsvariablen anzugeben. variablen, die innerhalb einer funktion definiert werden, sind local. definierst du ausserhalb von setup() bzw. loop(), dann ist die variable global. das verwenden von "#define name wert" ist eine compiler direktive und die ersetzung erfolgt waehrend des compilierens. das hat den gleichen effekt, also wuerdest du von hand anstelle des names ueberall selbst den wert reinschreiben. ich verwende es haeufig fuer konstanten, die ich je nach anwendung anpasse und die firmware neu compiliere. waehrend das programm laeuft, kann das dann nicht mehr geaendert werden.
• Upload doesn't work? Do a loop-back test.
• There's absolutely NO excuse for not having an ISP!
• Your AVR needs a brain surgery? Use the online FUSE calculator.
My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets...
• Microsoft is not the answer. It is the question, and the answer is NO!

kimmi

Hab mich inzwischen mal erkundigt und bin zu dem gleiche ergebnis gekommen, hab die Variablen aber global definiert:

Code: [Select]
// Selbsttest//
// Pinbelegung//
// analog 0 = PIR, analog 1 = Fotodiode, analog 2 = Thermistor //
// digital 13 = Led, digital 12 = Vibrationsmotor, digital 2-6 = Transceiver //

   int sensorpin = 0; // Sensorpin der ausgelsen wird //
 int sensorwert = 0; // Sensorwert der ausgelesen wird //
 int sensorcut = 0; //  Filter-Wert der vom Sensorwert abgezogen wird um Rauschen zu unterdrücken //
 int sensormulti = 0; // Filter-Multiplikator zur Verstärkung //
 int sensorteiler = 0; // Filter-Aufteilungswert um auf ein Byte - 0-255 - fürs funken zu kommen //
 int sensorclean = 0; // Wert der nach der Berechung von der Funktion zurückgegeben wird //
 
 int sensor0 = 0; // Speichervariable für Sensor Pin 0 //
 int sensor1 = 0; // Speichervariable für Sensor Pin 1 //
 int sensor2 = 0; // Speichervariable für Sensor Pin 2 //

 

void setup (){
 pinMode (13, OUTPUT);
 pinMode (12, OUTPUT);
 // analog Pins bruachen nicht defineirt zu werden, da immer Output //
 
}

void loop () {
 
 // Sensor 0, PIR der PIR sendet nur 0 oder 683/684, kann auch an einen digital Eingang, die werden aber knapp //

 sensorcut = 0; // braucht keine Filter //
 sensormulti = 0; // braucht keinen Filter //
 sensorteiler = 10; // dann kommt ca 6 raus //
 
 int sensor0 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 
 // Sensor 1, Fotodiode Werte zwischen 30(dunkel) und 1000 (Taschenlampe direkt) //
 sensorpin = 1; // der Fotodiode ist an analog 1 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 3-100 //
 
 int sensor1 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 
 // Sensor 2, Thermistor Werte zwischen 477(Eiswürfel) 340 (ca 20°) 240 (ca 37°) //
 sensorpin = 2; // der Thermistor ist an analog 2 //
 sensorcut = 0; // rauscht nicht //
 sensormulti = 0; // braucht keine Verstärkung //
 sensorteiler = 10; // ergibt Werte von 48-24 //
 
 int sensor2 = Sensorlies (sensorpin, sensorcut, sensormulti, sensorteiler); // Funktion Sensorlies aufrufen //
 
 }
 
 // Funktion Sensorlies //
 int Sensorlies (int funktionpin, int funktioncut, int funktionmulti, int funktionteiler){ // Bezeichnungen für Parameter //
   int funktionwert = digitalRead (funktionpin);
   sensorclean = ((funktionwert - funktioncut) * funktionmulti) / funktionteiler; // Filter auf sensowert anweden //
  return sensorclean; // sensorclean zurückgeben //
  }
 


Mir war zum einen nicht klar, dass die Parameter der Funktion nicht gleichzusetzen sind mit den übergebene Variablen, ist aber auch schlecht erklärt in der Reference.

Ich dachte wenn ich Variablen global definiere gelten sie auch für die Funktionen, das sit aber anscheinend nicht der Fall, da sie dort nur an die Funktionsparameter übergeben werden und nicht direkt als Variablen überommen werden.

kimmi

Wenn ich das nun richtig sehe funktioniert das so:

vor dem Void Setup:
> globale Variablen definieren

im Void Setup:
> Pinbelegungen definieren - aber keine Variablen

im Void Loop:
> Variablen nur für den Loop definieren

in Funktionen:
> Werte werden in Parameter übernommen, mit denen berechnet wird und die in der Funktion definiert werden müssen
> gobale Variabeln scheinen aber zu funktionieren

gatonero

Hi Kimmi,

eine ziemlich ausführliche Beschreibung der Gültigkeitsbereiche (=scope) von Variablen findest Du z.B. hier http://c-buch.sommergut.de/Kapitel10/G%FCltigkeitsbereich-von-Variablen.shtml

Viele Grüße aus Aachen
Just For Fun

Go Up