USART Fleruy lib auf ATMEGA88 - Problem bei hohen Datenraten

#2915865
Lesenswert?

Hallo zusammen,

ich habe die USART lib von Fleury auf einem ATMEGA88 mit 16MHz Quarz 
laufen. Der befeuert einen RS485 Transceiver (LT1785). Die Busleitungen 
sind mit einem VC 0805-14 Varistor geschützt.

Über einen USB - RS485 Converter (Digitus DA70157) gehe ich dann in den 
PC aufs Hyperterminal.

Das Ganze lief auf Anhieb, allerdings nur bis 115200 Bit/s. Bei höheren 
Datenraten gibts Datensalat.

Und ab da stehe ich auf dem Schlauch.
Ich muss für ein Projekt 1MBbit/s in den Controller einlesen, wollte das 
zumindest mal bis 921600Bit/s auf dem Rechner testen.

Meine Oszi Ausstattung lässt leider keine weitere Analyse zu. Wo könnte 
das Problem liegen?
- Kapazität auf der Leitung sollte Ok sein.
- Oh, ich seh grade, Terminierung könnte das Problem sein. Ich hab 
derzeit nichts dran, Leitung ist aber auch nur 20cm lang.
- sind irgendwelche Fallstricke in der lib vorhanden, die ich übersehen 
habe?
- andere Ideen?

Viele Grüße + herzlichen Dank für Eure Hilfe!
Volker
#2915880
Lesenswert?

Hi

die Probleme duerften an der Geschwindigkeit bzw. dem Quartz liegen.
Schau Dir mal den Artikel 
[[http://www.mikrocontroller.net/articles/Baudratenquarz]] an.

Diesen Code kannst Du verwenden um zu checken ob der gewaehlte Quartz 
auch passt. Er stammt aus dem sehr guten Tutorial auf 
mikrocontroller.net:
[[http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART]]

1
#define F_CPU  7372800UL
2
// Berechnungen
3
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
4
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
5
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
6
 
7
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
8
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
9
#endif

Gruesse
Tosa
#2935803
Lesenswert?

Hallo Tosa,

herzlichen Dank für den Tip, das war es natürlich.

Jetzt habe ich leider ein neues Problem, vermutlich ähnlich trivial?!

Ich kann nun einen String, Char, alles was das Fleury Beispielprogramm 
hergibt, ausgeben.
Aber wenn ich einen Char einlese und dieses als Echo wieder ausgebe, 
kommt nur Murks im Terminal an.
Das Programm habe ich denke ich verstanden, unsigned int wird auf 
unsigned char gecastet, damit die Diagnosebits abgeschnitten werden und 
dann wird das Byte zurückgeschrieben.

Irgendwo beim einlesen muss ein Fehler drin sein, denn
1
uart_putc('x');
funktioniert ja.

Hat jemand eine Idee, wie da heranzugehen ist?

Grüße,
Volker
#2935812
Lesenswert?

Vo M. schrieb:

> Aber wenn ich einen Char einlese und dieses als Echo wieder ausgebe,
> kommt nur Murks im Terminal an.
> Das Programm habe ich denke ich verstanden, unsigned int wird auf
> unsigned char gecastet, damit die Diagnosebits abgeschnitten werden und
> dann wird das Byte zurückgeschrieben.

Ja.
Aber nur dann, wenn in den Diagnosebits auch steht, dass ein Zeichen 
vorhanden ist.

> Irgendwo beim einlesen muss ein Fehler drin sein, denn

Der Fleury Code funktioniert. Den haben viele im Einsatz.
Also muss der Fehler vorrangig mal in deinem Code zu suchen sein.

> Hat jemand eine Idee, wie da heranzugehen ist?

Ja.
Wie immer. Den Code posten.
#3019915
Lesenswert?

http://www.gjlay.de/helferlein/avr-uart-rechner.html

Auf der Seite kannst du sehen, mit welchem Quarz du welche Baudrate 
hinbekommst, ohne das der Fehler zu gross wird.
RS232/485 verwendet asynchrone datenübertragung, sodass die Bitlänge auf 
2% genau sein muss, damit der Empfänger auch wirklich jedes bit 
mitbekommt und nichts verschluckt.
#3019932
Lesenswert?

Gustav schrieb:
> Karl Heinz Buchegger schrieb:
>
>>Der Fleury Code funktioniert. Den haben viele im Einsatz.
>
> Das kann nicht sein
> Es gibt auch unzählige wo es nicht geht.


Und wo ist dein Beispiel eines nicht funktionierenden Codes?
Erst mal ist nicht klar, warum es da überhaupt einen Unterschied geben 
soll. Der Fleury Code liefert die empfangenen Zeichen. Nicht mehr und 
nicht weniger. Wenn in der Weiterverarbeitung der Zeichen ein Fehler 
ist, dann kannst du das wohl schlecht dem Fleury Code anlasten. So 
gesehen ist es völlig egal, was du mit den Zeichen weiter machst - das 
ist erst mal dein Bier und bis zum Beweis des Gegenteils nicht dem 
Fleury Code anzulasten.

> Leider gibt es auch kein Beispiel auch hier nicht ausser das
> mitgelieferte wo, zb. Daten ins Array geschrieben
> werden.

Was genau stellt dich da vor Probleme?

1
char ReceivedLine[80];
2
uint8_t nextReceivedChar;
3
uint8_t receivedLineFinished;
4
uint8_t uartError;
5

6
uint8_t HandleUART()
7
{
8
  unsigned int c = uart_getc();
9

10
  if ( c & UART_NO_DATA )
11
    return;
12

13
  if ( (c & UART_FRAME_ERROR) ||
14
       (c & UART_OVERRUN_ERROR) ||
15
       (c & UART_BUFFER_OVERFLOW) ) {
16
    uartError = TRUE;
17
    return;
18
  }
19

20
  if ( nextReceivedChar >= sizeof( ReceivedLine ) - 1 ) {
21
    uartError = TRUE;
22
    nextReceivedChar  = 0;
23
  }
24

25
  ReceivedLine[ nextReceivedChar++ ] = c;
26
  ReceivedLine[ nextReceivedChar ] = '\0';
27

28
  if( c == '\n' )
29
    receivedLineFinished = TRUE;
30
  else
31
    receivedLineFinished  = FALSE;
32

33
  return receivedLineFinished ;
34
}

Was genau soll da jetzt in der Fleury Lib ein Problem machen?
Immer schön brav nach jedem uart_getc die Flags auswerten, dann kann es 
da keine Probleme mit der Lib geben. Eagl, wie man dann die Zeichen 
weiter auswertet und zb sukzessive in einem Array speichert.
#3020718
Lesenswert?

Lernender schrieb:
> Wie muss mann die "flags" in der Mainloop auswerten

Ähm.
Verarscht du mich jetzt?
Schon mal das Beispiel angesehen, welches Peter mitliefert?

Bzw. was könnte wohl das hier
1
  unsigned int c = uart_getc();
2

3
  if ( c & UART_NO_DATA )
4
    return;
5

6
  if ( (c & UART_FRAME_ERROR) ||
7
       (c & UART_OVERRUN_ERROR) ||
8
       (c & UART_BUFFER_OVERFLOW) ) {
9
    uartError = TRUE;
10
    return;
11
  }
sein, bzw. welche Aufgabe könnte das wohl im Zusammenhang mit dieser 
Funktion erfüllen?
Gast #3021782
Lesenswert?

nein ich will hier niemand Verarschen

so hab ich das bei mir,
nach Peter Fleury seinem Beispiel
1
uint8_t getdata()
2
{ 
3
  uint8_t next= 0;
4
  uint16_t c;
5
  char Message[70];
6
     
7

8
  
9

10
     next= 0;                    //Zeichenzähler auf Null setzen
11

12
     c = uart1_getc(); 
13

14
    if ( c & UART_NO_DATA )
15
    {
16
    }
17

18
    else
19
    {
20

21
            /*
22
             * new data available from UART
23
             * check for Frame or Overrun error
24
             */
25
            if ( c & UART_FRAME_ERROR )
26
            {
27
                /* Framing Error detected, i.e no stop bit detected */
28
                //uart_puts_P("UART Frame Error: ");
29
      }
30
            if ( c & UART_OVERRUN_ERROR )
31
            {
32
                /* 
33
                 * Overrun, a character already present in the UART UDR register was 
34
                 * not read by the interrupt handler before the next character arrived,
35
                 * one or more received characters have been dropped
36
                 */
37
                //uart_puts_P("UART Overrun Error: ");
38
      }
39
            if ( c & UART_BUFFER_OVERFLOW )
40
            {
41
                /* 
42
                 * We are not reading the receive buffer fast enough,
43
                 * one or more received character have been dropped 
44
                 */
45
                //uart_puts_P("Buffer overflow error: ");
46
      }
47
            /* 
48
             * send received character back
49
             */
50
            //uart_putc( (unsigned char)c );
51

52

53
   Message[ next] = c;                  //erstes Zeichen speichern
54
   next= 1;
55
     
56
        while( ( c = uart1_getc() ) != 55 && next< sizeof(Message)  )
57
        {
58
         Message[ next++ ] = c;
59
        }
60
        
61
     Message[next] = '\0';
62
    }
63
_delay_ms(400);
64
}
#3021812
Lesenswert?

Lernender schrieb:
> nein ich will hier niemand Verarschen
>
> so hab ich das bei mir,
> nach Peter Fleury seinem Beispiel

Na so ganz ist das nicht das Beispiel :-)
Du pruefst zwar auf die Fehlerzustaende, am Ende verwendest Du aber 
dennoch 'c' um es in Dein Array zu packen. Egal ob ein Fehler 
aufgetreten ist oder nicht.

Mach es so wie Karl Heinz es vorgeschlagen hat:
1
  if ( (c & UART_FRAME_ERROR) ||
2
       (c & UART_OVERRUN_ERROR) ||
3
       (c & UART_BUFFER_OVERFLOW) ) {
4
    // Hier kommt eine vernueftige Fehlerbehandlung
5
  }
6
  else {
7
    // und hier machst Du was mit 'c'
8
  }

Gruesse
#3021821
Lesenswert?

Thomas hat ja zu einem Teil schon was gesagt.

Weiters
1
       while( ( c = uart1_getc() ) != 55 && next< sizeof(Message)  )
2
        {
3
         Message[ next++ ] = c;
4
        }

Welchen Teil des Satzes ...
"Immer schön brav nach jedem uart_getc die Flags auswerten, dann kann es
da keine Probleme mit der Lib geben."
... hast du jetzt nicht verstanden?

Da, in dieser Schleife, ist ein uart_getc (ok, ein uart1_getc). WO 
wertest du die Flags aus, ob dieser Aufruf von uart1_getc überhaupt ein 
Zeichen geliefert hat?

Du musst schon nach den Regeln spielen! Das kann man wohl kaum der 
Fleury Lib anlasten, wenn du nicht gewillt bist, dich daran zu halten 
oder nicht verstehst, dass uart_getc dir mit seinem Returnwert mehrere 
Dinge mitteilen kann. Unter anderem den, dass zur Zeit eben kein Zeichen 
an der UART vorlag. Du scheinst das überhaupt nicht verstanden zu haben, 
dass dieses uart_getc aus der Fleury Lib eben NICHT wartet, bis ein 
Zeichen vorliegt, sondern dem Aufrufer mit dem Returnwert schlicht und 
ergreifend mitteilt: "Ich hab (noch) nichts. Probiers später nochmal. In 
der Zwischenzeit kannst du ja ruhig was anderes rechnen, wenn du 
möchtest."
#3021838
Lesenswert?

Damit Du nicht noch ewig rumhampeln musst ...
1
do {
2
  c = uart1_getc();
3
  if ( (c & UART_FRAME_ERROR) ||
4
     (c & UART_OVERRUN_ERROR) ||
5
     (c & UART_BUFFER_OVERFLOW) ) {
6
    // Fehlerbehandlung. Z.B. eine Led blinken lassen
7
  }
8
  else if( c & UART_NO_DATA ) {
9
    // kein Fehler. Aber es gibt (noch) kein Zeichen.
10
    // Der Mc ist nunmal schneller als die Schnittstelle :-)
11
  }
12
  else {
13
    // kein Fehler und es liegt auch ein Zeichen vor.
14
    Message[next++]=c;
15
  }
16
} while (c!=55 && next<sizeof(Message));

Das ist kein schoener Code, aber er soll Schritt fuer Schritt beleuchten 
wie man es machen koennte. Eventuell solltest Du noch vorsehen das Du 
nur Fehler bekommst (falsche Baudrate z.B.). Dann hast Du eine 
Endlosschleife weil die Abbruchbedingung nie erfuellt wird.
Gast #3021852
Lesenswert?

Karl Heinz Buchegger schrieb:
> Thomas hat ja zu einem Teil schon was gesagt.
>
> Weiters       while( ( c = uart1_getc() ) != 55 && next< sizeof(Message)  )
>         {
>          Message[ next++ ] = c;
>         }
>
> Welchen Teil des Satzes ...
> "Immer schön brav nach jedem uart_getc die Flags auswerten, dann kann es
> da keine Probleme mit der Lib geben."
> ... hast du jetzt nicht verstanden?



Es wird so lange eingelesen bis das Ende-Zeichen 55  kommt.
oder ist das nicht richtig
1
//Mainlloop
2
dat = uint8_t getdata() //wird von von der Mainloop aufgerufen
3

4

5
 if (dat == 1)
6
  {
7
   // keine daten
8
  }
9

10
 if (dat == 2)
11
  {
12
   // Daten Fehlerhaft
13
  }
14

15
 if (dat == 3)
16
  {
17
   // Daten korrekt
18
   //weiter verarbeiten
19
  }
20

21
uint8_t getdata()
22
{ 
23
  uint8_t next= 0;
24
  uint16_t c;
25
  char Message[70];
26
     
27

28
  
29

30
     next= 0;                    //Zeichenzähler auf Null setzen
31

32
     c = uart1_getc(); 
33

34
    if ( c & UART_NO_DATA )
35
    {
36
    return 1;
37
    }
38

39
  if ( (c & UART_FRAME_ERROR) ||
40
       (c & UART_OVERRUN_ERROR) ||
41
       (c & UART_BUFFER_OVERFLOW) ) {
42
    return 2;
43
  }
44
 else 
45
  {
46

47
   Message[ next] = c;                  //erstes Zeichen speichern
48
   next= 1;
49
     
50
        while( ( c = uart1_getc() ) != 55 && next< sizeof(Message)  )
51
        {
52
         Message[ next++ ] = c;
53
        }
54
        
55
     Message[next] = '\0';
56
    }
57
return 3;
58
_delay_ms(400);
59
}
#3021858
Lesenswert?

Lernender schrieb:
> Karl Heinz Buchegger schrieb:
>> Thomas hat ja zu einem Teil schon was gesagt.
>>
>> Weiters       while( ( c = uart1_getc() ) != 55 && next< sizeof(Message)  )
>>         {
>>          Message[ next++ ] = c;
>>         }
>>
>> Welchen Teil des Satzes ...
>> "Immer schön brav nach jedem uart_getc die Flags auswerten, dann kann es
>> da keine Probleme mit der Lib geben."
>> ... hast du jetzt nicht verstanden?
>
>
>
> Es wird so lange eingelesen bis das Ende-Zeichen 55  kommt.
> oder ist das nicht richtig

Aber der springende Punkt ist, dass nicht jeder Aufruf von uart1_getc 
ein Zeichen liefert!

Der µC ist hunderte male schneller, als Zeichen auf der Schnittstelle 
übertragen werden können!

Ist wie bei deinem Postkasten.
Du kannst alle 2 Minuten zum Postkasten laufen. Aber das bedeutet NICHT, 
dass da jedesmal ein Brief drinnen ist!

Sieh dir doch mal das Fleury Beispiel GENAU(!) an.

   c = uart_getc();

   if( c & UART_NO_DATA )
   {
   }

   else
     ....



was könnte wohl UART_NO_DATA heissen?
No Data - keine Daten
"Ich hab momentan nichts! Da ist nichts was du verarbeiten könntest!"
Eben "No Data"

Das scheint dich aber nicht weiter zu stören. Du speicherst trotzdem 
irgendwas ab. Selbst wenn auf der UART die Zeichen noch gar nicht da 
sind.
Gast #3021876
Lesenswert?

so geht es erstmal
aber ich muss _delay_ms(400); am ende reinschreiben ansonsten sind keine 
daten da
1
  c = uart1_getc();
2
  if ( (c & UART_FRAME_ERROR) ||
3
     (c & UART_OVERRUN_ERROR) ||
4
     (c & UART_BUFFER_OVERFLOW) ) {
5
    // Fehlerbehandlung. Z.B. eine Led blinken lassen
6
     return 1;
7
  }
8
  else if( c & UART_NO_DATA ) {
9
    // kein Fehler. Aber es gibt (noch) kein Zeichen.
10
    // Der Mc ist nunmal schneller als die Schnittstelle :-)
11
  }
12
  else
13
  {
14
    // kein Fehler und es liegt auch ein Zeichen vor.
15
    Message[next++]=c;
16
  
17
        while( ( c = uart1_getc() ) != 55 && next< sizeof(Message)  )
18
        {
19
         Message[ next++ ] = c;
20
        }
21
        
22
     Message[next] = '\0';
23
_delay_ms(400);
24
 return 4;
25
  }
26

27

28
}
#3021895
Lesenswert?

>        while( ( c = uart1_getc() ) != 55 && next< sizeof(Message)  )
                      ************


JEDER Aufruf von uart1_getc muss untersucht werden.

JEDER!

KEINE AUSNAHME!

ALLE!

ALL OF THEM!

TUTTI COMPLETI

(auf französisch kann ichs nicht)

ALLE!

DU HAST EINEN AUFRUF VON UART_GETC? DANN SIEH DIR IM ERGEBNIS DIE 
VERDAMMTEN FLAGS AN. WENN UART_NO_DATA GESETZT IST, DANN IST KEIN BYTE 
VORHANDEN! Noch nicht. Aber was noch nicht ist, kann ja noch werden.

alle? JAAAAA, ALLE!

aber .... KEIN 'ABER'. ALLE! JEDEN EINZELNEN!





Das ist doch nicht so schwer! Das ist eine ganz einfache Regel.

(Und ich glaube wir hatten das vor ein paar Monaten schon mal)
Gast #3022314
Lesenswert?

Leider geht das bei mir doch nicht so wies gedacht war.



1
  c = uart1_getc();
2
  if ( (c & UART_FRAME_ERROR) ||
3
     (c & UART_OVERRUN_ERROR) ||
4
     (c & UART_BUFFER_OVERFLOW) ) {
5
    // Fehlerbehandlung. Z.B. eine Led blinken lassen
6
  }
7
  else if( c & UART_NO_DATA ) {
8
    // kein Fehler. Aber es gibt (noch) kein Zeichen.
9
    // Der Mc ist nunmal schneller als die Schnittstelle :-)
10
  }
11
  else
12
  {
13
    // kein Fehler und es liegt auch ein Zeichen vor.
14
   Message[next++]=c;
15
     if ( c != 55 && next< sizeof(Message) )
16
      {
17
       TLED_ON();
18
       Message[next] = '\0'; 
19
      }
20
     else
21
      {
22
       TLED_OFF();
23
      }
24
 }
Gast #3022375
Lesenswert?

Das mit der do-while schleife blockiert ja dann das ganze Programm wenn 
mal kein zeichen kimmt.

Es sollen vom Slave Zeichen gelesen werden bis die Slave-Adresse =55 als 
Ende erkennung kommt.
Zeichen sehen wie folgt aus
zb. 889
zb.0010

Aber leider bekomme ich nur die ersten 3 zeichen.
1
  uint8_t next= 0;
2
  uint16_t c;
3
  char Message[70];
4

5
// Mainloop
6
  while (1)
7
  {
8
   getdata();
9

10
   DisplayText_s( 41, 35, Message);
11

12
  }
13
 }
14

15

16
uint8_t getdata()
17
{ 
18

19
  c = uart1_getc();
20
  if ( (c & UART_FRAME_ERROR) ||
21
     (c & UART_OVERRUN_ERROR) ||
22
     (c & UART_BUFFER_OVERFLOW) ) {
23
    // Fehlerbehandlung. Z.B. eine Led blinken lassen
24
  }
25
  else if( c & UART_NO_DATA ) {
26
    // kein Fehler. Aber es gibt (noch) kein Zeichen.
27
    // Der Mc ist nunmal schneller als die Schnittstelle :-)
28
  }
29
  else
30
  {
31
    // kein Fehler und es liegt auch ein Zeichen vor.
32
  
33
     if ( c != 55 && next< sizeof(Message) )
34
      {
35
       TLED_ON();
36
        Message[next++]=c;
37
      }
38
     else
39
      {
40
       Message[next] = '\0'; 
41
       next= 0;   // Zeichenzäühler auf null setzen
42
       TLED_OFF();
43
      }
44
 }
45
}
#3022417
Lesenswert?

Lernender schrieb:

>   while (1)
>   {
>    getdata();
>
>    DisplayText_s( 41, 35, Message);
>
>   }
>  }

Wenn du dir Message laufend ausgeben lässt, dann musst du auch dafür 
sorgen, dass Message nach jedem empfanegenen Zeichen wieder einen 
gültigen String ergibt. Im Moment tust du das nicht!

>      if ( c != 55 && next< sizeof(Message) )
>       {
>        TLED_ON();
>         Message[next++]=c;

        Message[next] = '\0';

>       }
>      else
>       {
>        Message[next] = '\0';
>        next= 0;   // Zeichenzäühler auf null setzen
>        TLED_OFF();
>       }
>  }
> }


Im übrigen: zeig alles!
#3022448
Lesenswert?

Moment.

Deine Messages: sind die überhaupt Text?
Oder sind das einfach nur eine Abfolge von Bytes?


Zeig doch bitte auch mal die Protokollbeschreibung nach der du 
programmierst. Das kommt mir ein wenig spanisch vor, dass jemand in 
einem binären Protokoll die Dezimal-Konstante 55 verwenden würde. 55 ist 
der ASCII COde für '7'. Und das wäre dann doch ein eher kurioses 'End Of 
Message' Zeichen.
Gast #3022465
Lesenswert?

So hier hab ich erstmal alles.
1
//SLAVE
2
sprintf(msg,"%02d",sens );  
3
uart_puts(msg);              
4
sprintf(msg,"%+03d,%1d", Vorkommastelle, Nachkommastelle);    
5
uart_puts( msg); 
6
uart_putc(55);       // device_ID ausgeben 
7
//SLAVE
8

9

10

11
  char buffer[50]; 
12
  char Message[70];
13
  uint8_t next= 0;
14

15
  signed int Wert[19];                  
16
  int Wertkomma[19];
17
  uint8_t sensorNr;                        
18

19
 
20

21
// Mainloop
22
  while (1)
23
  {
24
   getdata();
25

26
   
27

28
  }
29
 }
30

31

32
void getdata(uint8_t second)
33
{
34
  uint16_t c;
35

36
    if (second== 1)
37
    {_delay_ms(1000);
38
     tempsend(T_mess,TEMPER_ADDR);    // Komando zum Temperratur messen schicken
39
  }
40
  c = uart1_getc();
41
  if ( (c & UART_FRAME_ERROR) ||
42
     (c & UART_OVERRUN_ERROR) ||
43
     (c & UART_BUFFER_OVERFLOW) ) {
44
    // Fehlerbehandlung. Z.B. eine Led blinken lassen
45
  }
46
  else if( c & UART_NO_DATA ) {
47
    // kein Fehler. Aber es gibt (noch) kein Zeichen.
48
    // Der Mc ist nunmal schneller als die Schnittstelle :-)
49
  }
50
  else
51
  {
52
    // kein Fehler und es liegt auch ein Zeichen vor.
53
  
54
     if ( c != 55 && next< sizeof(Message) )
55
      {
56
       TLED_ON();
57
        Message[next++]=c;
58
      }
59
     else
60
      {
61
       Message[next] = '\0'; 
62
       next= 0;   // Zeichenzäühler auf null setzen
63
       TLED_OFF();
64
      }
65
 }
66

67

68
      // ersten 2 stellen vorm komma mit Vorzeichen Speichern
69
      int messWert = atoi( &Message[3] );
70
      Wert[sensorNr] = messWert;    
71
      //nachkomma= n;
72
      int n= atoi( &Message[7]);
73
      Wertkomma[sensorNr] = n;
74

75

76
      if( sensorNr == 1 ) 
77
     {  
78
        outtValut( 41, 35, sensorNr,"%2d %+3d,%1d", Wert[sensorNr], Wertkomma[sensorNr]);
79

80
       }
81

82
      if( sensorNr == 2 ) 
83
     {  
84
        outtValut( 41, 60, sensorNr,"%2d %+3d,%1d", Wert[sensorNr], Wertkomma[sensorNr]);
85

86
      } 
87

88

89
      if( sensorNr == 3 ) 
90
     {  
91
        outtValut( 41, 85, sensorNr,"%2d %+3d,%1d", Wert[sensorNr], Wertkomma[sensorNr]);
92

93
     }
94
}
95

96

97
void outtValut(uint16_t x,uint16_t y,uint8_t sens ,char *name, signed int valu,int nachkomma )
98

99
{
100

101
  SetBrushColor(0, 0, 0);// Brush Color white
102
  SetPenColor(255, 165, 0); 
103
  SetFont(1);                  // Text and Number Font 1
104
    
105
  sprintf( buffer_t,name ,sens, valu, nachkomma  ); 
106
  DisplayText_s(x, y, buffer_t);
107
  SetFont(0);                  // Text and Number Font 1
108

109
}
110

111

112

113

114

115

116

117

118
// Comando und Adresse Schicken
119
void tempsend(uint8_t data,uint8_t adress)
120
{
121
  setTransmitMode();
122
  uart1_putc(data);      // Startkommando: Messen
123
  uart1_putc(adress);    // Adresse schicken
124
  setReceiveMode();
125
}
#3022681
Lesenswert?

Ähm

> uart_putc(55);       // device_ID ausgeben

Dir ist aber schon klar, dass 55 der ASCII Code für '7' ist?

d.h. sobald in deinen Daten

> sprintf(msg,"%02d",sens );
> uart_puts(msg);
> sprintf(msg,"%+03d,%1d", Vorkommastelle, Nachkommastelle);
> uart_puts( msg);

irgendwo eine 7 vorkommt, dann wird der Empfänger das mit der von dir 
angedachten Device-Id verwechseln!

Der Empfänger kriegst Bytes. Welche Bytes er als Codes für ASCII Zeichen 
auffassen soll und welche Bytes direkt einen numerischen Wert 
darstellen, kann er erst mal nicht unterscheiden. Das gibt dein 
'Protokoll' bzw. die Implementierung beim Empfänger nicht her.
#3023354
Lesenswert?

Lernender schrieb:
> So habe die
>> uart_putc(60);       // device_ID ausgeben
> device_ID vonn 55 auf 60 geändert trotzdem bekomme ich nur den ersten
> wert!
Also ich verstehe es immer noch nicht. Was genau empfängst Du denn nun?
So wie ich das interpretiere, schickt Dir Dein Sensor einen String, 
bestehend aus 8 Zeichen. Die ersten beiden stehen für die Sensornummer, 
dann kommt das Vorzeichen des Messwerts, danach kommen zwei Zeichen, die 
den ganzzahligen Anteil des Messwerts darstellen, dann ein Komma, dann 
eine Nachkommastelle und dann noch ein Zeichen, dass die ID darstellt.

Mal ein Beispiel:
Der Sensor mit der Nummer "99" und der ID 60 sendet den Messwert "-9,8", 
d.h. die Übertragung lautet:
1
"99-09,8<"

Was davon "bekommst" Du denn nun?

Was mir an Deinem Code sonst noch aufgefallen ist:

Lernender schrieb:
> Wert[sensorNr] = messWert;

> Wertkomma[sensorNr] = n;

> if( sensorNr == 1 )

> if( sensorNr == 2 )

> if( sensorNr == 3 )

Der Variable "sensorNr", die Du hier mehrmals verwendest, wird nie ein 
Wert zugewiesen.

> // ersten 2 stellen vorm komma mit Vorzeichen Speichern
>       int messWert = atoi( &Message[3] );
Der Messwert (das Vorzeichen) beginnt bei Index "2" nicht bei "3".

> int n= atoi( &Message[7]);
Gleicher Fehler hier: die Nachkommastelle befindet sich bei Index "6", 
nicht "7".
#3023357
Lesenswert?

Lernender schrieb:
> So hier hab ich erstmal alles.
Alles ist das sicher nicht. Die includes fehlen z.B.


>
> // Mainloop
>   while (1)
>   {
>    getdata();
//hier rufst Du getdata ohne Parameter auf. Laut Definition weiter unten 
kommt hier ein Parameter hin. Nicht fein.
>
>
>
>   }
>  }
>
>
> void getdata(uint8_t second)
> {
>   uint16_t c;
>
// da Du den parameter second nicht uebergibst wird der Code auch nicht 
ausgefuehrt. Obwohl ich bezweifle das er sinnvoll ist...
>     if (second== 1)
>     {_delay_ms(1000);
>      tempsend(T_mess,TEMPER_ADDR);    // Komando zum Temperratur messen schicken
>   }

// Jetzt faengst Du an etwas sinnvolles zu machen
>   c = uart1_getc();
>   if ( (c & UART_FRAME_ERROR) ||
>      (c & UART_OVERRUN_ERROR) ||
>      (c & UART_BUFFER_OVERFLOW) ) {
>     // Fehlerbehandlung. Z.B. eine Led blinken lassen
>   }
>   else if( c & UART_NO_DATA ) {
>     // kein Fehler. Aber es gibt (noch) kein Zeichen.
>     // Der Mc ist nunmal schneller als die Schnittstelle :-)
>   }
>   else
>   {
>     // kein Fehler und es liegt auch ein Zeichen vor.
>
>      if ( c != 55 && next< sizeof(Message) )
>       {
>        TLED_ON();
>         Message[next++]=c;
>       }
>      else
>       {
>        Message[next] = '\0';
>        next= 0;   // Zeichenzäühler auf null setzen
>        TLED_OFF();
>       }
>  }
// und hier hoerst Du mit der Sinnhaftigkeit auf.

// Nun verwendest Du den Buffer obwohl ja nichts oder hoechstend 1 
Zeichen  drin steht.
//Wieder mal: wo ist Deine while oder do-while Schleife?
// Ab hier machst Du nur noch Quatsch. Sorry.

>       // ersten 2 stellen vorm komma mit Vorzeichen Speichern
>       int messWert = atoi( &Message[3] );
>       Wert[sensorNr] = messWert;
>       //nachkomma= n;
>       int n= atoi( &Message[7]);
>       Wertkomma[sensorNr] = n;
>
...

>So habe die
>> uart_putc(60);       // device_ID ausgeben
>device_ID vonn 55 auf 60 geändert trotzdem bekomme ich nur den ersten
>wert!
Wie kommst Du nun auf die 60? Ich sage nicht das es falsch ist, aber 
niemand ausser Dir weiss warum Du erst eine 55 und nun eine 60 
verwendest.
Welches Protokoll soll das sein?

Ich will Dich wirklich nicht aergern oder beleidigen, aber Du solltest 
definitv erst einmal ein C-Buch oder ein Tutorial durcharbeiten.
Mit Deinem Wissensstand wird das nix ...
Gast #3023389
Lesenswert?

So bekomme ich nur den ersten Wert vom Sensor angezeigt

getdata(second); wird doch in der While (1) schleife doch ständig 
aufgerufen.
   while (1)
   {
    getdata(second);
   }
 }





Mit der
do {
  c = uart1_getc();
  if ( (c & UART_FRAME_ERROR) ||
     (c & UART_OVERRUN_ERROR) ||
     (c & UART_BUFFER_OVERFLOW) ) {
    // Fehlerbehandlung. Z.B. eine Led blinken lassen
  }
  else if( c & UART_NO_DATA ) {
    // kein Fehler. Aber es gibt (noch) kein Zeichen.
    // Der Mc ist nunmal schneller als die Schnittstelle :-)
  }
  else {
    // kein Fehler und es liegt auch ein Zeichen vor.
    Message[next++]=c;
  }
} while (c!=55 && next<sizeof(Message));

wird ja das ganze Programm angehalten wenn kein zeichen kommt.

1
//SLAVE
2
sprintf(msg,"%02d",sens );  
3
uart_puts(msg);              
4
sprintf(msg,"%+03d,%1d", Vorkommastelle, Nachkommastelle);    
5
uart_puts( msg); 
6
uart_putc(55);       // device_ID ausgeben 
7
//SLAVE
8

9

10

11
  char buffer[50]; 
12
  char Message[70];
13
  uint8_t next= 0;
14

15
  signed int Wert[19];                  
16
  int Wertkomma[19];
17
  uint8_t sensorNr;                        
18

19
 
20

21
// Mainloop
22
  while (1)
23
  {
24
   getdata();
25

26
   
27

28
  }
29
 }
30

31

32
void getdata(uint8_t second)
33
{
34
  uint16_t c;
35

36
    if (second== 1)
37
    {_delay_ms(1000);
38
     tempsend(T_mess,TEMPER_ADDR);    // Komando zum Temperratur messen schicken
39
  }
40
  c = uart1_getc();
41
  if ( (c & UART_FRAME_ERROR) ||
42
     (c & UART_OVERRUN_ERROR) ||
43
     (c & UART_BUFFER_OVERFLOW) ) {
44
    // Fehlerbehandlung. Z.B. eine Led blinken lassen
45
  }
46
  else if( c & UART_NO_DATA ) {
47
    // kein Fehler. Aber es gibt (noch) kein Zeichen.
48
    // Der Mc ist nunmal schneller als die Schnittstelle :-)
49
  }
50
  else
51
  {
52
    // kein Fehler und es liegt auch ein Zeichen vor.
53
  
54
     if ( c != 55 && next< sizeof(Message) )
55
      {
56
       TLED_ON();
57
        Message[next++]=c;
58
      }
59
     else
60
      {
61
       Message[next] = '\0'; 
62
       next= 0;   // Zeichenzäühler auf null setzen
63
       TLED_OFF();
64
      }
65
 }
66

67
 
68
    sensorNr = (Message_in1[1]-'0')*10 + (Message_in1[2]-'0'); 
69
 
70

71
    if( sensorNr != 255 ) {
72

73
      // ersten 2 stellen vorm komma mit Vorzeichen Speichern
74
      int messWert = atoi( &Message[3] );
75
      Wert[sensorNr] = messWert;    
76
      //nachkomma= n;
77
      int n= atoi( &Message[7]);
78
      Wertkomma[sensorNr] = n;
79
}
80

81
      if( sensorNr == 1 ) 
82
     {  
83
        outtValut( 41, 35, sensorNr,"%2d %+3d,%1d", Wert[sensorNr], Wertkomma[sensorNr]);
84

85
       }
86

87
      if( sensorNr == 2 ) 
88
     {  
89
        outtValut( 41, 60, sensorNr,"%2d %+3d,%1d", Wert[sensorNr], Wertkomma[sensorNr]);
90

91
      } 
92

93

94
      if( sensorNr == 3 ) 
95
     {  
96
        outtValut( 41, 85, sensorNr,"%2d %+3d,%1d", Wert[sensorNr], Wertkomma[sensorNr]);
97

98
     }
99
}
100

101

102
void outtValut(uint16_t x,uint16_t y,uint8_t sens ,char *name, signed int valu,int nachkomma )
103

104
{
105

106
  SetBrushColor(0, 0, 0);// Brush Color white
107
  SetPenColor(255, 165, 0); 
108
  SetFont(1);                  // Text and Number Font 1
109
    
110
  sprintf( buffer_t,name ,sens, valu, nachkomma  ); 
111
  DisplayText_s(x, y, buffer_t);
112
  SetFont(0);                  // Text and Number Font 1
113

114
}
115

116

117

118

119

120

121

122

123
// Comando und Adresse Schicken
124
void tempsend(uint8_t data,uint8_t adress)
125
{
126
  setTransmitMode();
127
  uart1_putc(data);      // Startkommando: Messen
128
  uart1_putc(adress);    // Adresse schicken
129
  setReceiveMode();
130
}


So bekomm ich alle 3 Werte angezeigt
1
c = uart1_getc(); 
2

3
   Message[ next] = c;                  //erstes Zeichen speichern
4
   next = 1;
5
     
6
    while( ( c = uart1_getc() ) != 60 && next< sizeof(Message)  )
7
        {
8
         Message[ next++ ] = c;
9
        }
10
        
11
     Message[next] = '\0';
12
     next= 0;                    //Zeichenzähler auf Null setzen

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