Forum: PC-Programmierung [C] Bitwert in einer Zustandsmaschine abfragen und setzen/löschen


von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

habe folgendes Problem:

Programmiere grad an einem Projekt mit einem Tinkerforge µC. Ich habe 
eine Zustandsmaschine programmiert. Diese bekommt von einer Funktion 
einen Wert "*bit" mit 1 oder 0.
Nun möchte ich mit dem Wert *bit verschiedene Bedingungen durchlaufen. 
Je nach dem ob er 1 oder 0 ist. Funktioniert auch soweit nur ein Problem 
taucht auf was ich bis jetzt nicht lösen konnte:

In einer If-Schleife soll der Wert 8 mal (für 1 Byte) aufgerufen werden 
und je nach dem ob 1 oder 0 ist mit 1 oder 0 ausgegeben und 
abgespeichert werden.
Meine bisherige Lösung fragt ja nur einen Wert der am Anfang kommt ab. 
Dieses Problem war mir am Anfang gar nicht aufgefallen...

Kurze Beschreibung warum das ganze:
Ich habe 2 Tinkerforge µC. An dem ersten ist eine LED an dem 2. ein 
Helligkeitssensor. Ich möchte mit der LED Bits übertragen. LED an -> 1, 
aus -> 0
Es soll ein Byte übertragen werden. Am Anfang Startkennung mit 11 und 
dann immer Doppelkodierung mit einer 0 vorweg.

Das Problem tritt in der CASE LESE_BIT: aus

Hier der zusammengefasste Code:

1
int leseBit(int *bit){
2
    
3
    int helligkeit; 
4
    
5
    uint16_t illuminance; //lies illuminace(&_______, &helligkeit)
6
    ambient_light_get_illuminance(&al, &illuminance);
7
    
8
    helligkeit = (illuminance/10);
9
    
10
    if(helligkeit<SCHWELLWERT)
11
        *bit =0;
12
    else
13
        *bit=1;
14
}
15
16
void state_machine(){
17
18
    int j=0;
19
    int bit;
20
    
21
    usleep(500000);
22
    
23
    while(1){
24
    
25
    leseBit(&bit);       
26
    
27
    switch (zustand){
28
      
29
    case UNDEF:       
30
        sleep(1);      
31
        if(bit){
32
            printf("1 -> geht zu WARTE: ");
33
            zustand = WARTE;                    
34
        }
35
        else{
36
            printf("0 -> bleibe in UNDEF: ");
37
            zustand = UNDEF;
38
        }
39
        break;  
40
             
41
    case WARTE: 
42
        sleep(1);
43
        if(bit){
44
            printf("1 -> gehe zu VOR_BIT: ");
45
            zustand = VOR_BIT;                  
46
        }
47
        else{
48
            printf("0 -> bleibe oder gehe in UNDEF: ");
49
            zustand = UNDEF;
50
        }
51
        break; 
52
            
53
    case VOR_BIT:
54
        sleep(1); 
55
        if(bit){
56
            printf("1 -> bleibe oder gehe in UNDEF: ");
57
            zustand = UNDEF;
58
        }
59
        else {
60
            printf("0 -> gehe zu LESE_BIT: ");
61
            zustand = LESE_BIT;                 
62
        }
63
        break;
64
                
65
    case LESE_BIT:
66
   
67
        for (i=0; i<8; i++) {
68
            
69
            if (bit){//((bit<<i)&0x80) {
70
                sleep(1);
71
                //bit |= (1<<i);
72
                printf("1\n");//printf("%d a\n",i);//printf("01");
73
                //sleep(1);
74
            }            
75
            else {
76
                sleep(1);
77
                //bit &= ~(1<<i);  
78
                printf("0\n");//printf("%d b\n",i);//printf("00");
79
                //sleep(1);
80
            }            
81
        }
82
        
83
        printf("Byte gesendet -> gehe zu UNDEF: ");
84
        zustand = UNDEF;
85
86
    }
87
 
88
    uint16_t illuminance;
89
    
90
    if(ambient_light_get_illuminance(&al, &illuminance) < 0) {
91
    fprintf(stderr, "Could not get value, probably timeout\n");
92
    exit(1); 
93
    }
94
    
95
    printf("Illuminance: %f Lux\n", illuminance/10.0);
96
    
97
    }
98
    
99
}

von Karl H. (kbuchegg)


Lesenswert?

Du kannst hier keine for-Schleife machen
1
    case LESE_BIT:
2
   
3
        for (i=0; i<8; i++) {
4
            
5
            if (bit){//((bit<<i)&0x80) {
6
                sleep(1);
7
                //bit |= (1<<i);
8
                printf("1\n");//printf("%d a\n",i);//printf("01");
9
                //sleep(1);
10
            }            
11
            else {
12
                sleep(1);
13
                //bit &= ~(1<<i);  
14
                printf("0\n");//printf("%d b\n",i);//printf("00");
15
                //sleep(1);
16
            }            
17
        }

denn du würdest ja 8-mal dasselbe Bit behandeln.

Aber:
Du kannst natürlich mitzählen! Im zu LESE_BIT vorgelagerten Zustand 
setzt du dir einen Zähler auf 0 und jedesmal, wenn du in LESE_BIT kommst 
(weil dein Timing ja mit sleep gesteuert ist) erhöhst du diesen Zähler. 
Ist er bei 8 angelangt, dann hast du alle 8 Bit gelesen.

Also so ungefähr
1
    case VOR_BIT:
2
        sleep(1); 
3
        if(bit){
4
            printf("1 -> bleibe oder gehe in UNDEF: ");
5
            zustand = UNDEF;
6
        }
7
        else {
8
            printf("0 -> gehe zu LESE_BIT: ");
9
            zustand = LESE_BIT;
10
            bitZaehler = 0;                 
11
        }
12
        break;
13
                
14
    case LESE_BIT:
15
      if(bitZaehler == 8) {
16
        printf("alle 8 Bit eines Bytes empfangen -> gehe zu UNDEF: ");
17
        zustand = UNDEF;    
18
      }
19
      else {
20
        bitZaehler++;
21
22
        if (bit){
23
            ....


Im übrigen kommen mir in deinem Code etwas zuviele sleep vor. Wenn das 
mal gut geht. Die ganze Zustandsmaschine sieht so gesehen nicht richtig 
aus, weil du dich nie auf irgendeine Flanke synchronisierst, an der du 
dann deine tatsächlichen Zeiten loslaufen lassen könntest. Auch denke 
ich, dass ein nicht ganz unwesentlicher Anteil an der Funktionsfähigkeit 
deiner Zustandsmaschine darin besteht, dass auch ein printf Zeit 
benötigt. So gesehen, beeinflusst dein Messmittel das zu untersuchende 
System. Aber das wirst du dann schon noch sehen, wenn die mal alle weg 
sind.

von Alex (Gast)


Lesenswert?

Ok, danke!

Die printf's sind nur zum ersten nachvollziehen. Die verschwinden dann 
alle. Genauso die Sleep's. ist nur für den Anfang zum nachvollziehen. 
Ansonsten funktioniert es jetzt. DANKE!

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.