Mit der zweiten Antwort die du gut findest hast du schon die Trennung zwischen elektrischer/physikalischer Ebene und Abstraktion zur ersten Meinung. Nennen wir es doch beim Namen. Nennt sich C++ OOP - Objekt orientierte Programmierung. Man will bspw. eine Pumpe schalten. Dann handiert man im Programm nur mit Funktionen oder Methoden wie pumpeEin() oder pumpeAus(). Ob diese Funktionen intern mit invertierter Logik oder nicht arbeiten spielt für den Anwender keine Rolle. Der Name sagt was mit dem realen Objekt passiert. Alles andere wird vorher bzw. intern definiert. Davon redet Tommy und combie.
Sehe ich genau umgekehrt!
Eine fruchtbare "für" vs, "wider" Betrachtung geht nicht ohne den Kontext zu kennen/analysieren.
Das stimmt, momentan muss das (noch) reichen.
Stimmt! Das ist für mich persönlich auch schon zu „wuppen“ und habe ich sogar so ähnlich schon mal genutzt! Man
Bin ich nicht drauf gekommen gerade! Danke!
Aber so ist das wohl, wenn man nur alle paar Tage/Wochen mal 2 Stündchen Zeit findet
Leider.
Kann man das nicht lösen indem man beim negativen Logikteil die Variabeln mit ! negiert.
zB
pos Logik:
digitalWrite(pin, AN);
neg Logik:
digitalWrite(pin, !AN);
Grüße Uwe
Das wird auch schnell unübersichtlich und vor allem von Anfang an unlogisch.
Entweder man definiert die AN/AUS für die Bauelemente Gruppen einzeln, z.B. relaisAN/relayAUS und ledAN/ledAUS wenn diese unterschiedliche Logik haben.
Im Endeffekt ist der Ansatz von Combie aber der Bessere, wenn auch für den Einsteiger mit einer gewissen Lernkurve verbunden, die dieser evtl. nicht aufbringen will/kann.
Gruß Tommy
Wenn, dann, wäre logisch:
digitalWrite(led, AN); // led leuchtet
digitalWrite(led, !AN); // led nix leuchtet
digitalWrite(led, AUS);// led nix leuchtet
Dieses ist dagegen eine gruselige Verwirrungstaktik:
digitalWrite(led, AUS);// led leuchtet
digitalWrite(led, !AN);// led leuchtet
Und jetzt zum eigentlichen Grund:
Das Unterbewusstsein ist älter als das Bewusstsein.
Das Unterbewusstsein kann keine Negierungen.
Somit sind Negierungen auf eine bewusste Verarbeitung angewiesen.
Das Unterbewusstsein (Stammhirn usw.) kann ca 300 Entscheidungen pro Sekunde.
Das Bewusstsein vielleicht 3, oder bestenfalls 5 pro Sekunde.
Je mehr solcher "Dinge" man in sein Programm einbaut, desto weniger ist es intuitiv erfassbar. Desto Fehlerträchtiger wird die ganze Show.
Das gilt auch für if Konstruktionen!
Es kann in der Bedingung negiert werden, und jedes/viele if haben ein einen negativen else Zweig.
Ein kleines Programm kann auf diese Art ein Gehirn völlig übertölpeln.
Wobei ein großes, nach Intuitivkriterien verfasstes, recht leicht zu verstehen ist.
Nicht vergessen. Was man unterbewusst/bewusst macht kann man trainieren. Was man unterbewusst/bewusst macht, muss nicht richtig sein.
Ich dachte:
LED mit Vorwiderstand zwischen Ausgang und Masse:
digitalWrite(led, AN); // led leuchtet
digitalWrite(led, AUS); // led nix leuchtet
LED mit Vorwiderstand zwischen Ausgang und +5V:
digitalWrite(led, !AN); // led leuchtet
digitalWrite(led, !AUS); // led nix leuchtet
Ich verstehe aber Eure Einwände und Erklährungen
Grüße Uwe
Ich hab' da so meine Probleme mit Konstrukten wie
#define EIN 1
#define AUS 0
Welche anschliessend auf boolsche Operationen angewendet werden. Hat damit zu tun, dass hier boolsche Operationen (Mathematik) mit realen Zuständen der Hardware vermischt werden.
Wenn's dann doch mal sein muss, so habe ich immer in dieser Art definiert:
#define AUS 0
#define EIN (!AUS)
Wenn jetzt auf mit einem Wert verglichen wird, der weder "1" noch "0" ist, dann bekomme ich immer noch eine eindeutige Antwort.
[OT]
Kennt ihr die 4 Zustände eines Bit?
- WAHR
- FALSCH
- keine Ahnung
- ist mir egal
[/OT]
constexpr bool aus {false};
constexpr bool ein {!aus};
Leitsatz:
Jedes vermeidbare define ist ein böses define.
Jedes vermiedene define ist ein gutes define.
so ein globales Makro, const, constexpr,... mit lediglich einer Konstante mit einem (inversen) Wert ist doch auch nur eine weitere Verschleierung wenn man im Code dann erst recht wieder z.B. HIGH für aktive LEDs und EIN für LOW aktive Relais verwendet. Dann muss man wieder daran denken, ob man jetzt HIGH oder EIN verwendet. Da kann ich gleich ein Relais mit LOW einschalten.
Imho könnte man sich eine nette Klasse schreiben, und bei der Objektanlage nicht nur den Pin zuweisen sondern auch ob das ganze High oder LOW aktiv ist.
Dann zwei setter mit .on() .off() und hat anschließend im ganzen Sketch durchgängig immer .on() und off() zur Verfügung - das Objekt kümmert sich dann darum was aus on und off werden soll.
class Output {
protected:
const uint8_t pin;
const int8_t active;
public:
Output (uint8_t pin, int8_t active = HIGH) : pin(pin), active(active) {}
void begin() {
pinMode(pin, OUTPUT);
this->off();
}
void on() {
digitalWrite(pin, active);
}
void off() {
//digitalWrite(pin, !active);
digitalWrite(pin, active == HIGH ? LOW : HIGH);
}
};
Output led(13);
Output relay(7, LOW); // invers
void setup() {
led.begin();
relay.begin();
}
void loop() {
led.on();
relay.on();
delay(500);
led.off();
relay.off();
delay(500);
}
blinki blink
oder noch besser:
LED mit Vorwiderstand zwischen Ausgang und Masse:
ledStatus = AN;
digitalWrite(led, ledStatus); // led leuchtet
ledStatus = AUS;
digitalWrite(led, ledStatus); // led nix leuchtet
LED mit Vorwiderstand zwischen Ausgang und +5V:
ledStatus = AN;
digitalWrite(led, !ledStatus); // led leuchtet
ledStatus = AUS;
digitalWrite(led, !ledStatus); // led nix leuchtet
Grüße Uwe
[EDIT]
digitalWrite(led, AN); // led leuchtet
in
digitalWrite(led, ledStatus); // led leuchtet
geändert.
Grüße Uwe
[/EDIT]
Meinst Du
ledStatus = AN;
digitalWrite(led, ledStatus); // led leuchtet
Das halte ich, sorry Uwe, für Unsinn.
die Konstante AN wurde hier doch extra dafür erfunden, dass man erkennen soll, welchen gewünschten Zustand die LED damit hat.
Wenn, dann erfinde ein
constexpr LOW_AKTIV = LOW;
digitalWrite(led, LOW_AKTIV);
delay(500);
digitlaWrite(led, ! LOW_AKTIV); // led aus
Das wäre auch meiner Meinung nach die schönere Lösung.
Die hat ja combie in #20 mit Combie::Pin schon vorgestellt.
Gruß Tommy
Ach, ist schon ok....
Meinen etwas kruden Ideen/Gedanken/Wegen muss nicht jeder folgen.
Das supertolle an combiepin ist die Übergabe der Pin-Nummer als Template Parameter, wodurch eine wahnsinns-Performance --zumindest bei avr-controllern-- erreicht wird, und die konsequente Verwendung des Zuweisungsoperators, wenn man sich erstmal dran gewöhnt hat.
Dass bei combie ein InvOutputPin etwas anderes als ein OutputPin Objekt ist, finde ich bei @noiasca hübscher gelöst.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.