Differenzen auswerten: Geht das eleganter?

Gast #4467425
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);
Gast #4467596
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
}
Gast #4467597
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 :-)
Gast #4467624
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.
Gast #4467642
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren