Forum: Mikrocontroller und Digitale Elektronik MAX485: empfängt eine Null, die keine ist


von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

Hallo!
In meiner Hauselektronik werkelt ein Atmega 2560, indem er mittels 
mehrerer Max485 verschiedene Ein- und Ausgabegeräte ansteuert.
Es läuft alles wunderbar, auch keine Probleme mit Senden/ Empfang wie 
sie hier oftmals beschrieben sind.

Mit einer Einschränkung:
-wenn ich eine Zeichenkette händisch (d.h. langsam, z.B. per Hyperterm) 
sende, empfängt der AVR nach jedem gesendeten Zeichen ein nachgestelltes 
'/0'. Mir scheint, als nehme der MAX485 nach dem Empfang einen Zustand 
ein, den der AVR für ne empfangene '\0' wertet - aber es dürfte doch 
kein Stopp-Bit generiert werden. Kann ich das ggfs durch pull-up 
umgehen?

Beste Grüße und schonmal ein schönes Wochenende!


Ich benutze u.g. Routine.
1
ISR(USART3_RX_vect){
2
  unsigned char nextChar;
3
  nextChar = UDR3;
4
  if( uart3_str_complete == 0 ) {
5
    if( nextChar != '\n' &&  nextChar != '\r' &&  uart3_str_count < UART_MAXSTRLEN ){
6
      uart3_array[uart3_str_count] = nextChar;
7
      uart3_str_count++;}
8
    else {
9
      uart3_array[uart3_str_count] = '\0';
10
      uart3_str_count = 0;
11
      uart3_str_complete = 1;}
12
  }
13
}

: Bearbeitet durch User
von H.Joachim S. (crazyhorse)


Lesenswert?

Wie machst du denn die Richtungsumschaltung wenn du vom PC/Hyperterm aus 
sendest?

von Harald (Gast)


Lesenswert?

Suche mal nach "rs485 termination biasing", als Beispiel
https://know.innon.com/bias-termination-rs485-network

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stephan R. schrieb:
> Mir scheint
Ich würde diesen Anschein verfestigen und mal mit einem Oszilloskop 
messen:
Was tut sich da im Fehlerfall auf dem Bus?
Und was tut sich passend dazu am RX-Pin des µC?

von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

H.Joachim S. schrieb:
> Wie machst du denn die Richtungsumschaltung wenn du vom PC/Hyperterm aus
> sendest?

Das beschriebene Fehlerverhalten tritt völlig unabhängig vom 
Sende/Empfang-Umschalten auf bzw. ich habe sie zur Fehlersuche 
abgeschaltet. Der UART3 lauscht nur und der MAX485 ist die ganze Zeit im 
Empfangs-Modus.



Aber um die Frage dennoch zu beantworten:
1
#define RS485_3_SND_EN  {PORTG |=(1 << 5); _delay_ms(3);}
2
#define RS485_3_RCV_EN  {_delay_ms(3); PORTG &=  ~(1 << 5);}
3
4
void uart3_RS485 (char* string){
5
  RS485_3_SND_EN
6
  uart3_puts(string);
7
  RS485_3_RCV_EN
8
  uart3_flush ();
9
}
10
11
void uart3_flush (void){
12
    uart3_str_count = 0;
13
    uart3_str_complete = 0;
14
}

von Jim M. (turboj)


Lesenswert?

Wie ist der RS485 Bus vorgespannt? Da muss ja ein Pullup und ein 
Pulldown dran sein.

Eine "0" (binäre Null) unterscheidet sich nur durch das fehlende Stopp 
Bit von einem "Break". Ein auf Null vorgspannter Bus erzeigt immer ein 
Break wenn der Sender abschaltet.

Unterscheiden kann man das beim Empfänger nur dann wenn man die Status 
Bits auswertet.

Ich spanne daher den RS485 Bus gerne auf "1" vor...

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stephan R. schrieb:
> Der UART3 lauscht nur und der MAX485 ist die ganze Zeit im Empfangs-Modus.
Und: was macht der 485 Treiber auf der Senderseite?
Aus diesem Grund ist die einzig relevante Frage: was passiert auf dem 
Bus?

Jim M. schrieb:
> Wie ist der RS485 Bus vorgespannt? Da muss ja ein Pullup und ein
> Pulldown dran sein.
Es muss nicht unbedingt einer dran sein, aber dann muss der 
Empfänger eben mit den erratischen Pegeln klarkommen, die sich 
einstellen, wenn kein Sender aktiv ist.

: Bearbeitet durch Moderator
von Georg (Gast)


Lesenswert?

Stephan R. schrieb:
> aber es dürfte doch
> kein Stopp-Bit generiert werden

Es gibt überhaupt keine serielle Übertragung ohne Stopbit. Oder meinst 
du da was ganz anderes?

Georg

von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

Lothar M. schrieb:
> was passiert auf dem
> Bus?

D.h. Oszilloskop ausmotten

Georg schrieb:
> Es gibt überhaupt keine serielle Übertragung ohne Stopbit. Oder meinst
> du da was ganz anderes?

Nein, genau so.

Jim M. schrieb:
> Wie ist der RS485 Bus vorgespannt?

Muss ich herausfinden.. jedoch, bei längeren Zeichenketten funzt ja 
alles problemlos.

von leo (Gast)


Lesenswert?

Stephan R. schrieb:
> wenn ich eine Zeichenkette händisch (d.h. langsam, z.B. per Hyperterm)
> sende, empfängt der AVR nach jedem gesendeten Zeichen ein nachgestelltes
> '/0

Ich schätze mal, dass du UTF-16 schickst.

Leo

von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

leo schrieb:
> Ich schätze mal, dass du UTF-16 schickst.

Das Problem tritt auch auf, wenn ich mittels HTerm die Zeichen einzeln 
sende. Oder, was könnte die Verwendung von UTF-16 für mich und den AVR 
bedeuten?

EDIT: wenn ich Hyperterminal und HTerm "verbinde", so kommt im HTerm 
auch stets nur das eine jeweilige im Hyperterminal gesendete Zeichen an. 
Ohne Null.

: Bearbeitet durch User
von leo (Gast)


Lesenswert?

Stephan R. schrieb:
> was könnte die Verwendung von UTF-16 für mich und den AVR bedeuten?

Genau das beschriebene Symptom. Prüf den Zeichensatz des HTerms.

Leo

von Andreas B. (bitverdreher)


Lesenswert?

Stephan R. schrieb:
> D.h. Oszilloskop ausmotten

Tip: Kauf Dir einen Saleae clone für 10€ aus der Bucht und installiere 
Dir Pulseview. Das schlägt für so etwas jedes Oszilloskop.

von Stephan R. (Firma: FHK) (nautosteer)


Angehängte Dateien:

Lesenswert?

leo schrieb:
> Genau das beschriebene Symptom. Prüf den Zeichensatz des HTerms.

Das Bild zeigt die vom HTerm empfangenen Zeichen, wie ich sie ins 
Hyperterminal getippt habe. Gibt es Grund zur Annahme, dass Hyperterm 
noch mehr sendet?

: Bearbeitet durch User
von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

Andreas B. schrieb:
> Tip: Kauf Dir einen Saleae clone

Da fällt mir ein dass ich noch irgendwo einen RedPitaya herumliegen 
habe...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stephan R. schrieb:
> EDIT: wenn ich Hyperterminal und HTerm "verbinde", so kommt im HTerm
> auch stets nur das eine jeweilige im Hyperterminal gesendete Zeichen an.
Wie verbindest du die beiden? Über den RS485-Bus?

Andreas B. schrieb:
> Tip: Kauf Dir einen Saleae clone für 10€ aus der Bucht und installiere
> Dir Pulseview. Das schlägt für so etwas jedes Oszilloskop.
Nochn Tipp: sieh dir trotzdem auch die wirklichen analogen Pegel auf dem 
Bus an. Denn nur das, was dort völlig analog passiert, kann eine 
nachgeschaltete Elektronik in 0 und 1 umwandeln.

von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

Lothar M. schrieb:
> Wie verbindest du die beiden?

Über einen VirtualSerialPortEmulator

> sieh dir trotzdem auch die wirklichen analogen Pegel auf dem
Bus an.

Mach ich.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Stephan R. schrieb:
> Ich benutze u.g. Routine

Ist sichergestellt, dass sie framing-error erkennt?

Falls nicht, baudrate unterschiedlich und einbauen.

Fehler-Suche macht keinen Sinn, wenn framing (und Parity, overrun) nicht 
ausgewertet werden

von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

A. S. schrieb:
> Ist sichergestellt, dass sie framing-error erkennt?

Ich befürchte, das sagt mir nicht allzu viel. Hat mich aber auf einen 
Workaround gebracht:

Eine empfangene '\0' wird stets weggeschmissen.
Scheissidee?
1
ISR(USART3_RX_vect){
2
  unsigned char nextChar;
3
  nextChar = UDR3;
4
  if( uart3_str_complete == 0 &&  nextChar != '\0') {  //Da!
5
    if( nextChar != '\n' &&  nextChar != '\r' &&  uart3_str_count < UART_MAXSTRLEN ){
6
      uart3_array[uart3_str_count] = nextChar;
7
      uart3_str_count++;
8
      uart0_putc(nextChar);
9
    }
10
    else {
11
      uart3_array[uart3_str_count] = '\0';
12
      strcpy(uart3_string, uart3_array);
13
      uart3_str_count = 0;
14
      uart3_str_complete = 1;
15
    }
16
  }
17
}

EDIT: es funktioniert.

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

Was steht denn bei Dir bei "Send on Enter"?

von Dietrich L. (dietrichl)


Lesenswert?

Stephan R. schrieb:
> Jim M. schrieb:
>> Wie ist der RS485 Bus vorgespannt?
>
> Muss ich herausfinden.. jedoch, bei längeren Zeichenketten funzt ja
> alles problemlos.

Das kann durchaus sein: bei kurzen Pausen kann der Pegel auf der Leitung 
in den Sendepausen gerade noch gut genug erhalten bleiben, bei längeren 
Pausen driftet er weg.

von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

Andreas B. schrieb:
> Was steht denn bei Dir bei "Send on Enter"?

Je nachdem, was ich vorhabe: zum Einzelzeichen senden 'NONE', zum 
Komplettstring simulieren 'Cr'.

von Wolfgang (Gast)


Lesenswert?

Stephan R. schrieb:
> Mir scheint, als nehme der MAX485 nach dem Empfang einen Zustand
> ein, den der AVR für ne empfangene '\0' wertet - aber es dürfte doch
> kein Stopp-Bit generiert werden.

Für ein Stoppbit wird nichts generiert. Ein Stopp-Bit ist lediglich eine 
Pause (Mark-Pegel) von einer Bit-Dauer, bevor das nächste Start-Bit 
kommen darf.

von jo (Gast)


Lesenswert?

Jim M. schrieb:
> Eine "0" (binäre Null) unterscheidet sich nur durch das fehlende Stopp
> Bit von einem "Break". Ein auf Null vorgspannter Bus erzeigt immer ein
> Break wenn der Sender abschaltet.
>
> Unterscheiden kann man das beim Empfänger nur dann wenn man die Status
> Bits auswertet.

Zusatzinfo:
Die "break condition" wird hier, mehr oder weniger ausführlich, 
diskutiert:

https://netbsd-users.netbsd.narkive.com/LbW29ucx/what-is-a-serial-break

https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter#Break_condition

https://groups.google.com/g/beagleboard/c/-_MNJSArsFU

von A. S. (Gast)


Lesenswert?

Stephan R. schrieb:
> Scheissidee?

Ja. Framing ist das mindeste, was Du erkennen musst

Jim M. schrieb:
> Unterscheiden kann man das beim Empfänger nur dann wenn man die Status
> Bits auswertet.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stephan R. schrieb:
> Eine empfangene '\0' wird stets weggeschmissen.
So geht ein richtig guter Softwerkerworkaorund!
Der würde gut zum "Schönsaufen" passen:
>>>> Es läuft alles wunderbar, auch keine Probleme mit Senden/ Empfang

Denn schon das stimmt natürlich nicht. Du hast tatsächlich Probleme 
beim Empfangen und siehst mit diesem "Ausnahmefall" erstmal nur die 
Spitze des Eisbergs, ohne die Ursache zu kennen. Und vermutest, dass das 
immer eine 0 ist und die immer am Ende eines Telegramms kommt.
Aber wenn eines deiner Geräte beim sonst durchgängigen Senden einmal am 
Tag eine kurze Pause zwischen 2 Bytes einlegt (evtl. weil ein 
mordswichtiger Interrupt daherkommt), dann hast du eben auch mittendrin 
ab&zu mal so eine korrupte 0. Oder weil der Bus in diesem Augenblick ja 
offen herumfloatet eben irgendwas.

Ich würde aber auch drauf setzen, dass du nur solche Zeichen als 
gültig erkennst, die auch ein gültiges Stopbit haben. Denn wenn 
nicht mal das Stopbit stimmt, dann liegt es nahe, dass der Rest davor 
nicht viel besser ist...

: Bearbeitet durch Moderator
von EAF (Gast)


Lesenswert?

Stephan R. schrieb:
> uart3_puts(string);
>   RS485_3_RCV_EN

Das sieht für mich so aus, als wenn dir Richtung umgeschaltet wird, 
bevor das letzte Bit rausgeschoben wurde.
Leider entzieht sich das einer genaueren Überprüfung, da uart3_puts() 
geheim ist.

von (Gast)


Lesenswert?

Bus nachmessen im idle-Zustand.

Wenn kein "failsafe" vorhanden ist das für definierte Pegel sorgt kann 
(abhängig von Leitungslänge, Mondphase und aktuellem Gemütszustand von 
Lady Gaga) das Ausschalten des Senders vom Empfänger als Start-Bit 
interpretiert werden und dann wird ein Byte Mist eingelesen.

von Noy (Gast)


Lesenswert?

Womit bist du am Bus? FTDI+RS485 Treiber?
Hatte mal den Fall das auf so nem FTDI+Treiber Platinchen die RX/TX 
zwischen FTDI und RS485 Treiber mit Pulldowns statt Pullups bestückt 
waren... Da kam auch immer eine 0 zu viel an..

von Georg (Gast)


Lesenswert?

Wolfgang schrieb:
> Für ein Stoppbit wird nichts generiert. Ein Stopp-Bit ist lediglich eine
> Pause

Das habe ich auch schon gepostet, aber mein Eindruck ist dass der TO 
garnicht weiss wovon die Rede ist, er bringt wohl Stopbit und /0 
durcheinander.

Georg

von Stephan R. (Firma: FHK) (nautosteer)


Lesenswert?

Georg schrieb:
> mein Eindruck ist dass der TO
> garnicht weiss wovon die Rede ist

Möglicherweise liegst Du gar nicht so verkehrt, ich dachte stets, ein 
Stoppbit wäre mit einer Pegeländerung verbunden.
Nur, woring liegt der Unterschied zwischen einem Stopbit und einem 
"gesendeten" /0, wenn bei beidem keine Pegeländerungen stattfinden.

Da ich beruflich umorientiert "wurde" und auch mein Labor eingemottet 
ist, wird es ein wenig dauern, bis ich die Signale anschauen und melden 
kann.

von EAF (Gast)


Lesenswert?

Stephan R. schrieb:
> woring liegt der Unterschied zwischen einem Stopbit und einem
> "gesendeten" /0, wenn bei beidem keine Pegeländerungen stattfinden.

'\0' ist ein Zeichen oder Byte
Und ein Bit ist eben ein Bit, wovon sich häufig 8 zu einem Byte 
gruppieren, und ca 10 Bit in einem UART Frame versammelt sind.

von EAF (Gast)


Lesenswert?


von Hmmm (Gast)


Lesenswert?

Georg schrieb:
> mein Eindruck ist dass der TO garnicht weiss wovon die Rede ist, er
> bringt wohl Stopbit und /0 durcheinander.

Ich glaube, ihm ist einfach nicht klar, dass auch bei fehlendem Stopbit 
ein Byte empfangen wird und man deshalb "von Hand" auf Framing Errors 
prüfen muss.

Das Problem selbst dürfte einfach an fehlenden oder vertauschten 
Bias-Widerständen liegen.

Beim Abschalten des Treibers gibt es eine fallende Flanke, und dass die 
nur beim langsamen manuellen Senden stört, liesse sich damit erklären, 
dass der Code nach dem Empfang eines kompletten Pakets nachfolgenden 
Müll ignoriert.

Stephan R. schrieb:
> woring liegt der Unterschied zwischen einem Stopbit und einem
> "gesendeten" /0, wenn bei beidem keine Pegeländerungen stattfinden.

0x00 (korrekt):

1 (Ruhelage) - 0 (Startbit) - 8x 0 (Datenbits) - 1 (Stopbit, entspricht 
dem Ruhepegel)

0x00 (mit Framing Error):

1 (Ruhelage) - 0 (Startbit) - 8x 0 (Datenbits) - Rest egal, kann auch 
dauerhaft auf 0 bleiben.

Resultat: Eine fallende Flanke mit mindestens 9 Bitzeiten (streng 
genommen etwas weniger) Low-Pegel kommt als 0x00 mit Framing Error an.

von A. S. (Gast)


Lesenswert?

Stephan R. schrieb:
> Da ich beruflich umorientiert "wurde" und auch mein Labor eingemottet
> ist, wird es ein wenig dauern, bis ich die Signale anschauen und melden
> kann.

Dann solltest Du Dir umso mehr den Wiki-Artikel zur seriellen 
Übertragung anschauen.

Da es häufig zur Konfusion führt, zumindest bei RS232, wo es nur ein 
Pegel gibt (und kein differentielles Signal):

 * Der Ruhepegel der eigentlichen Schnittstelle ist 1 (high)
 * Da meist ein Inverter auf beiden Seiten verbaut ist, ist der 
Ruhepegel auf der Leitung (wo man meistens misst) 0 (oder low, z.B. 
-5V). Am Uart-Chip hingegen 1.
 * Ein Frame fängt mit dem Startbit an (Wechsel von Ruhepegel auf 0, für 
eine Bitzeit) und hört mit mindestens einem Bit Ruhepegel auf (Stoppbit)

Eine Übertragung beginnt mit dem Wechsel von high nach low. Das 
triggert ein neues Zeichen. Meist wird das Startbit selber gar nicht 
ausgewertet. D.H. auch ein kurzer Spike oder ein permanenter Wechsel vom 
Ruhepegel 1 nach 0 startet ein neues Zeichen. Und das ist nach 10 oder 
11 Bitzeiten auch fertig. Wenn Du die Fehlerbits nicht auswertet, wird 
halt beim Spike ein 0xff (alles 1), ansonsten eine 0 (alles 0) 
empfangen. Bei beliebigen Störungen auch beliebige Daten.

(Wenn Du eine 0 empfängst, lässt es darauf schließen, dass der Sender 
"abschaltet" und sich daraufhin am Empfänger "der NICHT-Ruhepegel" 
einstellt. Das ist ein perfektes 0x00 mit Framing-Error (=Stoppbit nicht 
erkannt).

von Wolfgang (Gast)


Lesenswert?

Stephan R. schrieb:
> Möglicherweise liegst Du gar nicht so verkehrt, ich dachte stets, ein
> Stoppbit wäre mit einer Pegeländerung verbunden.

Nur, wenn das MSB vom übertragenen Byte eine 0 ist.

von Hmmm (Gast)


Lesenswert?

Hmmm schrieb:
> Resultat: Eine fallende Flanke mit mindestens 9 Bitzeiten (streng
> genommen etwas weniger) Low-Pegel kommt als 0x00 mit Framing Error an.

Korrekt muss es heissen "ggf. mit Framing Error" - wenn nach den 9 
Bitzeiten Low-Pegel wieder ein High-Pegel kommt, gibt es keinen.

von achs (Gast)


Lesenswert?

Hmmm schrieb:
> Korrekt muss es heissen

Nach 9,5 bitzeiten low (bei 8 bit ohne parity) bzw. 10,5 mit parity.

9 bits sind Start und 8 datenbits. Das zehnte wird (wie alle) in der 
Mitte ausgewertet. Darum 9,5, bzw. mit parity 10,5.

von Sascha W. (sascha-w)


Lesenswert?

Stephan R. schrieb:
> A. S. schrieb:
>> Ist sichergestellt, dass sie framing-error erkennt?
>
> Ich befürchte, das sagt mir nicht allzu viel. Hat mich aber auf einen
> Workaround gebracht:
anstatt irgend was zu basteln solltest du einfach die entsprechenden 
Bits (FE, DOR, PE) im USR am Anfang deiner ISR checken - dazu sind sie 
da!

Sascha

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.