Forum: Mikrocontroller und Digitale Elektronik 2-Dimensionales Array. Fehler. Läuft aber trotzdem ?


von Dirk F (Gast)


Lesenswert?

Hallo zusammen,
ich habe ein 2-Dimensionaled Feld erstellt, in dem ich den Zustand von 
74 Relais auf 5 Steckkarten festhalten wollte.
Dabei ist mir der Fehler pssiert, dass ich das Feld für die Kartennummer 
um 1 zu klein gewählt habe.
(Ich weiss, normalerwise fängt man bei 0 an, und nicht bei 1. Bitte dies 
nicht diskutuieren)

unsigned char Relais[5][75]; //Karte 1-5   Relais 1-74

Seltsamerweise funktioniert das Programm aber trotzdem, wenn ich Schreib 
/ Lesezugriff auf z.B Relais[5][74]  = 1;  mache.
Ist das jetzt nur Glück, dass meine MCU nicht abstürzt weil der 
beschriebene Speicherbereich zufällig frei war ?

LG Dirk

von Falk B. (falk)


Lesenswert?

@ Dirk F (Gast)

>ich habe ein 2-Dimensionaled Feld erstellt, in dem ich den Zustand von
>74 Relais auf 5 Steckkarten festhalten wollte.

Hmm.

>Dabei ist mir der Fehler pssiert, dass ich das Feld für die Kartennummer
>um 1 zu klein gewählt habe.
>(Ich weiss, normalerwise fängt man bei 0 an, und nicht bei 1. Bitte dies
>nicht diskutuieren)

>unsigned char Relais[5][75]; //Karte 1-5   Relais 1-74

Für 74 Relais braucht man bei der Kenntnis von Bitmanipulation 
gerade mal 12 Bytes.

>Seltsamerweise funktioniert das Programm aber trotzdem, wenn ich Schreib
>/ Lesezugriff auf z.B Relais[5][74]  = 1;  mache.
>Ist das jetzt nur Glück, dass meine MCU nicht abstürzt weil der
>beschriebene Speicherbereich zufällig frei war ?

Ja.

von Dirk F (Gast)


Lesenswert?

Hallo Falk,
ja Du hast Recht, aber die Funktion ist jetzt schon für mich so komplex, 
dass ich lieber ein paar Bytes opfere, als den Überblick zu verlieren.
Hier ist der Lesezugriff auf das Array, um 5 x 2 LEDs anzusteuern:
1
    //------------------control----------------------------------------------------
2
void HL_LED_control (void)
3
    {
4
    static bit b_P12,b_P34;
5
    static unsigned char i,Port;
6
    static unsigned char LED_H[6],LED_H_alt[6],LED_L[6],LED_L_alt[6];
7
8
    Port ++;              // Port = 1-5
9
    if (Port==6) Port = 1;
10
11
    b_P34 = 0;
12
    b_P12 = 0;
13
    LED_H[Port]= 0;
14
    LED_L[Port]= 0;
15
16
    for (i=2;i<=64;i=i+2)                           // wenn ein even Relais = 1
17
       if (Relais [Port][i] == 1)  b_P34 = 1 ;      // setze bit
18
19
   for (i=1;i<=64;i=i+2)                            // wenn ein odd Relais  = 1
20
       if (Relais [Port][i] == 1)  b_P12 = 1 ;      //  setze bit
21
22
        LED_H[Port] =  (((bit) b_P34 && ((bit) Relais [Port][68] || (bit) Relais [Port][71]))    ||  ( b_P12 && ((bit)Relais [Port][65] || (bit) Relais [Port][66] )) ) ;  // ein even = 1 und (Relais 68 = 1 oder K71 = 1)
23
        LED_L[Port] =  (((bit) b_P34 && ((bit) Relais [Port][69] || (bit) Relais [Port][70]))    ||  ( b_P12 && ((bit)Relais [Port][67] || (bit) Relais [Port][72] )) ) ;  // ein even = 1 und (Relais 68 = 1 oder K71 = 1)
24
25
    if (LED_H[Port]  != LED_H_alt[Port])                // Hat sich der Zustand geändert ?
26
                writeSlave24 (Port, 1<<6 | Chip[73-1 ]<<3 | (bit)LED_H[Port],  2<<6 | Pin[73-1]-1  );  //  dann High-LED ein/aus schalten
27
28
    if (LED_L[Port]  != LED_L_alt[Port])                // Hat sich der Zustand geändert ?
29
                 writeSlave24 (Port, 1<<6 | Chip[74-1 ]<<3 | (bit)LED_L[Port],  2<<6 | Pin[74-1]-1  );  //  dann Low-LED ein/aus schalten
30
31
        LED_H_alt[Port] = LED_H[Port];                      // Zustand merken
32
        LED_L_alt[Port] = LED_L[Port];
33
    }

Anm. d. Mods: Hab etwas Farbe in den Quellcode gekippt :)

: Bearbeitet durch Moderator
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Dirk F schrieb:
> Ist das jetzt nur Glück, dass meine MCU nicht abstürzt weil der
> beschriebene Speicherbereich zufällig frei war ?

 Natürlich.
 Mach noch ein Array hinterher, z.B. TestArray, mit Nullen auffüllen,
 zugriff auf Relais[5][74]  = 1;
 und sende TestArray zum PC.

 Ich glaube, TestArray[0][73] sollte nun gesetzt sein.

von Falk B. (falk)


Lesenswert?

@ Dirk F (Gast)

>ja Du hast Recht, aber die Funktion ist jetzt schon für mich so komplex,
>dass ich lieber ein paar Bytes opfere, als den Überblick zu verlieren.

FALSCH! Wenn man es richtig macht (tm), wird es eher einfacher als 
schwiegiger.

Jetzt schreibst du

Relais[4][74] = 1;

bzw. du liest

x = Relais[4][74];

Mit zwei Funktionen kann man die Bitmanipulation PROBLEMLOS 
"verstecken"

relais_set(uint8_t board, uint8_t relais, uint8_t value);
uint8_t relais_get(uint8_t board, uint8_t relais);

>Hier ist der Lesezugriff auf das Array, um 5 x 2 LEDs anzusteuern:

Waren es nicht erst Relais?

Ausserdem kann das durch die Zeilenumbrüche keiner lesen. Wenn man 
Quelltext einfügt, dann mit Markierung
1
[c]
2
3
Quelltext hier, wird ohne extra Umbruch angezeigt
4
5
[/c]

von Dirk F (Gast)


Lesenswert?

>>>Waren es nicht erst Relais?

Den Schaltzustand von 74 Relais auf einer Karte auslesen und dann 2 LED 
aus der Verknüpfung ansteuern.
Bei 5 Karten sind das dann 10 LEDs.

Danke für den Tipp mit der Quelltextanzeige.
LG Dirk

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Falk Brunner schrieb:
> Für 74 Relais braucht man bei der Kenntnis von Bitmanipulation
> gerade mal 12 Bytes.

 Bei der Kenntnis von Bitmanipulation braucht man dafür genau 74 bits.

 Aber das Ganze bleibt viel übersichtlicher mit 2-Dimensionalem Array.
1
Oder man schreibt eine Funktion mit 3 Parametern (Karte, Relais, On/Off/Zustand)
2
 und lasst die Funktion die ganze bitschieberei machen.

: Bearbeitet durch User
von Dirk F (Gast)


Lesenswert?

So, da wären wir wieer bei dem alten Thema, warum es in C kein 
Bit-Arrays  gibt....

von Falk B. (falk)


Lesenswert?

@ Dirk F (Gast)

>So, da wären wir wieer bei dem alten Thema, warum es in C kein
>Bit-Arrays  gibt....

Darüber kannst du jetzt lang und breit lammentieren, eine 
Selbsthilfegruppe gründen oder an den Papst schreiben. Oder einfach ein 
bisschen Pragmatismus an den Tag legen, die zwei läppischen Funktionen 
in 10 Minuten runtertippen und glücklich sein. Triff deine Wahl.

von Max D. (max_d)


Lesenswert?

Marc Vesely schrieb:
> Bei der Kenntnis von Bitmanipulation braucht man dafür genau 74 bits

Man macht sich damit aber das Leben u.U. ziemlich schwer.

Wenn man für jede Karte 10 Bytes (= 80Bits) nimmt, dann kann man den 
Index für die Karten normal als Array belassen. Damit reduziert sich die 
Bitschubserei darauf erstmal das richtige Byte zu suchen
1
 
2
ByteAddresse = RelaisNummer/8;

und anchließend das richtige Bit zu maskieren
1
toReturn = Array[Kartennummer][Byte_Adresse] & (1<<(RelaisNummer&0b111));
2
return toReturn;

Hier wird dann eine 0 geliefert wenn das Relais aus ist und etwas >0 
wenn es an ist (kann man über ein simples if verarbeiten).

PS: Wer will kann die Adressberechnung mit in die rechteckigen Klammern 
schreiben und das ganze via Funktionsmakro einbinden.

von Falk B. (falk)


Lesenswert?

@ Marc Vesely (Firma: Vescomp) (logarithmus)

>> Für 74 Relais braucht man bei der Kenntnis von Bitmanipulation
>> gerade mal 12 Bytes.

Ahhh, heute mal wieder in Kopfrechnen schwach. Es sind natürlich 10 
Bytes.

> Bei der Kenntnis von Bitmanipulation braucht man dafür genau 74 bits.

Was leider nicht ganz durch 8 teilbar ist.

> Aber das Ganze bleibt viel übersichtlicher mit 2-Dimensionalem Array.

Das ist doch gar nicht die Frage! Aber ein

char relais[5][10] braucht 50 Bytes
char relais[5][75] braucht 375 Bytes

Jaja, am bestern noch einen ARM dazu nehmen, sicher ist sicher ;-)

von Dirk F (Gast)


Lesenswert?

HI,
da kommt mir noch ein ganz anderer Gedanke:
Wenn auf den 5 Karten immer das gleiche gemacht wird, dann brauch ich 
doch die Logikberechnung nicht 5 mal einzel mit 1 Bit machen, sondern 
Byteweise die Und/Oder Verknüpfungen durchführen,erste Bit für die erste 
Karte, Bit4 für die 5.te Karte, und vom Ergebnisbyte dann die ersten 5 
Bits auswerten.

Dirk

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Dirk F schrieb:
> Wenn auf den 5 Karten immer das gleiche gemacht wird, dann brauch ich
> doch die Logikberechnung nicht 5 mal einzel mit 1 Bit machen, sondern

 Wenn auf den 5 Karten immer das gleiche gemacht wird, dann brauchst du
 keine 5 Karten, denke ich.

von Falk B. (falk)


Lesenswert?

@ Dirk F (Gast)

>Wenn auf den 5 Karten immer das gleiche gemacht wird, dann brauch ich
>doch die Logikberechnung nicht 5 mal einzel mit 1 Bit machen, sondern
>Byteweise die Und/Oder Verknüpfungen durchführen,erste Bit für die erste
>Karte, Bit4 für die 5.te Karte, und vom Ergebnisbyte dann die ersten 5
>Bits auswerten.

Kann sein. Aber ich glaube nicht, dass du hier großartig Reichenleistung 
sparst. So eine Relaissteuerung ist sowieso um Faktor 1000++ langsamer 
als die langsamste CPU.

Kleiner Tip. Schreibe IMMER Klammern für den Körper bei for(), while(), 
if() etc. Sonst kannst du dir mal ganz schnell ins Knie schießen.

Siehe Strukturierte Programmierung auf Mikrocontrollern

von Dirk F (Gast)


Lesenswert?

>>>> Wenn auf den 5 Karten immer das gleiche gemacht wird, dann brauchst du
 keine 5 Karten, denke ich.

Nö.  Die Relais auf den 5 Karten sind unterschieldlich gesetzt.
Die 2 LEDs pro Karte sollen eine bestimmte Information übder den 
Schatzustand anzeigen.

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.