Forum: Compiler & IDEs Uart Daten-Empfang


von Heiko (Gast)


Lesenswert?

ich bin novh relatine neu in C  daher mal einen Frage.

Ich sende von einem Atmega8 daten zu einem anderen Atmega8 über die 
uart,
die daten kommen auch an, mein Problem ist wie ich die daten 
zusamensetze.
also wie ich den vergleich richtig mache leider funktioniert das nicht 
so.

vielleicht kann mir von ihnen wer weiterhelfen

sensNr = inLx[0]*10 + inLx[1];


  if ( sensNr == 1 )
    {
    }
........

  if ( sensNr == 19 )
    {

    }

1
//SENDER
2
 char     msg[30];  
3
 uint8_t i;
4
 uint8_t sens;
5
6
for (i = 1; i < 19; i++)
7
 {
8
  sens = i;
9
  sprintf(msg,"%02d",sens );  
10
  uart_puts(msg);
11
  uart_putc(60);
12
}
13
14
//EMPFÄNGER   
15
  char inLx[32];
16
  uint8_t sensNr = 0;
17
  uint8_t i;
18
  uint16_t c;//Uart Peter Fleury
19
20
  i = 0;//Uart Peter Fleury
21
  c = uart1_getc(); 
22
23
  if ( c & UART_NO_DATA )
24
   {
25
     //Keine Daten 
26
     //Mach was
27
   }
28
    
29
    else
30
     {
31
      inLx[ i ] = c;
32
      i = 1;
33
     
34
      while( ( c = uart1_getc() ) != 60 && i < sizeof(inLx)  )
35
       {
36
        inLx[ i++ ] = c;
37
       }
38
       inLx[i] = '\0';
39
      }
40
Daten stehen jetz in inLx
41
42
43
sensNr = inLx[0]*10 + inLx[1];      
44
45
46
  if ( sensNr == 1 )
47
    {
48
    }  
49
50
  if ( sensNr == 2 )
51
    {
52
    }  
53
54
55
56
  if ( sensNr == 19 )
57
    {
58
59
    }

von Rolf Magnus (Gast)


Lesenswert?

Heiko schrieb:
> sensNr = inLx[0]*10 + inLx[1];

Versuch's mal mit:
1
sensNr = (inLx[0]-'0')*10 + (inLx[1]-'0');

von Heiko (Gast)


Lesenswert?

Rolf Magnus schrieb:
>
> Versuch's mal mit:
> sensNr = (inLx[0]-'0')*10 + (inLx[1]-'0');
Vielen vielen dank jetz gehts
Danke
mfg

von Heiko (Gast)


Lesenswert?

so ich habe nochmal etwas versucht,Die IF-Abfrage Funktioniert aber mit 
der Ausgabe komme ich nicht weiter.
Es sollte eigendlich -1 bis  -18  Ausgegeben werden ich erhalte aber nur 
0.
vielleicht hat denn von ihnen jemand noch einen tipp .

1
//SENDER
2
 char     msg[30];  
3
 uint8_t i;
4
 uint8_t sens;
5
 int temp;
6
7
for (i = 1; i < 19; i++)
8
 {
9
  sens = i;
10
  sprintf(msg,"%02d",sens );  
11
  uart_puts(msg);
12
  
13
  temp = sens ;
14
  temp *= -1;
15
  sprintf(msg,"+%3d",temp );  
16
  
17
  uart_putc(60);
18
}
19
20
//EMPFÄNGER   
21
  char outpuffer[20];
22
  char inLx[32];
23
  uint8_t sensNr = 0;
24
  uint8_t i;
25
  signed int TWert[19];   
26
27
  uint16_t c;//Uart Peter Fleury
28
29
  i = 0;//Uart Peter Fleury
30
  c = uart1_getc(); 
31
32
  if ( c & UART_NO_DATA )
33
   {
34
     //Keine Daten 
35
     //Mach was
36
   }
37
    
38
    else
39
     {
40
      inLx[ i ] = c;
41
      i = 1;
42
     
43
      while( ( c = uart1_getc() ) != 60 && i < sizeof(inLx)  )
44
       {
45
        inLx[ i++ ] = c;
46
       }
47
       inLx[i] = '\0';
48
      }
49
50
      sensNr = (inLx[0]-'0')*10 + (inLx[1]-'0');
51
52
    int mess = atoi( &inLx[2] );
53
    TWert[sensNr ] = mess;    
54
55
56
  if ( sensNr == 1 )
57
    {
58
     sprintf( outpuffer,"+%3d",TWert[sensNr ]); 
59
     uart_puts( outpuffer); 
60
    }  
61
 
62
...........
63
64
65
66
  if ( sensNr == 19 )
67
    {
68
     sprintf( outpuffer,"+%3d",TWert[sensNr ]); 
69
     uart_puts( outpuffer); 
70
    }

von Karl H. (kbuchegg)


Lesenswert?

Heiko schrieb:


Ich versteh das nicht. Das ist jetzt in 2 Monaten der dritte mit dem 
mehr oder weniger gleichen Problem

>   c = uart1_getc();
>
>   if ( c & UART_NO_DATA )
>    {
>      //Keine Daten
>      //Mach was
>    }
>
>     else
>      {

Soweit so gut. Mindestens 1 Zeichen ist da. 1 Zeichen ist garantiert, 
aber keiner weiß ob es nur 1 Zeichen ist oder mehrere.

>       inLx[ i ] = c;
>       i = 1;
>
>       while( ( c = uart1_getc() ) != 60 && i < sizeof(inLx)  )
>        {
>         inLx[ i++ ] = c;

Nein.
Ob du hier von uart1_getc() tatsächlich 1 Zeichen gekriegt hast oder 
nicht, weißt du nicht. Hier kann uart1_getc() genauso UART_NO_DATA sein! 
Es ist sogar anzunehmen, dass in der Mehrzahl der Fälle ein UART_NO_DATA 
daherkommt, weil die Übertragung per UART für jedes Zeichen wesentlich 
länger dauert, als die Verarbeitung eines Zeichens. Nur weil das 
allererste Zeichen schon eingetroffen ist bedeutet das nicht, das ALLE 
Zeichen schon da sind. Das ist wie 'berittener Bote' für einen Brief, 
wobei jeder Reiter einen Buchstaben transportiert. Die Reiter brauchen 
länger zum reiten als du zum Lesen.


Du musst nach JEDEM Aufruf von uart1_getc() die Frage stellen: Habe ich 
ein Zeichen bekommen oder nicht? Und nicht nur beim ersten Aufruf!

von Heiko (Gast)


Lesenswert?

nein nein
wenn ich mir den inLx ausgeben lasse sind alle zeichen da.
Mir gehts um die verarbeitung
der daten mit,
1
    int mess = atoi( &inLx[2] );
2
    TWert[sensNr ] = mess;

ich bekomme das Vorzeichen nicht angezeigt
1
//SENDER
2
 char     msg[30];  
3
 uint8_t i;
4
 uint8_t sens;
5
 int temp;
6
7
for (i = 1; i < 19; i++)
8
 {
9
  sens = i;
10
  sprintf(msg,"%02d",sens );  
11
  uart_puts(msg);
12
  
13
  temp = sens ;
14
  temp *= -1;
15
  sprintf(msg,"+%3d",temp );  
16
  
17
  uart_putc(60);
18
}

von JJ (Gast)


Lesenswert?

Hallo
Vielleicht solltest du den negativen auch mal ausgeben!?
Gruß
Joachim

von Heiko (Gast)


Lesenswert?

Ist scheinbar beim kopieren hier verloren gegangen
Bei mir im code ist es drin
Mfg

von Programmierer (Gast)


Lesenswert?

Heiko schrieb:
> Ist scheinbar beim kopieren hier verloren gegangen
> Bei mir im code ist es drin

Dann zeig ihn doch mal her, den code. Den ganzen, bitte lesbar 
formatiert, und wenn er mehr als 30 Zeilen umfasst, als Attachment. Und 
bitte erst dann, wenn du das Teil sauber compilieren kannst (keine 
Warnings mehr etc.).

Kurz und Gut -> Netiquette beachten.

von ... (Gast)


Lesenswert?

... und wenn du dein Rechtschreibhilfe zusätzlich aktivierst, würde das 
die Sache noch lesbarer machen.

von Karl H. (kbuchegg)


Lesenswert?

Heiko schrieb:
> nein nein
> wenn ich mir den inLx ausgeben lasse sind alle zeichen da.

Aber nur, wenn du im Empfangscode vorher lange genug gewartet hast, bis 
alles eingetroffen ist.
Korrekt ist dein Code deswegen trotzdem nicht.

> Mir gehts um die verarbeitung
> der daten mit,
>
1
>     int mess = atoi( &inLx[2] );
2
>     TWert[sensNr ] = mess;
3
>
>
> ich bekomme das Vorzeichen nicht angezeigt

Nur mal angenommen, der empfangene String stimmt tatsächlich.
Dann sieht er zb so aus.

"12+-58"

und du setzt atoi hier an


"12+-58"
   ^
   +---- da ist inLx[2]

dh, du möchtest von atoi gerne haben, dass es den String "+-58" 
auswertet. Das es da mit dem - nichts mehr anfangen kann, sollte jetzt 
nicht wirklich verwundern. Was mich eher wundert ist, dass es da nicht 
überhaupt verweigert hat.

Es ist immer eine gute Idee, wenn man Ärger mit einer Konvertierfunktion 
hat, sich den String erst mal ausgeben zu lassen, den man konvertieren 
lässt. Bei dir ist das dann eben entsprechendes:

   uart_putc( '#' );
   uart_puts( inLx );
   uart_putc( '#' );
   uart_puts( &inLx[2] );
   uart_putc( '#' );

   int mess = atoi( &inLx[2] );
   TWert[sensNr ] = mess;

auf die Art kann man dann auch ganz einfach sehen, welchen String man 
exakt an atoi verfüttert.

von Heiko (Gast)


Lesenswert?

Hallo,
Lasse ich mir die Empfangenen Werte ausgeben sind sie Korrekt.
Mit der atoi zb.
    int mess = atoi( &inLx[2] );
    TWert[sensNr ] = mess;
denn in inLx[2] steht ja das vorzeichen drin,aber es kommt nur NULL als 
Ausgabe.
mfg
1
//SENDER
2
 char     msg[30];  
3
 uint8_t i;
4
 uint8_t sens=5;
5
 int temp;
6
7
 for (i = 10; i < 19; i++)
8
 {
9
  sprintf(msg,"%02d",sens );  
10
  uart_puts(msg);
11
12
  temp = i;
13
  temp *= -1;
14
  sprintf(msg,"+%3d",temp );  
15
  uart_puts(msg);  
16
  uart_putc(60);
17
 }
18
19
//EMPFÄNGER   
20
  char outpuffer[20];
21
  char inLx[32];
22
  uint8_t sensNr = 0;
23
  uint8_t i;
24
  signed int TWert[19];   
25
26
  uint16_t c;//Uart Peter Fleury
27
28
  i = 0;//Uart Peter Fleury
29
  c = uart1_getc(); 
30
31
  if ( c & UART_NO_DATA )
32
   {
33
     //Keine Daten 
34
     //Mach was
35
   }
36
    
37
    else
38
     {
39
      inLx[ i ] = c;
40
      i = 1;
41
     
42
        while( ( c = uart1_getc() ) != 60 && i < sizeof(inLx)  )
43
         {
44
          inLx[ i++ ] = c;
45
         }
46
        inLx[i] = '\0';
47
      }
48
49
      sensNr = (inLx[0]-'0')*10 + (inLx[1]-'0');
50
51
//inLx[0] = sensNr Zehner zb.0
52
//inLx[1] = sensNr Einer   zb.5 Währe für sensNr=5 
53
//inLx[2] = Vorzeichen +oder -
54
//inLx[2] = Zehner 
55
//inLx[4] = Einer   
56
 
57
//Werte werden richtig dargestellt
58
  uart_putc(inLx[0] );
59
  uart_putc(inLx[1] );
60
  uart_putc(inLx[2] );
61
  uart_putc(inLx[3] );
62
  uart_putc(inLx[4] );
63
64
65
//so bekomme ich nur Null als Ausgabe
66
    int mess = atoi( &inLx[2] );
67
    TWert[sensNr ] = mess;    
68
69
//so bekomme ich den Korregten wert als Ausgabe aber ohne Vorzeichen
70
  //  int mess = atoi( &inLx[3] );
71
  //  TWert[sensNr ] = mess;    
72
73
74
  if ( sensNr == 1 )
75
    {
76
     sprintf( outpuffer,"+%3d",TWert[sensNr ]); 
77
     uart_puts( outpuffer); 
78
    }  
79
 
80
...........
81
82
83
84
  if ( sensNr == 19 )
85
    {
86
     sprintf( outpuffer,"+%3d",TWert[sensNr ]); 
87
     uart_puts( outpuffer); 
88
    }

von Karl H. (kbuchegg)


Lesenswert?

Heiko schrieb:
> Hallo,
> Lasse ich mir die Empfangenen Werte ausgeben sind sie Korrekt.

Lass sie dir als Strings ausgeben!


Die können nicht korrekt sein. Nicht wenn du am Sender so wegschickst:
1
for (i = 1; i < 19; i++)
2
 {
3
  sens = i;
4
  sprintf(msg,"%02d",sens );  
5
  uart_puts(msg);
6
  
7
  temp = sens ;
8
  temp *= -1;
9
  sprintf(msg,"+%3d",temp );  
10
  
11
  uart_putc(60);
12
}

Denn dein String, den du zu zerlegen versuchst, MUSS damit so

01+-01

aussehen.
Und wenn du atoi auf inLnx[2] ansetzt, dann ist das am '+' Zeichen und 
nicht am '-'!

01+-01
  ^
  |
  |
  | inLnx[2], das ist hier!
    und gleich nach dem '+' kommt ein '-'. Und damit kann das keine
    gültige Zahl mehr sein, die bei inLnx[2] beginnt. Denn keine Zahl
    kann mit 2 hintereinanderstehenden Vorzeichen anfangen!

von Stefan E. (sternst)


Lesenswert?

Offensichtlich braucht er noch einen weiteren Wink (oder wohl eher Hieb) 
mit dem Zaunpfahl:
Das '+' steht auf der falschen Seite vom '%'.

von Heiko (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Das '+' steht auf der falschen Seite vom '%'.
Das war es.
Danke.


 Karl Heinz Buchegger schrieb
> Du musst nach JEDEM Aufruf von uart1_getc() die Frage stellen: Habe ich
> ein Zeichen bekommen oder nicht? Und nicht nur beim ersten Aufruf!
Wie müsste es denn richtig sein?.
Der EMPFÄNGER wird ja von der Mainloop Ständig aufgerufen.
mfg

von Karl H. (kbuchegg)


Lesenswert?

Heiko schrieb:
> Stefan Ernst schrieb:
>> Das '+' steht auf der falschen Seite vom '%'.
> Das war es.
> Danke.
>
>
>  Karl Heinz Buchegger schrieb
>> Du musst nach JEDEM Aufruf von uart1_getc() die Frage stellen: Habe ich
>> ein Zeichen bekommen oder nicht? Und nicht nur beim ersten Aufruf!
> Wie müsste es denn richtig sein?.

Wie schon gesagt:
Nach ausnahmslos JEDEM uart1_getc() muss eine Prüfung erfolgen, ob da 
eventuell UART_NO_DATA geliefert wurde.
Auch hier:
       while( ( c = uart1_getc() ) != 60 && i < sizeof(inLx)  )
         {
          inLx[ i++ ] = c;
         }
Du kannst dich nicht darauf verlassen, dass du hier ein Zeichen 
bekommst.
Das Zeichen von uart1_getc() steht in c. Und damit musst du wieder Tests 
machen, ehe feststeht, dass da ein Zeichen gekommen ist, welches du dann 
auswerten kannst. Die while Schleife wird also anders aussehen müssen.
Sofern man nicht überhaupt die komplette Systematik ändert und nicht 
aktiv auf das Eintreffen eines 60-er Bytes wartet:
Byte holen, sofern eines vorhanden ist
  Ist eines vorhanden:
  War es 60?
    wenn ja, dann kann der String ausgewertet werden
    wenn nein, dann wird das Zeichen an den String angehängt

Somit wartet die Funktion überhaupt nicht mehr, sondern holt sich ein 
Zeichen von der UART (wenn eines da ist) und entscheidet, ob damit der 
String vollständig geworden ist und ob es daher etwas (in Form der 
Auswertung) zu tun gibt oder ob man das Zeichen einfach mal an den 
String anhängt.

von Heiko (Gast)


Lesenswert?

Ich habe mich mal an das Beispiel von Peter Fleury gehalten aber als 
Ausgabe erhalte ich nur Buffer overflow error: .

mfg


1
 i = 0;     
2
 c = uart1_getc();
3
        if ( c & UART_NO_DATA )
4
        {
5
           /* 
6
            * no data available from UART 
7
            */
8
        }
9
        else
10
        {
11
           /*
12
            * new data available from UART
13
            * check for Frame or Overrun error
14
            */
15
            if ( c & UART_FRAME_ERROR )
16
            {
17
              /* Framing Error detected, i.e no stop bit detected */
18
              uart_puts_P("UART Frame Error: ");
19
            }
20
            if ( c & UART_OVERRUN_ERROR )
21
            {
22
             /* 
23
              * Overrun, a character already present in the UART UDR register was 
24
              * not read by the interrupt handler before the next character arrived,
25
              * one or more received characters have been dropped
26
              */
27
              uart_puts_P("UART Overrun Error: ");                
28
            }
29
            if ( c & UART_BUFFER_OVERFLOW )
30
            {
31
              /* 
32
               * We are not reading the receive buffer fast enough,
33
               * one or more received character have been dropped 
34
               */
35
              uart_puts_P("Buffer overflow error: ");                
36
            }
37
            /* 
38
             * send received character back
39
             */
40
        
41
42
            if(c != 60  )     
43
            {
44
             inLx[i] = '\0';
45
             sensNr = (inLx[0]-'0')*10 + (inLx[1]-'0'); 
46
            } 
47
            else
48
            {
49
            inLx[ i++ ] = c;      
50
            }
51
          }
52
    int mess = atoi( &inLx[2] );
53
    TWert[sensNr ] = mess;    
54
55
56
57
58
  if ( sensNr == 1 )
59
    {
60
     sprintf( outpuffer,"+%3d",TWert[sensNr ]); 
61
     uart_puts( outpuffer); 
62
    }  
63
 
64
...........
65
66
67
68
  if ( sensNr == 19 )
69
    {
70
     sprintf( outpuffer,"+%3d",TWert[sensNr ]); 
71
     uart_puts( outpuffer); 
72
    }

von Karl H. (kbuchegg)


Lesenswert?

Tja. das ist halt immer das Problem mit Codeausschnitten. Man sieht so 
schlecht, was noch alles schief gehen kann. Deine Code-Scnippets kann 
ich auch x-verschiedene Arten kombinieren, die alle irgendwann in einem 
Buffer Overflow münden.

von Heiko (Gast)


Lesenswert?

Leider Funktioniert das Beispiel von P.Fleury bei mir nicht,
jedoch aber das Beispiel mit der While-Schleife.
Scheinbar bin ich nicht der einzige der damit seine Probleme hat,mit dem 
Beispiel von P.Fleury
mfg

von Karl H. (kbuchegg)


Lesenswert?

Heiko schrieb:
> Leider Funktioniert das Beispiel von P.Fleury bei mir nicht,
> jedoch aber das Beispiel mit der While-Schleife.

Tja. Wenn man die Fehlerabfrage weglässt, funktioniert alles immer 
wunderbar. Bis man dann halt irgendwann mal drauf kommt, dass Daten 
fehlen.

> Scheinbar bin ich nicht der einzige der damit seine Probleme hat,mit dem
> Beispiel von P.Fleury

Och. Ich bitte dich. Bis jetzt hab ich noch kein 'Problem' mit der 
Fleury Lib gesehen, welches nicht darauf zurückzuführen ist, dass der 
Problemhaber nicht richtig programmieren kann.
Es ist nun mal ein Trugschluss, dass man nur fertige Libs nehmen muss 
und alles wird gut.

von Karl H. (kbuchegg)


Lesenswert?

Auf wie groß hast du eigentlich den Empfangsbuffer eingestellt?


Ist dir klar, dass du hier im Sender
1
for (i = 1; i < 19; i++)
2
 {
3
  sens = i;
4
  sprintf(msg,"%02d",sens );  
5
  uart_puts(msg);
6
  
7
  temp = sens ;
8
  temp *= -1;
9
  sprintf(msg,"+%3d",temp );  
10
  
11
  uart_putc(60);
12
}

eine Menge Daten rauspustest, die auch mal zwischengespeichert werden 
können müssen, wenn der Empfänger zu langsam mit der Abarbeitung ist. Zb 
dadurch, dass er sich da mit atoi's und vor allen Dingen sprintf's 
ausbremst?

von Heiko (Gast)


Lesenswert?

>Auf wie groß hast du eigentlich den Empfangsbuffer eingestellt?
 char inLx[100];


>Fleury Lib gesehen, welches nicht darauf zurückzuführen ist, dass der
>Problemhaber nicht richtig programmieren kann.
Das mag schon stimmen

>Es ist nun mal ein Trugschluss, dass man nur fertige Libs nehmen muss
>und alles wird gut.
Nein,Nein
Leider gibt es kein richtiges Beispiel wie mann es richtig Anwendet

Darum Fragte ich ja wie mann es richtig macht ,
leider klappt das bei mir nicht

von Karl H. (kbuchegg)


Lesenswert?

Heiko schrieb:
>>Auf wie groß hast du eigentlich den Empfangsbuffer eingestellt?
>  char inLx[100];

Nein.
Den von der Fleury UART-Lib.
Schau in die uart.h hinein. Da gibt es eine Einstellug für die 
Buffergröße.


> Darum Fragte ich ja wie mann es richtig macht ,
> leider klappt das bei mir nicht

Dann musst du endlich mal dein Programm zeigen und nicht immer nur 
nichtssagende Ausschnitte. Und dazu sagen, was du eigentlich machen 
willst, bzw. welche Überlegungen du zum Protokoll angestellt hast.

von Karl H. (kbuchegg)


Lesenswert?

Ich nahme mal ein paar Dinge an.

Der Sender fordert mit einem Messagestring die Daten eines Sensors an.
Messagestrings werden grundsätzlich mit einem ';' abgeschlossen.
Dazu schickt er ein '?' gefolgt von der Sensornummer.
Will der eine µC also vom anderen die Daten des Sensors 15 haben, dann 
schickt er den String "?15;". Will er die Daten vom Sensor 9 haben, dann 
schickt er "?9;"

Der andere µC antwortet auf eine Anfrage, indem er einen Messagestring 
zurückschickt, der mit einem '#' beginnt. Eine '#' Message besteht aus 2 
Teilen: die Sensornummer und der Sensorwert. Beide Werte sind mit einem 
',' veinander getrennt. Dieser µC kann also auf die Anforderung "?9;" 
mit "#9,127" antworten, wenn der momentane Sensorwert des Sensors 9 sich 
auf 127 beläuft. Die Sensornummer wird deswegen mit zurück geschickt, 
damit die Gegenstelle immer eindeutig feststellen kann, zu welchem 
Sensor ein bestimmter Wert gehört. Der jeweilige Empfänger bearbeitet 
eine Message so schnell er kann. Es findet kein Handshake statt. Einige 
Messages können zwischengespeichert werden, allerdings darf das auch 
nicht missbraucht werden. Im Idealfall sendet der eine µC die 
Anforderung für einen Sensorwert und wartet bis die Antwort eingetroffen 
ist. Der µC darf auch in einem Rutsch die Sensorwerte für 5 oder 10 
Sensoren abfragen, aus den Anworten kann er immer die eindeutige 
ZUordnung machen, welcher Wert zu welchem Sensor gehört. Mehr aber 
nicht, weil sonst Buffer-Overflows durch das fehlende Handshake drohen.


Der 'Empfänger' verfügt über diesen Code, der in regelmässigen 
Zeitabständen aus der Hauptschleife heraus aufzurufen ist. Dabei gelten 
die üblichen Gepflogenheiten, dass keine _delay_ms oder sonstige 
Verzögerungen erlaubt sind.

Im folgenden sind beide Message-Funktionalitäten in einem Code 
beisammen. Damit kann jeder der beiden µC beim jeweils anderen einen 
Wert anfordern und mit der Antwort etwas anfangen.

1
...
2
char Message[20];
3
uint8_t nextMsgChar;
4
5
//
6
// Bearbeitet ein Zeichen von der UART, wenn eines vorhanden ist
7
// Messages werden ausgewertet und gegebenenfalls eine Antwort
8
// generiert.
9
//
10
// Kommandos
11
//   '?'<nr_s>';'           Abfrage des Sensors <nr_s>
12
//   '#'<nr_s>','<nr_w>     Setzen des Sensorwertes <nr_s> auf den Wert <nr_w>
13
//
14
// Return:
15
//     0    kein Fehler
16
//   251    UART Frame Error
17
//   252    UART Overflow Error
18
//   253    UART Buffer Overfloe Error
19
//   254    illegal Command received
20
//
21
uint8_t processMessages()
22
{
23
  char c = uart1_getc();
24
25
  if ( c & UART_NO_DATA )
26
    return 0;
27
28
  if ( c & UART_FRAME_ERROR )
29
    return 251;
30
31
  if ( c & UART_OVERRUN_ERROR )
32
    return 252;
33
34
  if ( c & UART_BUFFER_OVERFLOW )
35
    return 253;
36
37
  /*
38
  ** Zeichen eingetroffen und kein Fehler
39
  */
40
41
  // Message fertig?
42
  if( c != ';' ) {
43
    Message[nextMsgChar++] = c;
44
    return 0;
45
  }
46
47
  // eine Message ist fertig empfangen worden
48
  // die jetzt auswerten
49
  Message[nextMsgChar] = '\0';  // sicherheitshalber
50
  nextMsgChar = 0;
51
52
  // Sensorabfrage
53
  // Syntax:  '?' sensorNr ';'
54
  // Aktion:  keine
55
  // Antwort: '#' sensorNr ',' SensorWert ';'
56
  // Spezial: Im Fehlerfall (ungültige Sensor Nummer) wird keine
57
  //          Antwort gesendet
58
  //
59
  if( Message[0] == '?' ) {
60
    uint8_t sensorNr = atoi( &Message[1] );
61
    if( sensorNr < sizeof( TWert ) / sizeof( *TWert ) ) {
62
      char Answer[10];
63
      uart_putc( '#' );
64
      uart_puts( itoa( (int)sensorNr, Answer, 10 ) );
65
      uart_putc( ',' );
66
      uart_puts( itoa( (int)TWert[sensorNr], Answer, 10 ) );
67
      uart_putc( ';' );
68
    }
69
  }
70
71
  // von der Gegenstelle ist ein Sensorwert gekommen
72
  // Syntax:  '#' sensorNr ',' sensorWert ';'
73
  // Aktion:  Sensorwert extrahieren und merken.
74
  // Antwort: keine
75
  // Spezial: Im Fehlerfall (ungültige Sensor Nummer) wird keine
76
  //          Aktion unternommen und auch nichts gesendet.
77
  //
78
  else if( Message[0] == '#' ) {
79
    uint8_t  sensorNr = 0;
80
    uint16_t newValue = 0;
81
    char*    nextChar = &Message[1];
82
83
    sensorNr = atoi( nextChar );
84
    // nach dem ',' suchen
85
    while( *nextChar != ',' )
86
      nextChar++;
87
88
    if( *nextChar == ',' ) {
89
      nextChar++;
90
      newValue = atoi( nextChar );
91
92
      if( sensorNr < sizeof( TWert ) / sizeof( *TWert ) )
93
        TWert[sensorNr] = newValue;
94
    }
95
  }
96
  else
97
    return 254;
98
99
  return 0;
100
}
101
102
103
int main()
104
{
105
  ....
106
107
  while( 1 ) {
108
    error = processMessages();
109
110
    if( error != 0 )
111
      mach was um dem Benutzer einen Fehler zu melden
112
      zb Fehler LED einschalten oder dergleichen
113
114
    ... andere Dinge, wie zb Sensoren abfragen und in TWert eintragen.
115
  }


Warnung: ungetesteter Code

von Heiko (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

In der Mainloop wird immer das getSensor(second) aufgerufen,(Im Timer 
läuft eine Uhr mit). Bei jeder neuen Sekunde wird ein Messbefehl 
gesendet zum Temperratur-Modul welches die Messung startet.

Anbei mal das Komplette Projekt vom sender
und vom Daten-Empfang.
Ich habe versucht Peters Beispiel umzusetzen aber da bekomme ich nur ein 
Wert angezeigt.
1
int main()
2
{
3
  ....
4
5
  while( 1 ) {
6
        getSensor(second);
7
8
  }
9
}
10
11
12
13
signed int TempgWert[19];          //Grenzwerte für DS18S20
14
 int activeTempgWert=1;
15
signed int TempWert[19];           //Temperraturwerte  
16
//###################################################################################
17
//Temperatur  Einlesen
18
void getSensor(uint8_t ss, )
19
//###################################################################################
20
{
21
  char inLx[32];
22
  uint8_t sensorNr = 0;
23
  uint8_t nachkomma= 0;
24
25
  uint8_t i;
26
  uint16_t c;//Uart Peter Fleury
27
28
    
29
 //Wenn eine neue Sekunde da ist Messbefehl zum Messmodul senden     
30
  if (ss == 1)
31
    {
32
     tempsend(0xB5,60);
33
    }
34
         
35
36
 
37
                   
38
//So bekomme ich alle Daten
39
40
//#########################################################################
41
42
  i = 0;
43
  c = uart1_getc(); 
44
45
    if ( c & UART_NO_DATA )
46
     {
47
      //Keine Daten 
48
      //Mach was
49
50
     }
51
    
52
    else
53
     {
54
   
55
     inLx[ i ] = c;
56
     i = 1;
57
     
58
        while( ( c = uart1_getc() ) != 60 && i < sizeof(inLx)  )
59
        {
60
         inLx[ i++ ] = c;
61
        }
62
        inLx[i] = '\0';
63
        
64
65
66
        if( i >= 7 )     // genug Bytes bekommen?
67
         {
68
          sensorNr = (inLx[0]-'0')*10 + (inLx[1]-'0'); 
69
         } 
70
       else
71
         {
72
          sensorNr = 255;  
73
         }
74
       }
75
76
77
78
  
79
  
80
81
82
83
84
    // wenn es sich um eine gültige Sensor Nummer handelt
85
    // dann wandle den Rest des Strings in eine Zahl um
86
    // und speichere sie im Temperatur Array zum korrekten Sensor
87
    if( sensorNr != 255 ) {
88
    // ersten 2 stellen vorm komma mit Vorzeichen Speichern
89
    int messWert = atoi( &inLx[2] );
90
    TempWert[sensorNr] = messWert;    
91
    int n= atoi( &inLx[6]);
92
    nachkomma = n;
93
  }    
94
   
95
96
97
98
99
100
101
  
102
  
103
//#########################################################################
104
 
105
  //ausgabe aller sensoren
106
107
108
  if ( sensorNr == 1 )
109
    {
110
     outtValut( 175, 98, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
111
  }  
112
113
  if ( sensorNr == 2 )
114
    {
115
     outtValut( 175, 119, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
116
    }  
117
118
  if ( sensorNr == 3 )
119
    {
120
     outtValut( 175, 140, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma); 
121
    }  
122
123
  if ( sensorNr == 4 )
124
    {
125
     outtValut( 175, 161, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
126
    }  
127
128
  if ( sensorNr == 5 )
129
    {
130
     outtValut( 175, 182, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
131
    }  
132
133
  if ( sensorNr == 6 )
134
    {
135
     outtValut( 175, 205, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
136
    }    
137
//#########################################################################
138
  if ( sensorNr == 7 )
139
    {
140
     outtValut( 423, 98, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
141
    }    
142
    
143
  if ( sensorNr == 8 )
144
    {
145
     outtValut( 423, 119, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
146
    }    
147
    
148
  if ( sensorNr == 9 )
149
    {
150
     outtValut( 423, 140, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
151
    }    
152
  
153
  if ( sensorNr == 10 )
154
    {
155
     outtValut( 423, 161, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
156
    }    
157
158
  if ( sensorNr == 11 )
159
    {
160
     outtValut( 423, 182, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
161
    }    
162
 
163
  if ( sensorNr == 12 )
164
    {
165
     outtValut( 423, 205, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
166
    }      
167
//#########################################################################
168
  if ( sensorNr == 13 )
169
    {
170
     outtValut( 579, 98, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
171
    }    
172
    
173
  if ( sensorNr == 14 )
174
    {
175
     outtValut( 579, 119, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
176
    }    
177
    
178
  if ( sensorNr == 15 )
179
    {
180
     outtValut( 579, 140, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
181
    }    
182
  
183
  if ( sensorNr == 16 )
184
    {
185
     outtValut( 579, 161, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
186
    }    
187
188
  if ( sensorNr == 17 )
189
    {
190
     outtValut( 579, 182, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
191
    }    
192
 
193
  if ( sensorNr == 18 )
194
    {
195
     outtValut( 579, 205, sensorNr,"%+3d,%1d", TempWert[sensorNr], nachkomma);
196
    }      
197
 
198
MinMaxSensor(sensorNr );
199
200
}
201
202
203
//###################################################################################
204
void MinMaxSensor(uint8_t senNr )
205
//###################################################################################
206
{
207
208
  //Vergleich aller sensoren
209
210
 
211
212
  if ( senNr == 1 )
213
    {
214
     if( TempWert[senNr]> TempgWert[senNr] ) {
215
       outpic(up1616,39,98,0,2,14,0 );
216
    }
217
    
218
     else if( TempWert[senNr] < TempgWert[senNr] ) {
219
       outpic(down1616,39,98,0,2,14,0 );
220
    }    
221
222
     else {
223
       outpic(ok1616,39,98,0,2,14,0 );
224
    }  
225
  }  
226
227
228
  if ( senNr == 2 )
229
    {
230
     if( TempWert[senNr] > TempgWert[senNr] ) {
231
       outpic(up1616,39,119,0,2,14,0 );
232
    }
233
    
234
     else if( TempWert[senNr] < TempgWert[senNr] ) {
235
       outpic(down1616,39,119,0,2,14,0 );
236
    }    
237
238
     else {
239
       outpic(ok1616,39,119,0,2,14,0 );
240
    }  
241
  }  
242
}  
243
244
245
246
//###################################################################################
247
//Temperatur-Ausgabe
248
void outtValut(int x,int y,uint8_t sens ,char *name, signed int valu,uint8_t nachkomma )
249
//###################################################################################
250
{
251
  char Buffert[20];
252
253
  gotoxy( x,y );
254
  sprintf( Buffert,"%2d  ", sens );
255
  uart_putc( ' ' );
256
  uart_puts( Buffert );
257
  sprintf( Buffert,name , valu, nachkomma  ); 
258
  uart_puts( Buffert );
259
260
261
}
262
263
//###################################################################################
264
// Zum Tempmodul Comando und Adresse Schicken
265
void tempsend(uint8_t data,uint8_t adress)
266
{
267
   
268
  setTransmitMode();
269
  uart1_putc(data);      // Startkommando: Messen
270
  uart1_putc(adress);        // Adresse schicken
271
  setReceiveMode();
272
 
273
}

von Kupferwurm (Gast)


Lesenswert?

>void getSensor(uint8_t ss, )
Gibt dir der Compiler dafür keine Warnung? Mach mal das Komma weg, die 
Routine erwartet noch einen zweiten Parameter, ann sein daß da komische 
Sachen passieren.

Und: Biste auch sicher daß deine Timer im Hintergrund kommt? Häng mal 
als Herzschlagüberwachung ne LED in die ISR mit rein die alle Sekunde 
oder so ein/ausgeschaltet wird, zB in der Form (LED hängt an PortC5, 
diesen vorher noch auf Ausgang setzen) PORTC ^= (1 << PC5);

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.