Forum: Mikrocontroller und Digitale Elektronik Probleme bei abhängigen Arrays Code


von D. Z. (zoundgalaxy)


Lesenswert?

Hallo zusammen,

ich möchte mit einem 4fach Dipswitch eine „Art“ Adressierung vornehmen. 
Diese verändert im Nachgang dann den Ausgabewert der nachfolgenden 5 
Taster.

Code Beispiel der Arrays:
1
//Dipswitch 1-4 gibt die Adresse vor
2
int pinNumbers1[4] = { 2, 3, 4, 5 };              //Pin
3
int buttonNumbers1[4] = { 1, 2, 3, 4 };           //Dipswitch
4
5
//Switch 5-9 gibt einen Key (a-z, Shift + a-x, oder 0-9) aus
6
int pinNumbers2[5] = { 6, 7, 8, 9, 10 };        //Pin
7
int buttonNumbers2[5] = { 5, 6, 7, 8, 9 };      //Switch
8
int key[60] = {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,Shift+a,Shift+b,Shift+c,Shift+d,Shift+e,Shift+f,Shift+g,Shift+h,Shift+i,Shift+j,Shift+k,Shift+l,Shift+m,Shift+n,Shift+o,Shift+p,Shift+q,Shift+r,Shift+s,Shift+t,Shift+u,Shift+v,Shift+w,Shift+x};    
9
//Ausgabe des Tasters

Hier mal ein tabellarisches Beispiel:
1
wenn pinNumbers1  
2
2   =   low     2   =   high    2   =   low     ...
3
3   =   low     3   =   low     3   =   high    ...   
4
4   =   low     4   =   low     4   =   low     ...
5
5   =   low     5   =   low     5   =   low     ...
6
ist buttonNumbers1    
7
0, 0, 0, 0      1, 0, 0, 0      0, 1, 0, 0      ...
8
ist buttonNumbers2    
9
5   =   a       5   =   f       5   =   k       ...
10
6   =   b       6   =   g       6   =   l       ...
11
7   =   c       7   =   h       7   =   m       ...
12
8   =   d       8   =   i       8   =   n       ...
13
9   =   e       9   =   j       9   =   o       ...

Code Beispiel:
1
void setup()
2
3
{
4
    if (pinNumbers1[0] == LOW &&
5
        pinNumbers1[1] == LOW &&
6
        pinNumbers1[2] == LOW &&
7
        pinNumbers1[3] == LOW)
8
    {
9
        buttonNumbers2[0] == key[0] && 
10
        buttonNumbers2[1] == key[1] &&
11
        buttonNumbers2[2] == key[2] && 
12
        buttonNumbers2[3] == key[3] &&
13
        buttonNumbers2[4] == key[4];
14
    }
15
}

Wie kann ich dies nun vereinfacht realisieren?

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Machen wir das mal in leserlich:
1
void setup()
2
{
3
    if (pinNumbers1[0] == LOW &&
4
        pinNumbers1[1] == LOW &&
5
        pinNumbers1[2] == LOW &&
6
        pinNumbers1[3] == LOW)
7
    {
8
        buttonNumbers2[0] == key[0] && 
9
        buttonNumbers2[1] == key[1] &&
10
        buttonNumbers2[2] == key[2] && 
11
        buttonNumbers2[3] == key[3] &&
12
        buttonNumbers2[4] == key[4];
13
    }
14
}
Dann sieht man auch, dass das so keinen Sinn ergibt. Zum einen hat der 
Code in dem Block keinerlei Effekt. Zum anderen hat pinNumbers1[0] den 
Wert 2, pinNumbers1[1] den Wert 3 u.s.w., und es scheint wenig sinnvoll, 
die mit LOW (was immer das sein mag) zu vergleichen.
Deshalb ist mir nicht so ganz klar, was das soll. Und warum kommen da 
nur pinNumbers1 und buttonNumbers2 vor?

von Klaus W. (mfgkw)


Lesenswert?

Und wieso ist key[] 60 Elemente lang?
Müsste das nicht 80 sein (2^4 Adressen = 16, mal die Bedeutung von 5 
Tasten)?

Wenn meine vage Idee von deiner Absicht halbwegs hinkommt, wäre für key 
vielleicht ein zweidimensionales Feld besser.

von D. Z. (zoundgalaxy)


Lesenswert?

Wie nachfolgend skizziert:

> Hier mal ein tabellarisches Beispiel:
>
>
1
> wenn pinNumbers1
2
> 2   =   low     2   =   high    2   =   low     ...
3
> 3   =   low     3   =   low     3   =   high    ...
4
> 4   =   low     4   =   low     4   =   low     ...
5
> 5   =   low     5   =   low     5   =   low     ...
6
> ist buttonNumbers1
7
> 0, 0, 0, 0      1, 0, 0, 0      0, 1, 0, 0      ...
8
> ist buttonNumbers2
9
> 5   =   a       5   =   f       5   =   k       ...
10
> 6   =   b       6   =   g       6   =   l       ...
11
> 7   =   c       7   =   h       7   =   m       ...
12
> 8   =   d       8   =   i       8   =   n       ...
13
> 9   =   e       9   =   j       9   =   o       ...
14
>
>

soll der Taster1 (sowie auch die rewstlichen) wie ein Keyboard agieren 
und beispielsweise entweder Key- "a" oder "f" oder "k" usw. je nach 
Stellung des 4fach Dipswitch (binär) ausgeben.

Sprich, wenn Dipswitch Switch 1, 2, 3 und 4 jeweils „LOW“ sind, also 
keine Spannung anliegen haben, soll Taster1 „a“, Taster2 „b“, Taster3 
„c“, Taster4 „d“ und Taster5 „e“ ausgeben.

Wechselt allerdings Dipswitch Switch 1 von „LOW“ auf „High“ (Spannung 
liegen an) und 2, 3 und 4 bleiben jeweils auf „LOW“ (keine Spannung 
liegen an), soll Taster1 „f“, Taster2 „g“, Taster3 „h“, Taster4 „i“ und 
Taster5 „j“ ausgeben.

usw.

Dafür suche ich den passenden Code.

von PittyJ (Gast)


Lesenswert?

Nach meinen C-Kenntnissen macht folgendes Statement einfach gar nichts.
    {
        buttonNumbers2[0] == key[0] &&
        buttonNumbers2[1] == key[1] &&
        buttonNumbers2[2] == key[2] &&
        buttonNumbers2[3] == key[3] &&
        buttonNumbers2[4] == key[4];
    }
Es wird verglichen, und das Ergebnis ignoriert. Aber vielleicht verstehe 
ich auch das moderne C-2022 nicht mehr.


Ich würde aus den pinNumbers1[] , die ja nur Low oder High sind, eine 
Zahl machen.

Zahl =     pinNumbers1[0]
        | (pinNumbers1[1] <<1)
        | (pinNumbers1[2] <<2)
        | (pinNumbers1[3] <<3);
Und dann einfach mit der Zahl weiter rechnen.

von D. Z. (zoundgalaxy)


Lesenswert?

Klaus W. schrieb:
> Und wieso ist key[] 60 Elemente lang?
> Müsste das nicht 80 sein (2^4 Adressen = 16, mal die Bedeutung von 5
> Tasten)?
>
> Wenn meine vage Idee von deiner Absicht halbwegs hinkommt, wäre für key
> vielleicht ein zweidimensionales Feld besser.

weil es aktuell, wie oben zu sehen ist, von "a" bis "Shift+x" geht, was 
dann 60 Elemente ergibt. Der Rest ist erstmal als "Puffer" da und wird 
bei Bedarf dann erweitert. Somit dann auch von 60 aufwärts auf 80 
vervollständigt.

von D. Z. (zoundgalaxy)


Lesenswert?

Das Code Beispiel sollte nur der Verdeutlichung dienen, bewirkt aber 
anscheinend das Gegenteil. Deswegen ignoriert dies bitte.

von Teo D. (teoderix)


Lesenswert?

D. Z. schrieb:
> Wechselt allerdings Dipswitch Switch 1 von „LOW“ auf „High“ (Spannung
> liegen an) und 2, 3 und 4 bleiben jeweils auf „LOW“ (keine Spannung
> liegen an), soll Taster1 „f“, Taster2 „g“, Taster3 „h“, Taster4 „i“ und
> Taster5 „j“ ausgeben.

Ändere einfach den Startwert des Index deines Arrays in der 
Ausgaberoutine.
Index = Mäuseklavier * 5;

von Falk B. (falk)


Lesenswert?

D. Z. schrieb:
> ich möchte mit einem 4fach Dipswitch eine „Art“ Adressierung vornehmen.
> Diese verändert im Nachgang dann den Ausgabewert der nachfolgenden 5
> Taster.

Alles viel zu chaotisch und aufgeblasen.

Zuerst liest man den DIP-Switch ein, damit hat man eine 4 Bit Zahl. Man 
hantiert nicht mit den einzelnen Bits. mit der 4 Bit Zahl wählt man 
einen Bereich aus, mit dein 5 Einzeltasten das Element. Das schreit nach 
einem zweidimensionalen Array. Sinnvollerweise organisiere man das so, 
daß es logisch ist, ggf auch mit Lücken.
1
char key[15][5] = {
2
    {'a','b','c','d','e'}, {'f','g','h','i','j'}, {'k','l','m','n','o'}, 
3
    {'p','q','r','s','t'}, {'u','v','w','x','y'}, {'z',0,0,0,0},
4
    {'0','1','2','3','4'}, {'5','6','7','8','9'},
5
    {'A','B','C','D','E'}, {'F','G','H','I','J'}, {'K','L','M','N','O'}, 
6
    {'P','Q','R','S','T'}, {'U','V','W','X','Y'}, {'Z',0,0,0,0}
7
};
8
9
int dip, button;
10
char mein_zeichen;
11
12
// DIP-Schalter einlesen, invertiert
13
dip = 0;
14
if (!digitalRead(2)) dip+=1;
15
if (!digitalRead(3)) dip+=2;
16
if (!digitalRead(4)) dip+=4;
17
if (!digitalRead(5)) dip+=8;
18
19
// Taster einlesen, invertiert
20
button = 100;
21
if (!digitalRead(6)) button=0;
22
if (!digitalRead(7)) button=1;
23
if (!digitalRead(8)) button=2;
24
if (!digitalRead(9)) button=3;
25
if (!digitalRead(10)) button=4;
26
27
mein_zeichen = 0;
28
if (buttton <5) mein_zeichen = key[dip][button];

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

@Falk: Meintest du zufällig key[16][5]?

von Falk B. (falk)


Lesenswert?

Klaus W. schrieb:
> @Falk: Meintest du zufällig key[16][5]?

Erwischt! ;-)

von Klaus W. (mfgkw)


Lesenswert?

Dann bin ich beruhigt.
Mit 5*16 bekomme ich meine 80 Elemente.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

D. Z. schrieb:
> ich möchte mit einem 4fach Dipswitch eine „Art“ Adressierung vornehmen.

Es schadet nichts, sich als blutiger Anfänger erstmal mit dem 
Binärsystem zu beschäftigen. Das ist die Grundlage jeglicher Nutzung von 
IO-Pins.
Dann verschwinden die riesigen if/else Konstrukte ganz automatisch und 
der Code wird erheblich besser lesbar.

von Teo D. (teoderix)


Lesenswert?

D. Z. schrieb:
> int pinNumbers1[4] = { 2, 3, 4, 5 };              //Pin
> ....

Ich bastle mir ein Byte....
int pinNumbers; -> int dipswitch_summe; // weils ja keine Pinnummer 
sind....
dipswitch_summe = (dipswitch_pin1 + (dipswitch_pin2 << 1) + 
(dipswitch_pin3 << 2) + (dipswitch_pin4 << 3));

https://www.mikrocontroller.net/articles/Bitmanipulation


Vorausgesetzt:
Peter D. schrieb:
> Es schadet nichts, sich als blutiger Anfänger erstmal mit dem
> Binärsystem zu beschäftigen.


Starthilfe Ente
bb

von D. Z. (zoundgalaxy)


Lesenswert?

@Falk Danke, dass ist ne super Idee. Werde es gleich mal so umschreiben 
und um @Klaus seinen Einwand und meine weiteren Daten ergänzen.

von Falk B. (falk)


Lesenswert?

Hmm, damit man nicht so endlos viele Hochkommas eintippen muss, geht es 
auch deutlich einfacher. Warum ist mir das nicht gleich eingefallen? 
Egal.
1
char key[16][5] = {
2
    "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
3
    "01234", "56789",
4
    "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000", 
5
    "00000", "00000"
6
};

von Rolf M. (rmagnus)


Lesenswert?

Das geht allerdings nur in C, nicht in C++.

von Falk B. (falk)


Lesenswert?

Rolf M. schrieb:
> Das geht allerdings nur in C, nicht in C++.

Häää? Warum soll das in C++ nicht gehen? Das sind triviale Arrays mit 
Strings.

von EAF (Gast)


Lesenswert?

Rolf M. schrieb:
> Das geht allerdings nur in C, nicht in C++.

Doch schon....
Zumindest der GCC lässt es durchgehen.
warning: initializer-string for 'char [5]' is too long [-fpermissive]
Die Meldung ist berechtigt, da die abschließende Null nicht mit 
gespeichert wird.
1
#include <Streaming.h> // die Lib findest du selber ;-)
2
Print &cout = Serial; // cout Emulation für "Arme"
3
4
char key[16][5] = {
5
    "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
6
    "01234", "56789",
7
    "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000", 
8
    "00000", "00000"
9
};
10
11
12
void setup()
13
{
14
  Serial.begin(9600);
15
  cout << F("Start: ") << F(__FILE__) << endl;
16
17
  for(char[5] &dim1:key)
18
  {
19
    for(char &dim2:dim1) cout << dim2; 
20
    cout << endl; 
21
  }
22
23
}
24
25
void loop()
26
{
27
}

von Rolf M. (rmagnus)


Lesenswert?

Falk B. schrieb:
> Rolf M. schrieb:
>> Das geht allerdings nur in C, nicht in C++.
>
> Häää? Warum soll das in C++ nicht gehen? Das sind triviale Arrays mit
> Strings.

Weil die Stringliterale jeweils 6 Bytes groß sind, da sie das 
abschließende \0 enthalten. In C gibt es eine Sonderregel, dass das auch 
weggelassen werden kann, wenn das Ziel genau so groß ist, dass das \0 
gerade nicht mehr rein passt. Die gibt's in C++ aber nicht.


EAF schrieb:
> Rolf M. schrieb:
>> Das geht allerdings nur in C, nicht in C++.
>
> Doch schon....
> Zumindest der GCC lässt es durchgehen.

Meiner nicht.

> warning: initializer-string for 'char [5]' is too long [-fpermissive]
> Die Meldung ist berechtigt, da die abschließende Null nicht mit
> gespeichert wird.

Bei mir ist das keine Warnung, sondern ein Fehler. Offenbar hast du dem 
Compiler noch ein -fpermissive oder irgendetwas, das das beinhaltet, 
mitgegeben.
1
g++ charkey.cpp 
2
charkey.cpp:3:5: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
3
    3 |     "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
4
      |     ^~~~~~~
5
charkey.cpp:3:14: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
6
    3 |     "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
7
      |              ^~~~~~~
8
charkey.cpp:3:23: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
9
    3 |     "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
10
      |                       ^~~~~~~
11
charkey.cpp:3:32: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
12
    3 |     "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
13
      |                                ^~~~~~~
14
charkey.cpp:3:41: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
15
    3 |     "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
16
      |                                         ^~~~~~~
17
charkey.cpp:3:50: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
18
    3 |     "abcde", "fghij", "klmno", "pqrst", "uvwxy", "z0000",
19
      |                                                  ^~~~~~~
20
charkey.cpp:5:5: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
21
    5 |     "01234", "56789",
22
      |     ^~~~~~~
23
charkey.cpp:5:14: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
24
    5 |     "01234", "56789",
25
      |              ^~~~~~~
26
charkey.cpp:7:5: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
27
    7 |     "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000",
28
      |     ^~~~~~~
29
charkey.cpp:7:14: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
30
    7 |     "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000",
31
      |              ^~~~~~~
32
charkey.cpp:7:23: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
33
    7 |     "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000",
34
      |                       ^~~~~~~
35
charkey.cpp:7:32: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
36
    7 |     "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000",
37
      |                                ^~~~~~~
38
charkey.cpp:7:41: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
39
    7 |     "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000",
40
      |                                         ^~~~~~~
41
charkey.cpp:7:50: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
42
    7 |     "ABCDE", "FGHIJ", "KLMNO", "PQRST", "UVWXY", "Z0000",
43
      |                                                  ^~~~~~~
44
charkey.cpp:9:5: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
45
    9 |     "00000", "00000"
46
      |     ^~~~~~~
47
charkey.cpp:9:14: error: initializer-string for ‘char [5]’ is too long [-fpermissive]
48
    9 |     "00000", "00000"
49
      |              ^~~~~~~

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Rolf M. schrieb:
> Weil die Stringliterale jeweils 6 Bytes groß sind, da sie das
> abschließende \0 enthalten. In C gibt es eine Sonderregel, dass das auch
> weggelassen werden kann, wenn das Ziel genau so groß ist, dass das \0
> gerade nicht mehr rein passt. Die gibt's in C++ aber nicht.

Ja mein Gott, dann mach da 6 chars pro Zeile und gut. Die 16 Bytes 
"Verschwendung" können wir uns wohl gerade noch leisten.

char key[16][6]

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.