Forum: PC-Programmierung Differenzen auswerten: Geht das eleganter?


von Christian J. (Gast)


Lesenswert?

Hallo,

gibt es, obwohl das durchaus ein effizienter Code ist eine Möglichkeit 
sowas eleganter zu schreiben? Es handelt sich nur um 12 LED, die 
Temperaturen darstellen sollen, auch Zwischenwerte sollen dargestellt 
werden durch 2 LED. Die Led Setzfunktion lässt derzeit nur einen 
Parameter zu + ON, OFF oder BLINK.
Dazu setze ich einfach in einem Array die LED und ein Interrupt wertet 
diesen dann aus und betätigt das Schieberegister.
1
/ Bitmasken für die Aussentemperatur LES
2
3
#define HC595_LED_M10       0
4
#define HC595_LED_M5        1
5
#define HC595_LED_0         2
6
#define HC595_LED_5         3
7
#define HC595_LED_10        4
8
#define HC595_LED_15        5
9
#define HC595_LED_17        6
10
#define HC595_LED_20        7
11
#define HC595_LED_22        8
12
#define HC595_LED_25        9
13
#define HC595_LED_30        10
14
#define HC595_LED_35        11
15
16
/* Zustand der Aussen-Temperatur LED am 74HCT595 Nr.2 */
17
led_status_t atemp_led[12] = {OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF};



1
  if (W->Ext_Temperature < -10.5)
2
         HC595_SetATempLed(HC595_LED_M10,BLINK);
3
    else if ((W->Ext_Temperature > -10.5) && (W->Ext_Temperature < -9.5))  {
4
         HC595_SetATempLed(HC595_LED_M10,ON);
5
    } else if ((W->Ext_Temperature > -9.5) && (W->Ext_Temperature < -5.5)) {
6
        HC595_SetATempLed(HC595_LED_M10,ON);
7
        HC595_SetATempLed(HC595_LED_M5,ON);
8
    } else if ((W->Ext_Temperature > -5.5) && (W->Ext_Temperature < -4.5)) {
9
        HC595_SetATempLed(HC595_LED_M5,ON);
10
    } else if ((W->Ext_Temperature > -4.5) && (W->Ext_Temperature < -0.5)) {
11
        HC595_SetATempLed(HC595_LED_M5,ON);
12
        HC595_SetATempLed(HC595_LED_0,ON);
13
    } else if ((W->Ext_Temperature > -0.5) && (W->Ext_Temperature < 0.5)) {
14
        HC595_SetATempLed(HC595_LED_0,ON);
15
    } else if ((W->Ext_Temperature > 0.5) && (W->Ext_Temperature < 4.5)) {
16
        HC595_SetATempLed(HC595_LED_0,ON);
17
        HC595_SetATempLed(HC595_LED_5,ON);
18
    } else if ((W->Ext_Temperature > 4.5) && (W->Ext_Temperature < 5.5)) {
19
        HC595_SetATempLed(HC595_LED_5,ON);
20
    } else if ((W->Ext_Temperature > 5.5) && (W->Ext_Temperature < 9.5)) {
21
        HC595_SetATempLed(HC595_LED_5,ON);
22
        HC595_SetATempLed(HC595_LED_10,ON);
23
    } else if ((W->Ext_Temperature > 9.5) && (W->Ext_Temperature < 10.5)) {
24
        HC595_SetATempLed(HC595_LED_10,ON);
25
    } else if ((W->Ext_Temperature > 10.5) && (W->Ext_Temperature < 14.5)) {
26
        HC595_SetATempLed(HC595_LED_10,ON);
27
        HC595_SetATempLed(HC595_LED_15,ON);
28
    } else if ((W->Ext_Temperature > 14.5) && (W->Ext_Temperature < 15.5)) {
29
        HC595_SetATempLed(HC595_LED_15,ON);
30
    } else if ((W->Ext_Temperature > 15.5) && (W->Ext_Temperature < 16.5)) {
31
        HC595_SetATempLed(HC595_LED_15,ON);
32
        HC595_SetATempLed(HC595_LED_17,ON);
33
    } else if ((W->Ext_Temperature > 16.5) && (W->Ext_Temperature < 17.5)) {
34
        HC595_SetATempLed(HC595_LED_17,ON);
35
    } else if ((W->Ext_Temperature > 17.5) && (W->Ext_Temperature < 19.5)) {
36
        HC595_SetATempLed(HC595_LED_17,ON);
37
        HC595_SetATempLed(HC595_LED_20,ON);
38
    } else if ((W->Ext_Temperature > 19.5) && (W->Ext_Temperature < 20.5)) {
39
        HC595_SetATempLed(HC595_LED_20,ON);
40
    } else if ((W->Ext_Temperature > 20.5) && (W->Ext_Temperature < 21.5)) {
41
        HC595_SetATempLed(HC595_LED_20,ON);
42
        HC595_SetATempLed(HC595_LED_22,ON);
43
    } else if ((W->Ext_Temperature > 21.5) && (W->Ext_Temperature < 22.5)) {
44
        HC595_SetATempLed(HC595_LED_22,ON);
45
    } else if ((W->Ext_Temperature > 22.5) && (W->Ext_Temperature < 24.5)) {
46
        HC595_SetATempLed(HC595_LED_22,ON);
47
        HC595_SetATempLed(HC595_LED_25,ON);
48
    } else if ((W->Ext_Temperature > 24.5) && (W->Ext_Temperature < 25.5)) {
49
        HC595_SetATempLed(HC595_LED_25,ON);
50
    } else if ((W->Ext_Temperature > 25.5) && (W->Ext_Temperature < 29.5)) {
51
        HC595_SetATempLed(HC595_LED_25,ON);
52
        HC595_SetATempLed(HC595_LED_30,ON);
53
    } else if ((W->Ext_Temperature > 29.5) && (W->Ext_Temperature < 30.5)) {
54
        HC595_SetATempLed(HC595_LED_30,ON);
55
    } else if ((W->Ext_Temperature > 30.5) && (W->Ext_Temperature < 34.5)) {
56
        HC595_SetATempLed(HC595_LED_30,ON);
57
        HC595_SetATempLed(HC595_LED_35,ON);
58
    } else if ((W->Ext_Temperature > 34.5) && (W->Ext_Temperature < 35.5)) {
59
        HC595_SetATempLed(HC595_LED_35,ON);
60
    } else if (W->Ext_Temperature > 35.5)
61
        HC595_SetATempLed(HC595_LED_35,BLINK);

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Es genügt doch, die "Sprung"temperaturen zu speichern, die dann in einer 
Schleife abgefragt werden.

Wenn die Temperatur z.B: < -5.5 ist, werden 3 LEDs gesetzt: Die 1. im 1. 
Schleifendurchlauf, die 2. in 2. Durchlauf und die 3. im 3.  Danach wird 
die Schleife beendet weil die Temperatur zu klein ist für die 4. LED und 
alle folgenden.

von Tom (Gast)


Lesenswert?

Christian J. schrieb:
> if (W->Ext_Temperature < -10.5)
>          HC595_SetATempLed(HC595_LED_M10,BLINK);
>     else if ((W->Ext_Temperature > -10.5) && (W->Ext_Temperature <
> -9.5))  {
>          HC595_SetATempLed(HC595_LED_M10,ON);
>     } else if ((W->Ext_Temperature > -9.5) && (W->Ext_Temperature <
> -5.5)) {

Willst Du den Fall W->Ext_Temperature == -10.5 explizit nicht behandeln?
Andernfalls wäre der Vergleich nämlich doppelt.
1
if (a <= -10)
2
   blubb1;
3
else if ( (a > -10) && (a < -5) )
4
   blubb2;

Das (a >-10) steckt schon im Wort else mit drin: Wäre a nicht > -10, 
wäre die erste Abfrage a<=-10 schon wahr gewesen und die zweite würde 
nie ausgeführt.


Ansonsten fände ich eine Lookuptable für die Grenzen der 
Temperaturbereiche und eine für die aus den Stufen resultierenden 
LED-Zustände etwas kompakter. Eleganz und Effizienz 
(Platz/Geschwindigkeit/gute Wartbarkeit?) ist natürlich wie immer 
Ansichtssache.
1
#include <stdio.h>
2
3
/* Temperatur wird in Stufen eingeteilt:
4
... -2        -> 0
5
-2 .. -1      -> 1
6
-1 .. -0. 5   -> 2
7
......
8
3.0 ...       -> 6
9
*/
10
const float temperature_range_limits[] = {-2,-1,-0.5, 0, 2.5, 3.0};
11
const size_t num_temperature_ranges = sizeof(temperature_range_limits) / sizeof(temperature_range_limits[0]);
12
const unsigned char leds[] = {0,1,2,3,4,5,6}; // irgendwelche Bitmuster.
13
14
size_t get_temperature_range(float t)
15
{
16
    for (size_t i = 0; i < num_temperature_ranges; ++i)
17
        if (t <= temperature_range_limits[i])
18
            return i;
19
    return num_temperature_ranges;
20
}
21
22
unsigned get_led_state(size_t temperature_range)
23
{
24
    // TODO: bereichsueberpreufung!
25
    return leds[temperature_range];
26
}
27
28
int main(void)
29
{
30
    for (float t = -2.5; t < 4.0; t += 0.234567)
31
    {
32
        size_t range = get_temperature_range(t);
33
        unsigned char leds = get_led_state(range);
34
        printf("%f\t%d\n", t, leds);
35
    }
36
    return 0;
37
}

von Christian J. (Gast)


Lesenswert?

Hm... mir schwebt grad sowas vor... ist aber noch nicht zu Ende 
gedacht...
1
const float atemp[12] = {-10.0, -5.0, 0.0, 5.0, 10.0, 15.0, 17.0, 20.0, 22.0, 25.0, 30.0, 35.0};
2
3
    for (uint8_t i = 0; i < 12; i++)
4
    {
5
        if ( (W->Ext_Temperature > (atemp[i] - 0.5)) && (W->Ext_Temperature < (atemp[i] + 0.5)))
6
            HC595_SetATempLed(i,BLINK);
7
8
        if ( (W->Ext_Temperature > (atemp[i] + 0.5)) && (W->Ext_Temperature < (atemp[i+1] - 0.5))) {
9
            HC595_SetATempLed(i,ON);
10
            HC595_SetATempLed(i+1,ON);
11
        }
12
13
    }

PS: Läuft! Thread kann gelöscht werden :-)

von Sebastian S. (amateur)


Lesenswert?

>PS: Läuft! Thread kann gelöscht werden :-)

Lang lebe der Egoismus ;-)

von Christian J. (Gast)


Lesenswert?

Tom schrieb:
> Willst Du den Fall W->Ext_Temperature == -10.5 explizit nicht behandeln?

Float Werte kann man nicht auf Gleichheit prüfen. Trotzdem Danke, dass 
Du Dir soviel Mühe gemacht hast! Mein Vorteil war, dass alle Temps 0.5 
um ihr Zentrum liegen und alle Zwischenräume eben dazwischen. Dadurch 
war das mit der Schleife oben einfach lösbar.

const size_t num_temperature_ranges = sizeof(temperature_range_limits) / 
sizeof(temperature_range_limits[0]);

Auch noch nicht gesehen .... ich habe einfach 12 reingeschrieben.

von Tom (Gast)


Lesenswert?

Das heißt aber nicht, dass zwei float-Werte nie gleich sein können.

von Christian J. (Gast)


Lesenswert?

Tom schrieb:
> Das heißt aber nicht, dass zwei float-Werte nie gleich sein können.

Habe ich aber so gelernt, dass man die nicht mit == vergleichen kann.

Das KOnstrukt von Tom habe ich grad eingebaut, man lernt nie aus :-)

von Möwe (Gast)


Lesenswert?

Christian J. schrieb:
>> Willst Du den Fall W->Ext_Temperature == -10.5 explizit nicht behandeln?
>
> Float Werte kann man nicht auf Gleichheit prüfen. Trotzdem Danke

Ich gehe davon aus das Tom ein ">=" oder "<=" meint. Prinzipiell ist es 
natürlich möglich dass zwei float/double-Werte einander gleich sind. In 
einem solchen, zugegebenermaßen eher seltenen, Fall würde das Programm 
direkt an deinem ganzen Konstrukt vorbeispringen. Deshalb fragt man in 
der Regel eine von zwei angrenzenden Bedingung abgeschlossen ab.

Grüße

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.