1 | #include <Wire.h> //Einbinden der I2C Library
|
2 |
|
3 | /*
|
4 | * Portexpander: PF575 / PCF8575 (Beide Bezeichnungen sind 1 und das selbe Bauteil!)
|
5 | *
|
6 | *Notiz:
|
7 | *http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html#ga6a441da9211eb85881d99c60b1003552
|
8 | *
|
9 | *Portexpanderaddressen (1.Array) müssen als Hex (0x..) gespeichert sein,
|
10 | *damit die Portexpander richtig angesprochen werden
|
11 | *
|
12 | *Led´s sind LOW-aktiv! ( 0=an )
|
13 | */
|
14 | char Portexpander [9] = {0x27, 0x23, 0x24, 0x20, 0x25, 0x21, 0x26, 0x22, '\0'}; //Adressen der 8 Portexpander im Uhrzeigersinn.
|
15 | /*~~~Die Arrays dienen dazu die Informationen für alle 10 Led´s zu halten und dabei möglichst wenig Vatiablennamen zu haben.~~~*/
|
16 | /*~~~(dabei ist die erste Stelle immer frei, sodass die Stellen 1-10 genutzt werden)~~~*/
|
17 | char ExpanderNr [12]; //Zu welchem portexpander gehört die LED?
|
18 | char ledzahl [12]; //Welche LED soll am entsprechenden Expander angesteuert werden?
|
19 | char highbyte [9]; //Übertragung an die Portexpander Byte1
|
20 | char lowbyte [9]; //Übertragung an die Portexpander Byte2
|
21 | char bufer [45]; //Buffer
|
22 | String DataIN, Befehl; //Datenstrings anlegen
|
23 | uint8_t i, x=0, a, anzahl; //Variablen anlegen
|
24 | uint16_t daten;
|
25 |
|
26 |
|
27 |
|
28 | void setup()
|
29 | {
|
30 | Wire.begin(); //Initialisieren der Bibliothek
|
31 | Serial.begin(9600) ; //festlegen der Baud-Rate
|
32 | for ( i=0 ; i<8 ; i++)
|
33 | {
|
34 | Wire.beginTransmission(Portexpander[i]); //Bereitet die Datenübertragung an den Portexpander vor
|
35 | Wire.write(0xFF); //Alle LED´s AUS
|
36 | Wire.write(0xFF); //Alle LED´s AUS
|
37 | Wire.endTransmission(); //Senden der Daten
|
38 | }
|
39 | }
|
40 |
|
41 |
|
42 |
|
43 | //---------------------------------//
|
44 | //~~~~~~~~~~Hauptprogramm~~~~~~~~~~\\
|
45 | //---------------------------------//
|
46 |
|
47 | void loop()
|
48 | {
|
49 | /*~~~~~Neuen String einlesen~~~~~*/
|
50 | if ( Serial.available() ) //Wenn sich Daten im Eingangspuffer befinden
|
51 | { //
|
52 | anzahl = Serial.readBytesUntil('#',bufer,42); //Wie viele Daten befinden sich im Eingangspuffer? Und diese in bufer schreiben
|
53 | anzahl = anzahl/4; //das a_ vorne spielt keine rolle, da a_ nur 2/4/0,5 und keine Kommazahlen und kein Rest mitgeschrieben wird
|
54 | DataIN = bufer; //Eingehende Daten in DataIN als String übertragen
|
55 | Befehl = DataIN.substring(0,1); //1.Zeichen auslesen
|
56 | Serial.println(DataIN);
|
57 |
|
58 |
|
59 |
|
60 | /*-------------------------------------------------------------------------
|
61 | * Informations Befehl
|
62 | */-------------------------------------------------------------------------
|
63 | if ( Befehl == "?" ) //<<---------Fehlermeldung Zeile63
|
64 | {
|
65 | Serial.println("?-Befehl");
|
66 | /*~~Einlesen der Informationen~~*/
|
67 | a = 0;
|
68 | for ( i=0 ; i<8 ; i++ ) //Für alle 8 Portexpander
|
69 | {
|
70 | Wire.requestFrom(Portexpander[i] , 2); //Informationen vom Portexpander anfordern
|
71 | while (Wire.available() > 0) //Wenn Informationen vorliegen(vom Expander gesendet wurden)
|
72 | {
|
73 | lowbyte [i] = 255 - Wire.read(); //255-, da so alle Bits des Byts invertiert werden, weil
|
74 | highbyte[i] = 255 - Wire.read(); //0 ja LED=AN bedeutet, und wir so für LED=AN=1 haben, auf das wir abfragen können
|
75 | }
|
76 |
|
77 | /*~~Abfrage auf leuchtende LED´s~~*/
|
78 | for ( x=0 ; x<8 ; x++ ) //Für alle 8Bit eines Byte
|
79 | {
|
80 | if (bitRead(lowbyte [i] , x) == 1) //Für das 1.eingegangene Byte
|
81 | { //Wenn eine 1 vorliegt (also LED=AN)
|
82 | ledzahl[a] = (i * 16) + x; //Wert der LED = 16LED´s pro Portexpander (i) + stelle am Expander (x)
|
83 | a++; //Auf den Array-Platz der nächsten LED weiterzählen
|
84 | }
|
85 | if (bitRead(highbyte[i] , x) == 1) //Für das 2.eingegangene Byte
|
86 | { //Wenn eine 1 vorliegt (also LED=AN)
|
87 | ledzahl[a] = (i * 16) + x +8; //Wert der LED = 16LED´s pro Portexpander (i) + stelle am Expander (x)+8 für 2.Byte
|
88 | a++; //Auf den Array-Platz der nächsten LED weiterzählen
|
89 | }
|
90 | } //Ende Abfrage auf leuchtende LED´s
|
91 | } //Ende Einlesen der Informationen
|
92 | /*~~Ausgebe der Informationen~~*/ //(Welche LED´s Leuchten)
|
93 | Serial.print(a),Serial.println(" LED`s an");
|
94 | for ( i=0 ; i<a ; i++)
|
95 | {
|
96 | Serial.print("LED"),Serial.print(i+1), Serial.print(" "),Serial.println(ledzahl[i],DEC);
|
97 | }
|
98 | }// Ende ?-Befehl
|
99 |
|
100 | /*------------------------------------------------------------------------------
|
101 | * Setz Befehl
|
102 | */-----------------------------------------------------------------------------
|
103 | else if ( Befehl == "s") //Zustandsänderung von Led´s
|
104 | {
|
105 | Serial.print(anzahl, DEC) , Serial.println(" LEDs anzusprechen");
|
106 | /*~~~~~Werte vorsetzen~~~~~*/
|
107 | for( i=0 ; i<8 ; i++)
|
108 | {
|
109 | lowbyte [i] = 0xFF;
|
110 | highbyte[i] = 0xFF;
|
111 | }
|
112 | /*~~~~~Auslesen der Informationen~~~~~*/ //Auslesen und auswerten der informationen
|
113 | for( i=0 ; i<anzahl ; i++) //aus dem Datenstring
|
114 | {
|
115 | //String --> DEZ-Zahl //ASCII 0-9 = 0x30 - 0x39 --> ASCII - 0x30 = dezZahl
|
116 | x = 100 * (DataIN[i*4+2] - 0x30); //100er Stelle
|
117 | x = x + ( 10 * (DataIN[i*4+3] - 0x30)); // 10er Stelle
|
118 | x = x + (DataIN[i*4+4] - 0x30); // 1er Stelle
|
119 | if ( x > 127 ) { x = x-128;} //Beschränkung auf 127
|
120 | Serial.print("x ") , Serial.println(x);
|
121 | Serial.println();
|
122 | ledzahl[i] = x; //Information in Array speichern (x= Welche LED von Allen 128 wird angesprochen?)
|
123 | ExpanderNr[i] = ledzahl[i] / 16; //Welcher Portexpander muss angesprochen werden? //Expander 0-7
|
124 | ledzahl[i] = ledzahl[i] % 16; //Welche Led dieses Expanders //0-15 also 16LEDs pro Expander
|
125 | }
|
126 |
|
127 | /*~~~~~Bitmanipulation~~~~~*/
|
128 | for( i=0 ; i<anzahl ; i++)
|
129 | {
|
130 | //Aufteilen in High & Low Byte
|
131 | if ( ledzahl[i] > 7 )
|
132 | {
|
133 | ledzahl[i] = ledzahl[i] - 8;
|
134 | highbyte[ ExpanderNr[i] ] &=~ ( 1 << ledzahl[i] );
|
135 | }
|
136 | else { lowbyte[ ExpanderNr[i] ] &=~ ( 1 << ledzahl[i] ); }
|
137 | /*hier wir das Bit in den entsprechenden Byts der EXPANDER gesetzt (auf 0).
|
138 | * Die Information, welche LED angesteuert werden soll wird hier also in die Bytes reingeschrieben, welche
|
139 | * nacher an die Portexpander übertragen werden.*/
|
140 | }
|
141 |
|
142 | /*~~~~~Ausgabe~~~~~*/ //Ausgabe der fertigen Daten-Bytes auf die Portexpander
|
143 | for( i=0 ; i<8 ; i++)
|
144 | {
|
145 | if (( lowbyte[i] != 0xFF ) || ( highbyte[i] != 0xFF ))
|
146 | {
|
147 | Wire.beginTransmission( Portexpander[i] ); //Bereitet die Datenübertragung an den Portexpander vor
|
148 | Wire.write( lowbyte[i] ); //Schreibt den Inhalt für das 1.Byte in den Sendepuffer
|
149 | Wire.write( highbyte[i] ); //Schreibt den Inhalt für das 1.Byte in den Sendepuffer
|
150 | Wire.endTransmission(); //Überträgt die gepufferten Daten
|
151 | }
|
152 | }
|
153 |
|
154 | }//Ende s-Befehl
|
155 | } //Ende Serial.availabile
|
156 | } //Ende Void Loop //<<---------Fehlermeldung Zeile156
|