Hallo zusammen, folgende Problemstellung stellt sich mir gerade: Ich habe eine Funktion, der acht Default-Parameter mitgegeben werden, der Dummy schaut so aus:
void initPLC(uint8_t Port0 = iPORT, uint8_t Port1 = oPORT, etc, uint8_t Port7 = iPORT)
{
if {Port0 == 1} bitSet(ioType,0);
if {Port1 == 1} bitSet(ioType,1);
...
if {Port7 == 1} bitSet(ioType,7);
// Funktion geht weiter
}
Das muss doch irgendwie "eleganter" gehen, ich hab' gerade ein Brett vom Kopf. Ein Array kann und will ich nicht übergeben, weil der User beim Aufruf der Funktion die Parameter ändern können soll, es soll also flexibel bleiben.
Danke, auf "va_" bin ich auch schon gestoßen, allerdings habe ich es so verstanden dass es für eine variable Parameteranzahl gedacht ist. Hier sind's ja fix acht Stück. Zudem habe ich auch keine Lösung gefunden, wie ich mit einem solchen Konstrukt die Defaultwerte übergeben kann.
Vielen Dank für den Denkanstoss... so ganz raffe ich das noch nicht muss ich ehrlich sagen, aber ich beisse mich da durch. Schön wäre es den oben genannten Funktionsaufruf beizubehalten.
... inklusive der Defaultwerte beibehalten (oder zumindest userfreundlich gestalten) und in einer Schleife o.ä. die Werte von Port0 bis Port7 abfragen.
Warum, wozu?
Warum so?
In Verbindung mit "geht nicht", werden die Fragen um so wichtiger.
Aus meiner Sicht bist du irgendwo falsch abgebogen, und steckst jetzt in einer Sackgasse.
Mein Rat: 3 Schritte zurückgehen, und beschreiben, was du "wirklich" erreichen willst.
Ich frage mich die ganze Zeit was mit "Der User soll die Daten ändern können" gemeint ist.
Zum Ändern der Daten wird eh ein Interface gebraucht. Und da ist es doch erst mal egal, in welcher Form die Parameter an eine Funktion übergeben werden. Also warum wird ein Array da von vornherein ausgeschlossen? Könnte ja auch ein Objekt sein...
Nundenn... nochmal ganz langsam:
Das Ganze soll eine Initialisierungsroutine für vier Portexpander werden. Diese besitzen jeweils zwei Ports a 8 Bit, welche in der Software als Input oder Output definiert werden können.
Die Ansteuerung der Expander selbst übernimmt eine Library. Auf der Platine selbst können diese acht Ports durch Tausch von ICs entweder mittels Spannungsteiler als Eingang, oder via Leistungstreiber als Ausgang fungieren. Standardmäßig sind Port 0 bis 3 als Eingang bestückt, die Ports 4 bis 7 als Ausgang - wie gesagt, dies kann mittels einer Änderung an der Hardware geändert werden.... soweit die "Rahmenbedingungen".
Ich möchte nun eine Routine schreiben, in der der User die gewünschte - und auch (hoffentlich) hardwareseitig richtig konfiguierte - Funktion der Ports 0 bis 7 angeben kann, damit mittels der Expander-Library die Ports entsprechend gesetzt werden können. Auf die Defaultwerte kam ich damit die "Standardkonfiguration" bereits hinterlegt ist und die Routine auch ohne Parameter aufgerufen werden kann.
Und nein, das Ganze ist bis dato nicht in einer Klasse gekapselt. Der Krempel im ersten Post funktioniert ja, aber schön ist nunmal anders.
Ich bin für weitere Denkanstöße und Ansätze offen, weiß aber wirklich nicht wie ich es noch ausführlicher beschreiben soll.
Natürlich würde ein Byte reichen, aber ich möchte nicht zwingend etwas kryptisches wie "0b11110000" übergeben, sondern Bezeichner (Input = 0, Output = 1) aus einem Enum.
Könnte daran liegen dass dies oben nur ein Rumpf ist und glaube mir, das Ganze funktioniert ausprogrammiert. Und jetzt komm' mir bitte nicht mit "Aber warum ist es nicht ausprogrammiert? Fragen über Fragen?!". Solltest du dich da jetzt angesprochen fühlen kannst du das Thema für dich gerne als abgeschlossen betrachten, auf solche Diskussionen von der Seite kann ich gerne verzichten. Nichts für ungut...
klingt für mich du möchtest ein Funktion mit 8 Parameter oder 0 Parameter
Das kannst du mit den default Werten machen (wie im Eingangspost angedeutet) oder
du machst eine Funktion mit 8 Parameter (ohne Default Werte) und eine zweite (kann ja auch gleichlautend sein) mit 0 Parameter die dann erstere mit ihren 8 Parametern aufruft (overloading)
P.S.: als User würde ich das durchaus gerne auch als bitamp übergeben können...
OOP
alternativ, wenn du z.B. dem User gezieht die Möglichkeit geben willst nur z.B. Port 3 und 5 zu setzen, würde ich doch den OOP weg gehen und setter schreiben für
void setPort(byte port, byte type);
dann kann der User geziehlt setzen:
plc.setPort(3, OUTPUT);
plc.setPort(5, OUTPUT);
und die anderen Ports bleiben auf INPUT.
wenn beides nicht ist was du dir vorstellst - führe weiter aus, was bei den beiden Vorschlägen anders sein soll.
du (TO) möchtest das der User konfiguriert welcher Pin Eingang bzw. Ausgang ist? Konstrukte wie iPORT oder oPORT sind genauso fehleranfällig, unterscheidet sich nur in einem Buchstaben und wird irgendwo im Sketch angegeben. Wenn es nur 8 Bit sind schreibe eine Klasse und gib das bei der Initialisierung an.
Bspw.
Der Rest läuft intern in der Klasse ab. Mit dem einen Byte für die I/O Konfig kann man intern um Längen besser arbeiten als wenn man hunderte Parameter auswerten muss. Man kann mit Bitmasken zum filtern arbeiten usw. Meine Meinung. Ich kann damit einfach unterbinden das Pin Bit.4 versehentlich geschalten wird.
Wenn es allerdings zur Laufzeit änderbar sein soll, dann nimmt man eine Methode und kann den Pin mittels INPUT/OUTPUT konfigurieren. Mit letzterem kann man die Arduino defines verwenden.
Dann könnte man nach der Objekt Initialisierung mit 8 Methodenaufrufen die Pins konfigurieren.