PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Was macht dieser Befehl: digitalWrite(ziffer[0][j], (segmente[i][j]==1)?HIGH:LOW);



Chevy
30.03.2015, 16:36
Hi,

in meinem Programm habe ich folgenden Befehl eingebunden:



digitalWrite(ziffer[0][j], (segmente[i][j]==1)?HIGH:LOW);


Das ganze Funktioniert auch wie es soll, habe den Befehl aus einem Beispielprogramm kopiert. Aber so genau habe ich die Funktion dessen nicht verstanden.

Es geht vor allem um ...........,(Array[x][y]==1)?HIGH:LOW);

Kann mir einer das verständlich erklären?

Gruß Marco

HeXPloreR
30.03.2015, 17:19
Hallo Chevy,

zu dem Array/segmente selbst kann ich jetzt nichts weiter sagen, außer das es anscheinen Zählvariablen enthält die sich vermutlich auf den zu steuerneden Pin in einem Zweidimensionalem Array beziehen. Weiter kann dir sagen das auf Gleicheit (==) mit 1 geprüft wird, der Operator dahinter ( ?: ) nennt sich "tenärer Operator" und kürzt eine if - else Abfrage aufs absolute minimum ein - zur Lasten der anfänglichen Verständlichkeit.

Bedingung ? Anweisung1 : Anweisung2;
Wenn Bedingung wahr ( nicht 0 ) ist , wird Anweisung1 (High) ausgeführt, sonst bei 0 die Anweisung2 (Low).

Ich würde vermuten das es hier in Verbindung mit digitalWrite zur Steuerung von mehreren Pins (als software PWM) benutzt wird.

Du sagst das es funktioniert, dann lasse ich das mal so stehen, denn ich habe damit weiter noch keine Erfahrung ob der Code das richtige tut.
Da habe ich leider auch nur gefährliches Halbwissen bis jetzt.

Verlinke doch mal woher genau das Beispiel stammt.

Viele Grüße
Jörg

Peter(TOO)
30.03.2015, 17:42
Hallo Marco,

in meinem Programm habe ich folgenden Befehl eingebunden:



digitalWrite(ziffer[0][j], (segmente[i][j]==1)?HIGH:LOW);


Das ganze Funktioniert auch wie es soll, habe den Befehl aus einem Beispielprogramm kopiert. Aber so genau habe ich die Funktion dessen nicht verstanden.

Es geht vor allem um ...........,(Array[x][y]==1)?HIGH:LOW);

Kann mir einer das verständlich erklären?

Das ist eine Kurzform für if
Könnte man ersetzen durch:


int f(void)
{
if (segmente[i][j]==1)
return HIGH
else
return LOW
}
.
.
.
digitalWrite(ziffer[0][j], f() );

Falls du es testen willst, int f() ist geraten, aus deinem Ausschnitt geht nicht hervor wie HIGH und LOW definiert sind und auch nicht welchen Parameter digitalWrite() erwartet. Das müsstest du evtl. entsprechend anpassen.

MfG Peter(TOO)

Sisor
30.03.2015, 18:59
segmente[i][j]==1 ? HIGH:LOW
Wenn der Wert in der Matrix 'segmente' in Zeile 'i', Spalte 'j' '1' ist, schreibe hier HIGH. Ansonsten schreibe hier LOW.

Chevy
30.03.2015, 19:28
Hi Jörg,



Verlinke doch mal woher genau das Beispiel stammt.


Also das Beispiel stammt von hier: https://blog.silvertech.at/arduino-7-segmentanzeige-ansteuern/




zu dem Array/segmente selbst kann ich jetzt nichts weiter sagen, außer das es anscheinen Zählvariablen enthält die sich vermutlich auf den zu steuerneden Pin in einem Zweidimensionalem Array beziehen.


Um genau zu sein auf zwei Zweidimensionale Arrays, das stammt ja auch von mir und das hatte ich verstanden.




Weiter kann dir sagen das auf Gleicheit (==) mit 1 geprüft wird, der Operator dahinter ( ?: ) nennt sich "tenärer Operator" und kürzt eine if - else Abfrage aufs absolute minimum ein - zur Lasten der anfänglichen Verständlichkeit.Bedingung ? Anweisung1 : Anweisung2; Wenn Bedingung wahr ( nicht 0 ) ist , wird Anweisung1 (High) ausgeführt, sonst bei 0 die Anweisung2 (Low).


Vielen Dank! jetzt habe ich es verstanden und finde ich auch genial... Da macht das Programmieren noch mehr Spass, wenn man weiß um was es geht.




Ich würde vermuten das es hier in Verbindung mit digitalWrite zur Steuerung von mehreren Pins (als software PWM) benutzt wird.

Nee nicht ganz. Ok ich lade mal die Funktion hoch. Es geht um eine 5 stellige 13 Segmentanzeige wobei diese von zwei Mega 2560 gesteuert wird und der Code ist für den Mega Nr.1
Die Anzeige ist ca. 2m auf 0,5m groß und die Segmente werden über 230Volt LED Lampen befeuert. Durch die nötige und verbauten Schaltungen fällt das Multiplexen leider flach. Mehrere Versuche die Anzeige zu Multiplexen gingen daneben, so das ich jetzt jedes Segment seperat ansteuere..

Da hätte ich auch gleich noch ne Frage: Zum Schluß der Funktion habe ich den Befehl: Serial.print("Error"); welches er auch auf den Monitor bringt, jedoch der Rest wird nicht mehr ausgeführt und das Programm springt sehr weit nach oben. Ist das jetzt Zufall, ein Fehler in meinem Code oder macht das Wort Error was aktives?

Und wenn ich jetzt das "==1)?HIGH:LOW)" sehe, dann könnte man doch die ganzen If Abfragen in meiner Funktion etwas zusammenfassen oder funktioniert das dann nicht?

Gruß Marco




/*
* Copyright (c) 2015 Marco Steinhauser. All rights reserved
*
* Funktion Pin Anzeige
*
* Test Programm für eine 5 stellige 13 Segment Anzeige mit Doppelpunkt, Punkt, KM/H
* und Sekunden. Aufgeteilt auf zwei Arduino 2560 MEGA R3
*
*
* Für den Arduino 2560 MEGA R3 Nr.1
*
*
* Steuert die Digitalen Pins der Ziffern X4, X5 und X6 an und aktiviert die Digitalen Ausgänge
* für die Zahlen 0-9, KM/H und SEK. Für die Ziffern X1 und X2 sowie den Punkt und Doppelpunkt
* werden die Zahlen über den I²C Bus an den Mega Nr. 2 übergeben.
* Zur Kontrolle werden die Zustände der digitalen Ausgänge auf dem Serial Monitor angezeigt.
*
* Version 2.2
*
* Vers. 1.0 vom 27 März 2015
* V. 1.0 Das Programm wurde an Hand eines Beispiel Program aus dem Internet
* entworfen und dient zur Kontrolle ob die Digitalen Ausgänge auch so
* angesteuert werden wie gewünscht.
*
* Vers. 1.1 vom 28 März 2015
* V. 1.1 Das Programm wurde an die Funktion "Zahl Auswerten" angepasst.
*
*
* Vers. 2.2 vom 30 März 2015
* V. 2.0 Das Programm wurde in die Funktion "Pin Anzeige" geändert.
* V. 2.1 Es wurden die Fallunterscheidungen für die 6 stellige Einzelzahl implementiert.
* V. 2.2 Zu Testzwecken wurden die Funktionen "empfangeZahl" und "bestimmeZahl" implementiert.
*
**/
byte digipin[34]={6,7,13,22,23,24,25,26,27,28,29,30,31,32,33,34,35 ,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,5 2,};
// Digital-Ausgänge deklarieren


byte ziffer[3][11] = {
{43,44,45,46,47,48,49,50,51,52,13}, // Ziffer 0 = X4
{33,34,35,36,37,38,39,40,41,42,13}, // Ziffer 1 = X5
{22,23,24,25,26,27,28,29,30,31,32}, // Ziffer 2 = X6
};



byte segmente[14][11] = {

{1,1,1,1,1,1,1,0,1,1,0}, // segmente 0 = Zahl 0
{1,0,0,0,0,0,0,0,1,1,0}, // segmente 1 = Zahl 1
{1,1,1,0,1,1,1,1,1,0,1}, // segmente 2 = Zahl 2
{1,1,1,0,1,0,1,1,1,1,1}, // segmente 3 = Zahl 3
{1,0,1,1,1,0,0,1,1,1,0}, // segmente 4 = Zahl 4
{1,1,1,1,1,0,1,1,0,1,1}, // segmente 5 = Zahl 5
{1,1,1,1,1,1,1,1,0,1,1}, // segmente 6 = Zahl 6
{1,0,1,0,0,0,1,1,1,1,0}, // segmente 7 = Zahl 7
{1,1,1,1,1,1,1,1,1,1,1}, // segmente 8 = Zahl 8
{1,1,1,1,1,0,1,1,1,1,1}, // segmente 9 = Zahl 9
{1,1,1,1,1,1,1,1,0,0,1}, // segmente 10 = Buchstabe E
{1,1,1,1,1,1,0,0,1,1,1}, // segmente 11 = Buchstabe U
{1,1,1,1,1,0,1,1,0,1,1}, // segmente 12 = Buchstabe S
{1,1,1,1,1,1,1,1,1,1,0}, // segmente 13 = Buchstabe A
};


long eingangszahl=0; //Die Variable für den Empfang der Einganszahl deklarieren und den Wert 0 zuweisen.

long a =0;

long divisor=100000; // Variable Divisor deklarieren und Wert zuweisen. Dieser Wert muss mit der
// Anzahl der Stellen des Einganswerts übereinstimmen.

long teilzahl=0; // Variable für die zwischen Schritte deklarieren

int i=0; // Variable für die Zählerschleife deklarieren
int j=0;

byte einzelzahl[6]; // Variable für das Ergebnis deklarieren. Es werden die einzelnen Werte der
// achtstelligen Zahl in einer Feld-Variable gespeichert

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

for(int i = 0; i<34; i++){
pinMode(digipin[i], OUTPUT); //Digital Pins als Ausgang aktivieren
};

for(int j = 0; j<11; j++){
digitalWrite(ziffer[0][j], (segmente[11][j]==1)?HIGH:LOW);
digitalWrite(ziffer[1][j], (segmente[12][j]==1)?HIGH:LOW);
digitalWrite(ziffer[2][j], (segmente[13][j]==1)?HIGH:LOW);
}
Serial.print("USA"); Serial.println("");
for (int i = 0; i < 34; i++){
Serial.print(digitalRead(digipin[i]));
}
Serial.println("");

delay(2000);

}

void loop()
{



eingangszahl=0;

empfangZahl();

delay (1000);

bestimmeZahl(); // Aufruf der Funktion innerhalb des Programms

delay (1000);

pinAnzeige();

}


void empfangZahl(){

Serial.flush();
Serial.println("Bitte 6 stellige Zahl eingeben:");
while (Serial.available() == 0)
{
// Macht nichts! Wartet bis eine Zahl empfangen wird.
}
while (Serial.available() > 0)
{
eingangszahl = eingangszahl * 10;
a=Serial.read()-'0';
eingangszahl = eingangszahl + a;
delay (5);
}
Serial.print("Die empfangene Zahl ist:");
Serial.println(eingangszahl);
}

void bestimmeZahl () // Funktion zum Auswerten einer 8 stelligen Zahl
{
for (int i=0; i<6; i++){

teilzahl=(eingangszahl/divisor);

divisor=(divisor/10);

if (teilzahl >=10) {
teilzahl=(teilzahl%10);
}
einzelzahl[i] = (teilzahl);
}
divisor=100000;
Serial.println ("Die Einzelzahlen sind:");

for (int i=0;i<6;i++){
Serial.println (einzelzahl[i]);
}
}

void pinAnzeige()
{
for(int i = 0; i<34; i++)
digitalWrite(digipin[i],LOW); //Digitale Ausgäng ausschalten




if (einzelzahl[0]==1){ //erste Stelle ist 1 = Uhrzeit

Serial.print("Uhrzeit"); Serial.println("");
Serial.print("DoppelPunkt"); Serial.println("");
delay(1000);

for(int i=0; i<10; i++){
if (einzelzahl[3]==i){ //vierte Stelle 0-9 = Ziffer X4 Zahl 0-9
for(int j = 0; j<11; j++){
digitalWrite(ziffer[0][j], (segmente[i][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[0][j]));
}
Serial.println("");
}
if (einzelzahl[4]==i){ //fünfte Stelle 0-9 = Ziffer X5 Zahl 0-9
for(int j = 0; j<11; j++){
digitalWrite(ziffer[1][j], (segmente[i][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[1][j]));
}
Serial.println("");
}
}
}
if (einzelzahl[0]==2||einzelzahl[0]==3){ //erste Stelle ist 2 oder 3

if (einzelzahl[0]==2){ //erste Stelle ist 2 = Sekunden

digitalWrite(7,HIGH); //aktiviert PIN 7 SEK
Serial.print("PIN 7 SEK ="); Serial.println(digitalRead(7));
Serial.print("PIN 6 KM/H ="); Serial.println(digitalRead(6));
Serial.print("Punkt"); Serial.println("");
delay(1000);
}
if (einzelzahl[0]==3){ //erste Stelle ist 3 = KM/H

digitalWrite(6,HIGH); //aktiviert PIN 6 KM/H
Serial.print("PIN 7 SEK ="); Serial.println(digitalRead(7));
Serial.print("PIN 6 KM/H ="); Serial.println(digitalRead(6));
Serial.println("");
delay(1000);
}
for(int i = 0; i<10; i++){
if (einzelzahl[3]==i){ //vierte Stelle 0-9 = Ziffer X4 Zahl 0-9
for(int j = 0; j<11; j++){
digitalWrite(ziffer[0][j], (segmente[i][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[0][j]));
}
Serial.println("");
}
if (einzelzahl[4]==i){ //fünfte Stelle 0-9 = Ziffer X5 Zahl 0-9
for(int j = 0; j<11; j++){
digitalWrite(ziffer[1][j], (segmente[i][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[1][j]));
}
Serial.println("");
}
if (einzelzahl[5]==i){ //sechste Stelle 0-9 = Ziffer X6 Zahl 0-9
for(int j = 0; j<11; j++){
digitalWrite(ziffer[2][j], (segmente[i][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[2][j]));
}
Serial.println("");
}
}
}


if (einzelzahl[0]>=4&&einzelzahl[0]<=6){ //erste Stelle ist größer/gleich 4 = Fehler

Serial.print("Fehler");
Serial.println("");
for(int j = 0; j<11; j++){
digitalWrite(ziffer[0][j], (segmente[10][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[0][j]));
}
Serial.println("");

for(int i = 0; i<10; i++){
if (einzelzahl[4]==i){ //dritte Stelle 0-9 = Ziffer X1 Zahl 0-9
for(int j = 0; j<11; j++){
digitalWrite(ziffer[1][j], (segmente[i][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[1][j]));

}
Serial.println("");
}
if (einzelzahl[5]==i){ //dritte Stelle 0-9 = Ziffer X1 Zahl 0-9
for(int j = 0; j<11; j++){
digitalWrite(ziffer[2][j], (segmente[i][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[2][j]));

}
Serial.println("");
}
}
}

if (einzelzahl[0]==0||einzelzahl[0]>=7){ //erste Stelle ist 0 = Error
Serial.print("Error");
Serial.println("");
for(int j = 0; j<11; j++){
digitalWrite(ziffer[0][j], (segmente[10][j]==1)?HIGH:LOW);
digitalWrite(ziffer[1][j], (segmente[3][j]==1)?HIGH:LOW);
digitalWrite(ziffer[2][j], (segmente[3][j]==1)?HIGH:LOW);
Serial.print(digitalRead(ziffer[0][j]));
Serial.print(digitalRead(ziffer[1][j]));
Serial.print(digitalRead(ziffer[2][j]));
}
Serial.println("");
}
}



- - - Aktualisiert - - -

Hallo Peter und Sisor,

vielen Dank für euere Antworten. Hatte mir schon gedacht das dieser Befehl die 1 und die 0 aus dem einen Array überträgt auf die digitalen Pins des anderen Array, da es ja auch funktioniert. Nur das wie war nicht klar. Aber Dank eueren Antworten bin ich jetzt wieder etwas schlauer... \\:D/

Gruß Marco

HeXPloreR
30.03.2015, 21:41
Hallo Marco,

dass das Programm sehr weit nach oben springt sollte klar sein, da die Sub-Funktion "pinAnazeige" hier nunmal endet, zurück in die loop geht, die dann endet und von neuem beginnt.

Warum die letzten drei prints nicht ausgegeben werden wenn das "error" kommt, kann ich nicht sehen. Hier befindet man sich ja schon in der if-Anweisung die das print "error" enthält.
Das "Error" selbst hat innerhalb dieses Strings hier jedenfalls nichts damit zu tun und kann nicht irgendwie aktiv werden. Es sei den der String wird noch irgendwie irgendwo ausgewertet - sieht aber nicht danach aus.

Versuche mal den Inhalt vom ersten (fehlendem) print manuell in einen definitven String zu ändern (z.B. Serial.print("Ziffer 0"); ). Wenn der dann nach dem "error" auch kommt dann tippe ich darauf das der Inhalt von print jetzt noch fehlerhaft ist. Print scheint gar keinen Inhalt zu haben. Was ja nicht sein kann wenn alle Prints davor in der gleichen Form "print(digitalread ... )" funktionieren. Warum sehe ich aber nicht.

Viele Grüße
Jörg

Edit1:
Unglücklich finde ich immer so Bedingungen wie z.B. " >=7 " zu wählen wenn man auf eine Zahl prüft ob sie größer als 6 ist. Da würde ich persönlich immer direkt " >6 " bevorzugen, weil man hier direkt sehen kann worum es geht, nämlich um einen Test auf "größer als 6". Die 7 kommt zwar nach 6, ist aber im Bezug auf die Prüfung bei Ganzzahlen nicht relevant.
Das gleiche sinngemäß umgekehrt für die for-Schleifen z.B. bei "(..., j <=10 , ... )".

Edit2:
Um die "if 's" alles zusammenzufassen würde ich Dir ncht empfehlen den Operator ?: zu benutzen. Wie Du selbst gesehen hast erzeugt er eher Verwirung, bei der großangelegten Verwendung in Blöcken ist diese umso größer.
Daher schaue Dir dazu lieber ein "switch-case" Konstrukt an.

Chevy
02.04.2015, 23:41
Hi Jörg,



Das "Error" selbst hat innerhalb dieses Strings hier jedenfalls nichts damit zu tun und kann nicht irgendwie aktiv werden.


Hatte ich mir auch so gedacht, kann eigentlich nicht da beim print Befehl innerhalb der " " keine Befehle stehen. Habe das aber auch nicht weiter verfolgt, da diese Serial.print nur zur Kontrolle eingebaut waren und da ich momentan keine Zeit habe mich länger daran aufzuhalten, sondern das Projekt muss bald stehen habe ich die Funktion erst mal als fertig abgespeichert und die nächste Funktion angegangen.



Edit1:
Unglücklich finde ich immer so Bedingungen wie z.B. " >=7 " zu wählen wenn man auf eine Zahl prüft ob sie größer als 6 ist. Da würde ich persönlich immer direkt " >6 " bevorzugen, weil man hier direkt sehen kann worum es geht, nämlich um einen Test auf "größer als 6". Die 7 kommt zwar nach 6, ist aber im Bezug auf die Prüfung bei Ganzzahlen nicht relevant.
Das gleiche sinngemäß umgekehrt für die for-Schleifen z.B. bei "(..., j <=10 , ... )".


Da hast Du völlig recht, ich mag dieses negieren der Negierung auch nicht. Bei den FOR Schleifen habe ich das auch nicht drin, da ja das > oder < sich auf den Inhalt eines Array bezieht und nicht auf Zahlen sondern auf Spalten bzw. Felder. Möglicherweise ahnst Du schon warum ich das jetzt bei den If Abfragen so gewählt habe, (hier darf man mal lachen:rolleyes:) ich war mir nämlich nicht sicher ob eine Ganzzahl auch wirklich intern als Ganzzahl behandelt wird. Durch die Funktion mit dem Modulo bin ich etwas durcheinander geraden, da ich dachte der Rest einer Division ist ja das ....,XY also das ,23 bei zB. 1,23. Bis ich die Funktion richtig verstanden hatte, hatte ich die Abfragen schon geschrieben und damit verhindern wollte das eine 6,23 als >6 angesehen wird. Ok Ok werde es ändern ;)




Edit2:
Um die "if 's" alles zusammenzufassen würde ich Dir ncht empfehlen den Operator ?: zu benutzen. Wie Du selbst gesehen hast erzeugt er eher Verwirung, bei der großangelegten Verwendung in Blöcken ist diese umso größer.
Daher schaue Dir dazu lieber ein "switch-case" Konstrukt an.

Hast ebenfalls recht, den Code kann man dann nur noch schwer durchschauen. Bei den zuweisungen der "einsen" und "nullen" zu den Pins ist das ja noch i.O. aber wenn ich jetzt verschiedene Bedingungen damit definiere dann kann ich das kaum selbst, nach ein paar Tagen, nachvollziehen. Das mit dem switch-case muss ich mir noch mal genauer anschauen, ist schon gut 2 Jahre her als ich das letzte mal damit was programmiert hatte. Zur Zeit habe ich aber ein anderes Problem, nähmlich mit der Wire Funktion. Aber dazu mach ich einen anderen Tread auf, hat ja mit der obigen Funktion nichts zu tun.

Gruß Marco

Peter(TOO)
03.04.2015, 10:48
Hallo Jörg,

Edit1:
Unglücklich finde ich immer so Bedingungen wie z.B. " >=7 " zu wählen wenn man auf eine Zahl prüft ob sie größer als 6 ist. Da würde ich persönlich immer direkt " >6 " bevorzugen, weil man hier direkt sehen kann worum es geht, nämlich um einen Test auf "größer als 6". Die 7 kommt zwar nach 6, ist aber im Bezug auf die Prüfung bei Ganzzahlen nicht relevant.
Das gleiche sinngemäß umgekehrt für die for-Schleifen z.B. bei "(..., j <=10 , ... )".

Es kommt immer darauf an was man macht und was schlussendlich übersichtlicher ist. z.B.


if (a == 0) f0();
if (a == 1) f1();
if (a == 2) f2();
if (a == 3) f3();
if (a >= 4) f4();
ist sicher übersichtlicher als:


if (a == 0) f0();
if (a == 1) f1();
if (a == 2) f2();
if (a == 3) f3();
if (a > 3) f4();

Auch wenn man mit Konstanten arbeitet, kann es Sinn machen:


if (('a' <= x) && (x <= 'z')) f0();


MfG Peter(TOO)