Forum: Mikrocontroller und Digitale Elektronik Arduino Schalter abfragen


von Fabian F. (fabiii9)


Lesenswert?

Hallo zusammen,

zu meinem Vorhaben:
Ich möchte mehrere Schalter abfragen, welche an Schieberegister 
angeschlossen werden.

Wenn der Schalter[i] auf "an" steht soll ein MidiSignal "Noteon" Taste 
[i] gesendet werden, wenn er auf aus steht soll ein Noteoff gesendet 
werden.

Ich habe jetzt in mehreren Etappen programmiert und möchte mich so 
langsam der lösung nähern.

Ich habe es geschafft zwei Schieberegister abzufragen.
Jedoch ist dazu recht viel Code notwendig und vorallem muss ich für 
jedes Schieberegister einen extraCode-Block schreiben.

Ich möchte eigentlich, dass ich einfach mehrere Schieberegister 
aneinanderhängen ohne an dem Code etwas zu ändern und automatisch das 
erste schieberegister Taste 1-8 übernimmt, das 2. Schieberegister Taste 
9-16, das 3. Schieberegister Taste 17-24.

Wie könnte ich den Code vereinfachen??
Ich komm einfach momentan auf nichts leichteres

Ich bedanke mich jetzt schon einma für Eure geduld und LG
Fabi

Code:
1
//**************************************************************//
2
//  Name    : shiftIn Example 2.1                               //
3
//  Author  : Carlyn Maw                                        //
4
//  Date    : 25 Jan, 2007                                      //
5
//  Version : 1.0                                               //
6
//  Notes   : Code for using a CD4021B Shift Register       //
7
//          :                                                   //
8
//****************************************************************
9
10
//define where your pins are
11
int latchPin = 8;
12
int dataPin = 9;
13
int clockPin = 7;
14
15
//Define variables to hold the data
16
//for each shift register.
17
//starting with non-zero numbers can help
18
//troubleshoot
19
byte switchVar1 = 72;  //01001000
20
byte switchVar2 = 159; //10011111
21
22
23
int Befehl = 183; //Note on, Kanal 8
24
int S1Taste[] = {1, 2, 3, 4, 5, 6, 7, 8};
25
int S2Taste[] = {9, 10, 11, 12, 13, 14, 15, 16};
26
int Wert1 = 127;
27
int Wert2 = 0;
28
29
int TasteAlt;
30
31
void setup() {
32
  //start serial
33
  Serial.begin(9600);
34
35
  //define pin modes
36
  pinMode(latchPin, OUTPUT);
37
  pinMode(clockPin, OUTPUT);
38
  pinMode(dataPin, INPUT);
39
40
}
41
42
43
////// ----------------------------------------shiftIn function
44
///// just needs the location of the data pin and the clock pin
45
///// it returns a byte with each bit in the byte corresponding
46
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0
47
48
byte shift(int myDataPin, int myClockPin) {
49
  int i;
50
  int temp = 0;
51
  int pinState;
52
  byte myDataIn = 0;
53
54
  pinMode(myClockPin, OUTPUT);
55
  pinMode(myDataPin, INPUT);
56
57
  //we will be holding the clock pin high 8 times (0,..,7) at the
58
  //end of each time through the for loop
59
60
  //at the begining of each loop when we set the clock low, it will
61
  //be doing the necessary low to high drop to cause the shift
62
  //register's DataPin to change state based on the value
63
  //of the next bit in its serial information flow.
64
  //The register transmits the information about the pins from pin 7 to pin 0
65
  //so that is why our function counts down
66
  for (i = 7; i >= 0; i--)
67
  {
68
    digitalWrite(myClockPin, 0);
69
    delayMicroseconds(2);
70
    temp = digitalRead(myDataPin);
71
    if (temp) {
72
      pinState = 1;
73
      //set the bit to 0 no matter what
74
      myDataIn = myDataIn | (1 << i);
75
    }
76
    else {
77
      //turn it off -- only necessary for debuging
78
      //print statement since myDataIn starts as 0
79
      pinState = 0;
80
    }
81
82
    //Debuging print statements
83
    //Serial.print(pinState);
84
    //Serial.print("     ");
85
    //Serial.println (dataIn, BIN);
86
87
    digitalWrite(myClockPin, 1);
88
89
  }
90
  //debuging print statements whitespace
91
  //Serial.println();
92
  //Serial.println(myDataIn, BIN);
93
  return myDataIn;
94
}
95
96
97
void loop() {
98
99
  //Pulse the latch pin:
100
  //set it to 1 to collect parallel data
101
  digitalWrite(latchPin, 1);
102
  //set it to 1 to collect parallel data, wait
103
  delayMicroseconds(20);
104
  //set it to 0 to transmit data serially
105
  digitalWrite(latchPin, 0);
106
107
  //while the shift register is in serial mode
108
  //collect each shift register into a byte
109
  //the register attached to the chip comes in first
110
  switchVar1 = shift(dataPin, clockPin);
111
  switchVar2 = shift(dataPin, clockPin);
112
113
  //Print out the results.
114
  //leading 0's at the top of the byte
115
  //(7, 6, 5, etc) will be dropped before
116
  //the first pin that has a high input
117
  //reading
118
119
  for (int n = 0; n <= 7; n++)
120
  {
121
    //so, when n is 3, it compares the bits
122
    //in switchVar1 and the binary number 00001000
123
    //which will only return true if there is a
124
    //1 in that bit (ie that pin) from the shift
125
    //register.
126
    if ((switchVar1 & (1 << n) ) && TasteAlt==LOW ) {
127
      //print the value of the array location
128
      Serial.println(Befehl);
129
      Serial.println(S1Taste[n]);
130
      Serial.println(Wert1);
131
      TasteAlt=HIGH;
132
    }
133
    else if ((switchVar1 & (1 << n) ) && TasteAlt==HIGH ) {
134
      //print the value of the array location
135
      Serial.println(Befehl);
136
      Serial.println(S1Taste[n]);
137
      Serial.println(Wert2);
138
      TasteAlt=LOW;
139
    }
140
  }
141
142
  
143
  for (int n = 0; n <= 7; n++)
144
  {
145
    //so, when n is 3, it compares the bits
146
    //in switchVar1 and the binary number 00001000
147
    //which will only return true if there is a
148
    //1 in that bit (ie that pin) from the shift
149
    //register.
150
    if ((switchVar2 & (1 << n) ) && TasteAlt==LOW ) {
151
      //print the value of the array location
152
      Serial.println(Befehl);
153
      Serial.println(S2Taste[n]);
154
      Serial.println(Wert1);
155
      TasteAlt=HIGH;
156
    }
157
    else if ((switchVar2 & (1 << n) ) && TasteAlt==HIGH ) {
158
      //print the value of the array location
159
      Serial.println(Befehl);
160
      Serial.println(S2Taste[n]);
161
      Serial.println(Wert2);
162
      TasteAlt=LOW;
163
    }
164
  }
165
166
   /* if (switchVar2 & (1 << n) && TasteAlt==LOW ) {
167
      //print the value of the array location
168
      Serial.println(Befehl);
169
      Serial.println(S2Taste[n]);
170
      Serial.println(Wert1);
171
      TasteAlt=HIGH;
172
    }
173
    else if ((switchVar2 & (1 << n) ) && TasteAlt==HIGH ) {
174
      //print the value of the array location
175
      Serial.println(Befehl);
176
      Serial.println(S1Taste[n]);
177
      Serial.println(Wert2);
178
      TasteAlt=LOW;
179
    }
180
   } */
181
182
  //white space
183
  Serial.println("-------------------");
184
  //delay so all these print satements can keep up.
185
  delay(500);
186
}
187
188
//------------------------------------------------end main loop

von Rainer U. (r-u)


Lesenswert?

Fabian M. schrieb:
> Ich habe es geschafft zwei Schieberegister abzufragen.
> Jedoch ist dazu recht viel Code notwendig und vorallem muss ich für
> jedes Schieberegister einen extraCode-Block schreiben.
>
> Ich möchte eigentlich, dass ich einfach mehrere Schieberegister
> aneinanderhängen ohne an dem Code etwas zu ändern

Du kannst den Ausgang des ersten Schieberegisters auf den Eingang 
(soweit vorhanden) oder sonst auf das erste Bit vom zweiten 
Schieberegister schalten. Dann musst Du halt entsprechend mehr 
Clock-Pulse generieren, um alle Daten auszulesen.

von Fehlformatierer (Gast)


Lesenswert?

Fabian M. schrieb:
> zu meinem Vorhaben:

Zunächst solltest du das vorhaben:


Wichtige Regeln - erst lesen, dann posten!

    .........
    Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

    [c ]C-Code[/c]

von Einer K. (Gast)


Lesenswert?

Verketten der Schieberegister wurde schon genannt.
Arduino hat eine shiftIn() Funktion im Lieferumfang.

Mit den beiden Maßnahmen kannst du deinen Quellcode auf geschätzte 10% 
eindampfen.

Nächste Optimierung:
Dem Hardware SPI die Schieberei überlassen. Und das dann noch Interrupt 
getrieben. Das dürfte den Zeitbedarf dann auch auf ca 10% eindampfen.

von Joachim B. (jar)


Lesenswert?

wozu Schieberegister?

ich würde diese kaskadierbaren Ports nehmen I2C

http://www.ebay.de/itm/PCF8574-PCF8574T-I2C-8-Bit-IO-GPIO-Expander-Module-for-Arduino-Raspberry-Pi-UK-/272432637606?var=&hash=item3f6e4026a6:m:mQFPRLxSj-zVxa61Qe6YVhQ

bis zu 8 sind möglich 4 Strippen, 2x I2C und VCC + GND gibt 64 Ports 
(8x8)

I2C Libs gibt es auch und scheint mir sicherer weil langsamer, wer muss 
denn Taster oder Schalter im Mbit Tempo abfragen?

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

viele Schalter kann man auch als Matrix aufbauen, das veringert die Zahl 
der Ports beachtlich, mit nur 2x 8-bit also 16 Ports sind dann auch als 
Matrix 8x8 = 64 Schalter möglich.

von Fabian F. (fabiii9)


Lesenswert?

Hallo,
Vielen Dank für Eure Antworten!

Rainer U. schrieb:
> Du kannst den Ausgang des ersten Schieberegisters auf den Eingang
> (soweit vorhanden) oder sonst auf das erste Bit vom zweiten
> Schieberegister schalten. Dann musst Du halt entsprechend mehr
> Clock-Pulse generieren, um alle Daten auszulesen.

Das werde ich gleich mal ausprobieren und etwas am Code tüfteln!

Arduino F. schrieb:
> Arduino hat eine shiftIn() Funktion im Lieferumfang.

Vielen Dank für die Info! Werde ich mir genauer anschauen.

Fehlformatierer schrieb:
> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Oh verzeihung! Für die Zukunft weiß ich es jetzt! :)

Ich habe mich schon durch viele Tutorials über Schieberegister 
gearbeitet. Gibt es echt gute auf Youtube. Nur wird leider immer nur das 
Schieberegister als Out-Schieberegister vorgestellt und nie als 
In-Schieberegister.

Werde nochmal etwas nachdenken und tüfteln.
Melde ich dann nochmal, wenn ich eine konkrete Frage habe!
Vielen Dank!

VG
Fabi

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.