Forum: Mikrocontroller und Digitale Elektronik Variable Analog beschreiben


von Ron B. (simatic)


Lesenswert?

Moin,

ich habe eine Steuerung mit einem Arduino Uno realisiert. In dieser wird 
zur Eingabe ein Potentiometer (10K) an A0 verwendet. Per analogRead wird 
der Wert in die Variable P3_Value geschrieben. Der Sketch arbeitet mit 
P3_Value im Bereich 0-1023. Jetzt möchte ich über zwei digitale Taster, 
an Pin 3 (S10) und Pin 4 (S11), den Wert von S3 auf einen bestimmten 
Wert setzen (S3==1 --> P3_Value=0; S4==1 --> P3_Value=1000). Unabhängig 
von A0. Gleichzeitiges Betätigen der Taster ist nicht möglich.

Meine Logik habe ich unten eingefügt. Leider funktioniert dies so nicht. 
Habt ihr Tipps für mich?

Das komplette Programm ist leider nicht vorhanden.

Liebe Grüße
Ron
1
const int P3 = A0;
2
const int S10 = 3;
3
const int S11 = 4;
4
5
int P3_Value = 0;
6
7
void setup()
8
{
9
  pinMode (S10, INPUT);  //Wenn S10 == 1 soll P3_Value 0 sein.
10
  pinMode (S11, INPUT);  //Wenn S11 == 1 soll P3_Value 1000 sein.
11
}
12
13
void loop()
14
15
{
16
17
  if (S10 == 1 && S11 == 0)
18
19
  {
20
    P3_Value = 0;
21
  }
22
23
  if (S11 == 1 && S10 == 0)
24
25
  {
26
    P3_Value = 1000;
27
  }
28
29
  if (S10 == 0 & S11 == 0)
30
31
  {
32
    P3_Value = analogRead(P3);
33
  }
34
35
}

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ron B. schrieb:
> if (S10 == 0 & S11 == 0)

Tippfehler?

von Ron B. (simatic)


Lesenswert?

Matthias S. schrieb:
> Ron B. schrieb:
>> if (S10 == 0 & S11 == 0)
>
> Tippfehler?

Da hast du mich erwischt. Sind natürlich zwei &&.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Die nächste Frage wäre, ob die Schalter wirklich eine 1 liefern, wenn 
sie aktiv sind.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Vll. wäre die Definition von 'funktioniert nicht so' ganz nett.

Was macht das Programm, wann
Was hättest Du erwartet

Meinem Denken nach sollte der Ablauf so passen - deshalb die Frage, was 
denn nicht funktioniert.

MfG

von Ron B. (simatic)


Lesenswert?

Matthias S. schrieb:
> Die nächste Frage wäre, ob die Schalter wirklich eine 1 liefern, wenn
> sie aktiv sind.

Jap, wurde über den Seriellen Monitor festgestellt. Ich vermute einen 
Logikfehler. Bin noch nicht so lange beim Thema Arduino/µC dabei.

von HG (Gast)


Lesenswert?

Die Tasten werden so nie abgefragt, dazu ist ein Funktionsaufruf wie

if (digitalRead(S10) == HIGH)

notwendig

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ron B. schrieb:
> Jap, wurde über den Seriellen Monitor festgestellt.

Das klingt nun aber so, als wäre das nicht das ganze Programm. Schalter 
schalten auch in der MC Welt meistens gegen Masse und liefern eine 1 am 
Pin, wenn sie offen sind und eine 0 in geschlossenem Zustand.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Die Arduino-Welt macht es Einem leicht, die Schalter so anzuklemmen, wie 
man es gerne hätte.
Auch für mich war früher +5V = 'High'  = AN.
Erst mit den µC und den internen PullUp-Widerständen ergaben sich 
leichte Anpassungen im Hirn :)
(früher hat man auch Register ver-X-odert zum Löschen ... lange ist's 
her)

Trotzdem denke ich, daß eine Abfrage == 1 bzw == HIGH das gleiche 
Ergebnis liefern.

MfG

von Ron B. (simatic)


Lesenswert?

Patrick J. schrieb:
> Hi
>
> Vll. wäre die Definition von 'funktioniert nicht so' ganz nett.
>
> Was macht das Programm, wann
> Was hättest Du erwartet
>
> Meinem Denken nach sollte der Ablauf so passen - deshalb die Frage, was
> denn nicht funktioniert.
>
> MfG

P3_Value hat immer den Wert von P3.


@HG und Matthias S.

Ich werde beide Ansätze prüfen/umsetzen. Leider habe ich grade nicht die 
Möglichkeit den kompletten Sketch zu zeigen.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Jetzt verstehe ich erst den Ansatz von

HG schrieb:
> Die Tasten werden so nie abgefragt, dazu ist ein Funktionsaufruf
> wie
>
> if (digitalRead(S10) == HIGH)
>
> notwendig

Du musst die Tasten erst auslesen, also einer Variable zuweisen.
1
int a=digitalread(S10);
2
int b=digitalread(S11);

Trotzdem müssten dann S10 und S11 '3' bzw. '4' sein, und nicht Null und 
Null :/

Hätte die Bedingungen selber verschachtelt ...
1
  if (S10 == 0 )
2
  {
3
      if (S11 == 0)
4
      {
5
         P3_Value = analogRead(P3);
6
      }else{
7
         P3 = 1000;
8
      }
9
  }else{
10
     P3 = 0;
11
  }

MfG

: Bearbeitet durch User
von Ron B. (simatic)


Lesenswert?

Das Auslesen der Taster mit Schreiben auf eine Variable habe ich 
gemacht.

Was ich nicht ganz verstehe ist, was du mit

Patrick J. schrieb:
> Trotzdem müssten dann S10 und S11 '3' bzw. '4' sein, und nicht Null und
> Null :/

meinst. Diese könne ja nur 1 oder 0 sein.
Durch die verschachtelte Bedingung steige so auch nicht ganz durch, aber 
ich teste sie einfach mal.

von Thomas E. (thomase)


Lesenswert?

Ron B. schrieb:
> meinst. Diese könne ja nur 1 oder 0 sein.

Nein, sie kann  0 und !0 sein. Aber !0 ist nicht unbedingt 1, sondern 
kann auch jeder andere Wert ausser 0 sein.

Du fragst aber explizit auf 1 ab. Das kann schief gehen. Deswegen wird, 
wie schon oben geraten wurde, üblicherweise auf == HIGH abgefragt.

oder in typischer C-Manier:
1
if(a && !b)
2
{
3
  //blablabla
4
}

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Ron B. schrieb:
> const int S10 = 3;
> const int S11 = 4;

Ron B. schrieb:
> if (S10 == 1 && S11 == 0)
>
>   {
>     P3_Value = 0;
>   }
>
>   if (S11 == 1 && S10 == 0)
>
>   {
>     P3_Value = 1000;
>   }

Du definierst eine Konstante, das Konstrukt 'S10' hat den Wert 3
Durch diesen Wert wird auch der 'Pin 3' zu einem Input.

Ron B. schrieb:
> pinMode (S10, INPUT);  //Wenn S10 == 1 soll P3_Value 0 sein.

Dadurch dürfte aber die Abfrage auf ==1 nicht zutreffen, da S10 = 3 ist 
und S10==1 FALSE sein müsste.
Somit dürfte die Abfrage, von Dir gedacht, beide Taster auf LOW zu 
prüfen (also S10 == 0 && S11 == 0) nicht zutreffen und P3 somit NICHT 
den Wert des AnalogRead annehmen.

Verständlich ausgedrückt?

von Ron B. (simatic)


Lesenswert?

Danke fürs erklären. Hab's verstanden. Ich würde in diesem Fall das 
selben erwarten wie du. Die Bedingung zum setzen der Konstanten ist 
jetzt !0 also alles außer 0. Leider ändert sich immer noch nichts, wenn 
ich S10/S11 betätige... P3_Value zeigt immer den Analog Wert an. Ich bin 
echt am Ende mit meinem Latein. :(

von HG (Gast)


Lesenswert?

Dann zeig dein Programm nochmal wie es jetzt aussieht

von Ron B. (simatic)


Lesenswert?

Hier mein Programm. Ich hoffe ich habe die Tipps richtig umgesetzt.

1
const int P3 = A0;
2
const int S10 = 3;
3
const int S11 = 4;
4
5
int P3_Value = 0;
6
7
void setup()
8
{
9
  pinMode (S10, INPUT);  //Wenn S10 == 1 soll P3_Value 0 sein.
10
  pinMode (S11, INPUT);  //Wenn S11 == 1 soll P3_Value 1000 sein.
11
12
13
  _S10_Value = digitalRead(S10);
14
  _S11_Value = digitalRead(S11);
15
}
16
void loop()
17
18
{
19
20
  if (S10 == !0)
21
22
  {
23
    P3_Value = 0;
24
  }
25
26
  if (S11 == !0)
27
28
  {
29
    P3_Value = 1000;
30
  }
31
32
  if (S10 == !1 && S11 == !1)
33
34
  {
35
    P3_Value = analogRead(P3);
36
  }
37
38
}

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Ron B. schrieb:
> const int S10 = 3;

Ron B. schrieb:
> if (S10 == !0)

Ich kenn ja kein Arduino. Aber wenn ich das sehe, ist S10 immer 3. Wo 
wird S10 0? Wo wird der Pin regelmässig eingelesen? In deinem Programm 
sehe ich das nicht.

Ron B. schrieb:
> if (S10 == !1

Das ist auch nicht korrekt.

Die Abfrage, die du machen willst, ist eine Abfrage auf true oder false. 
Dabei gilt: false = 0 und true = !0.

von Einer K. (Gast)


Lesenswert?

Ron B. schrieb:
> Ich hoffe ich habe die Tipps richtig umgesetzt.
Ein bisschen!

Jetzt sehe ich digitalRead().
Aber das Ergebnis der Reads wird immer noch nicht verwendet.
Das solltest du aber tun....

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi
1
const int P3 = A0;
2
const int S10 = 3;
3
const int S11 = 4;
4
5
int P3_Value = 0;
6
7
void setup()
8
{
9
  pinMode (S10, INPUT);  //Wenn S10 == 1 soll P3_Value 0 sein.
10
  pinMode (S11, INPUT);  //Wenn S11 == 1 soll P3_Value 1000 sein.
11
12
}
13
void loop()
14
15
{
16
  _S10_Value = digitalRead(S10);
17
  _S11_Value = digitalRead(S11);
18
19
  if (_S10 == HIGH)
20
21
  {
22
    P3_Value = 0;
23
  }
24
25
  if (_S11 == HIGH)
26
27
  {
28
    P3_Value = 1000;
29
  }
30
31
  if (_S10 == LOW && _S11 == LOW)
32
33
  {
34
    P3_Value = analogRead(P3);
35
  }
36
37
}

== !0 hätte ich so noch nicht gesehen, wenn war das != 0

Da mir das ELSE-Konstrukt nicht bekannt ist, habe ich hier auf ein 
Umstellen verzichtet.
In diesem Code wird bei jedem Durchgang der Zustand beider Taster 
gelesen, und dann damit gearbeitet (_S10 und _S11)

MfG

von Einer K. (Gast)


Lesenswert?

Patrick J. schrieb:
> In diesem Code wird bei jedem Durchgang der Zustand beider Taster
> gelesen,
Ja!

Patrick J. schrieb:
> und dann damit gearbeitet (_S10 und _S11)
Nein!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ron B. schrieb:
> _S10_Value = digitalRead(S10);
>   _S11_Value = digitalRead(S11);

Wie HG schon sehr richtig anmerkte, musst du die Schalter innerhalb der 
loop() abfragen. Und dann deren Wert benutzen. Also z.B.
1
loop () {
2
  _S10_Value = digitalRead(S10);
3
  _S11_Value = digitalRead(S11);
4
5
   if (_S10_Value == HIGH && _S11_Value == LOW) {
6
       // dingens 1
7
      }
8
// und so weiter

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

... ups ... da steht noch 'value' hinter - darf's aber jetzt nicht mehr 
ändern :)

Vll merkt man ja etwas, daß ich mit Arduino noch nicht sooo grün bin ;)

Denke aber, daß die letzten Posts einiges an Klarheit gebracht haben - 
schauen wir Mal.

MfG

von Ron B. (simatic)


Lesenswert?

Thomas E. schrieb:
> Ron B. schrieb:
>> const int S10 = 3;

Damit, so kenne ich es, wird beim Arduino der Pin definiert. In diesem 
Fall Pin3. Ob S10 True oder False ist, hängt von dem Taster ab 5V oder 
0V.

Thomas E. schrieb:
> Ron B. schrieb:
>> if (S10 == !1
>
> Das ist auch nicht korrekt.
>
> Die Abfrage, die du machen willst, ist eine Abfrage auf true oder false.
> Dabei gilt: false = 0 und true = !0.

Danke, ist geändert.

von Einer K. (Gast)


Lesenswert?

Thomas E. schrieb:
> Dabei gilt: false = 0 und true = !0.

Das tut alles keine Not!
Das ist C++ und die Rückgabe von digitalRead() ist vom Type bool

Der Vergleich ohne impliziten Cast ist also "Variable == true", oder 
eben false



"if(variable == true)"
schreibt man so:
"if(variable)"


Ebenso:
"if(variable == false)"
Wird zu:
"if(!variable)"

Ist kein Muss, aber es ist knapper, und macht genau das, was man will.

von Manfred (Gast)


Lesenswert?

Patrick J. schrieb:
> _S10_Value = digitalRead(S10);
>
>   if (_S10 == HIGH)

Ist das eine Schulaufgabe oder hast Du das schon einmal durch die IDE 
prüfen lassen:

Arduino: 1.7.4
xxx.ino: In function 'void loop()':
xxx.ino:16:3: error: '_S10_Value' was not declared in this scope
xxx.ino:17:3: error: '_S11_Value' was not declared in this scope
xxx.ino:19:7: error: '_S10' was not declared in this scope
xxx.ino:25:7: error: '_S11' was not declared in this scope
xxx.ino:31:7: error: '_S10' was not declared in this scope
xxx.ino:31:22: error: '_S11' was not declared in this scope
Fehler beim Kompilieren.

So jedenfalls wird das nichts, den Fehler in Deinen drei Zeilen solltest 
Du eigenständig finden können. Besorge Dir ein Buch zu den Grundlagen, 
irgendwo wurde hier im Forum die Tage der Link zu einem guten pdf 
gepostet. Dann setze Dich auf den Hintern, schalte Internet aus und 
teste selbst!

Die Reihenfolge Deiner Abfragen ist ungeschickt, die von Dir benannte 
Doppelbetätigung wird hier nicht mehr abgefangen - es gewinnt immer S11.

von Thomas E. (thomase)


Lesenswert?

Ron B. schrieb:
> Damit, so kenne ich es, wird beim Arduino der Pin definiert. In diesem
> Fall Pin3. Ob S10 True oder False ist, hängt von dem Taster ab 5V oder
> 0V.

Wie schon gesagt, ich kenne kein Arduino. Aber:

Damit definierst du einen Pin als Eingang:
1
pinMode (S11, INPUT);
Weil du vorher S11 auf 4 gesetzt hast, ist das Pin4 nach der Arduino-
Zählweise. Du könntest aber auch schreiben:
1
pinMode (4, INPUT);
Und wenn Wasser bei den Arduinoleuten auch bei 100° kocht, macht das 
genau dasselbe.

Aber du musst diesen Pin und den anderen natürlich auch vor jeder 
Auswertung abfragen. Das musst du tun. Das macht der Controller nicht 
von sich aus. Auch nicht unter Arduino.

Entweder du wertest die Abfrage direkt aus:
1
if(digitalRead(S10))
2
{
3
  //Blablabla
4
}

oder du speicherst das in einer Variable zwischen:
1
unsigned char a = digitalRead(S10);
2
if(a)
3
{
4
  //Blablabla
5
}

von Einer K. (Gast)


Lesenswert?

Thomas E. schrieb:
> unsigned char a = digitalRead(S10);

Ich schlage vor:
 bool a = digitalRead(S10);

Thomas E. schrieb:
> Und wenn Wasser bei den Arduinoleuten auch bei 100° kocht, macht das
> genau dasselbe.
So ist es!

von Thomas E. (thomase)


Lesenswert?

Arduino F. schrieb:
> Das tut alles keine Not!
> Das ist C++ und die Rückgabe von digitalRead() ist vom Type bool

Ja und?
Deswegen ist false immer noch 0 und true !0.

von Ron B. (simatic)


Lesenswert?

Ich muss euch was beichten. Habe grade gesehen dass im Arduino Programm 
der Arduino Robot, anstatt des Uno eingestellt war. Mit der Abfrage der 
Taster im loop funktioniert die Sache nun. Danke vielmals für eure 
Geduld und die vielen Tipps. Mein Lernerfolg war dadurch deutlich höher. 
Gute Nacht an alle Helfer! :)

von Thomas E. (thomase)


Lesenswert?

Arduino F. schrieb:
> Ich schlage vor:
>  bool a = digitalRead(S10);

Zustimmung.

von Thomas E. (thomase)


Lesenswert?

Manfred schrieb:
> Dann setze Dich auf den Hintern, schalte Internet aus und
> teste selbst!

Was willst du denn schon wieder? Wenn wir das hier mit ihm durchkakeln, 
dann ist das unsere Sache. Also halt dich da raus.

Ausserdem grüßt er mit "Moin", was bedeutet, daß er aus dem Norden kommt 
und potentiell keinen Karneval feiert, was ihn wiederum sympathisch 
macht.

: Bearbeitet durch User
von Manfred (Gast)


Lesenswert?

Thomas E. schrieb:
> Was willst du denn schon wieder? Wenn wir das hier mit ihm durchkakeln,
> dann ist das unsere Sache.
Wenn Du Verstopfung hast, gehe in die Apotheke.
Ich habe mir den Programmcode angesehen und zu Anfang leider den Wald 
vor lauter Bäumen nicht gesehen.

Ich habe den letzten Code in die IDE kopiert, leider, ohne vorher Deine 
Erlaubnis dafür einzuholen. Die Fehlerausgabe war sowas von eindeutig, 
dass man direkt drüber fallen muß. Das bekommt der Fragesteller nicht 
alleine hin?

Deine Diskussionen:

Thomas E. schrieb:
> Nein, sie kann  0 und !0 sein. Aber !0 ist nicht unbedingt 1, sondern
> kann auch jeder andere Wert ausser 0 sein.
Thomas E. schrieb:
> Ich kenn ja kein Arduino. Aber wenn ich das sehe, ist S10 immer 3. Wo
> wird S10 0
Thomas E. schrieb:
> Ja und?
> Deswegen ist false immer noch 0 und true !0.

waren natürlich extrem hilfreich, insbesondere für einen Anfänger! 
Scheiß auf Boolean oder sonstwas, Arduinos fragen auf ==High oder ==Low 
ab und fertig.

Dass die Abfrage "S10 == 0" eine falsche Variable bewertet, hast auch Du 
nicht erkannt, also mal ganz friedlich.

von Einer K. (Gast)


Lesenswert?

Manfred schrieb:
> Arduinos fragen auf ==High oder ==Low
> ab und fertig.

Falsch!
Vielleicht der eine, aber nicht "die".
Außerdem gibts in der Arduinowelt kein High und auch kein Low.

von Manfred (Gast)


Lesenswert?

Arduino F. schrieb:
> Außerdem gibts in der Arduinowelt kein High und auch kein Low.

Wir gehen also davon aus, dass im Buch
Arduino für Fortgeschrittene
O’REILLY / Arduino Kochbuch
im Kapitel 5.1 die Abfrage eines Schalters fehlerhaft beschrieben wurde:

void loop(){
 int val = digitalRead(inputPin); // Eingangswert einlesen
   if (val == HIGH) // Eingang HIGH?
   {
    digitalWrite(ledPin, HIGH); // LED einschalten, wenn Taster gedru 
¨ckt
   }
   else
   {
    digitalWrite(ledPin, LOW); // LED ausschalten
   }
}

Falls Dir gerade Korinthen entfleucht sein sollten: High und Low ohne 
Großbuchstaben bemerkt mein Editor.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Ron B. schrieb:
> Ich muss euch was beichten. Habe grade gesehen dass im Arduino
> Programm
> der Arduino Robot, anstatt des Uno eingestellt war. Mit der Abfrage der
> Taster im loop funktioniert die Sache nun. Danke vielmals für eure
> Geduld und die vielen Tipps. Mein Lernerfolg war dadurch deutlich höher.
> Gute Nacht an alle Helfer! :)


Vll. ab und zu ALLE neuen Beiträge lesen und nicht nur den Einen 
anpissen, Den man gerade nicht mag??

Manfred schrieb:
> Patrick J. schrieb:
>> _S10_Value = digitalRead(S10);
>>
>>   if (_S10 == HIGH)
>
> Ist das eine Schulaufgabe oder hast Du das schon einmal durch die IDE
> prüfen lassen:

Jupp, einfach Mal ALLES lesen, dann wäre vll. auch Dir aufgefallen, daß 
ich nicht der Fragende in dieser Situation bin.
Wenn Du mit Pseudo-Code Nichts anzufangen weißt, dann eben nicht.
Schade, daß man gerade Dir hier Alles vorkauen muß - aber so Leute gibt 
es und auch Dir wird hier geholfen werden.

MfG

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.