Hallo,
ich habe noch nicht viel Erfahrung mit Arduino, bisher habe ich aber dank vieler Anleitungen im Internet alles programmiert bekommen. Nun möchte ich über RS485 eine Vernetzung machen und habe mir dafür einen fertigen Adapter gekauft, so etwa in der Art wie der hier:
https://www.ebay.de/itm/MAX485-TTL-Schnittstelle-Modul-Adapter-RS-485-RS-485-Arduino-Raspberry-Pi-Module-/162384175341?_trksid=p2385738.m4383.l4275.c10
Leider gibt es diese Dinger zu tausenden, nur nirgends ist ein Anschlussplan zu finden. Welcher Anschluss muss denn an welchen Pin auf dem Arduino-Board?
RS485 ist ein Halbduplex-Bus, das heißt, die Daten können immer nur in eine Richtung geschickt werden und die Datenrichtung muß an jedem RS485-Wandler eingestellt werden. Außerdem muß die Software garantieren, daß nicht 2 Wandler gleichzeitig senden. RS485 braucht nur 2 Leitungen, darauf ist das Signal immer „gegenphasig“.
RS485 Module
Die nicht invertierte Leitung wird meist mit B oder + oder P (positiv) gekennzeichnet, die invertierte mit A, − oder N. Es werden immer Anschluss „A“ mit Anschluss „A“ verbunden (und B mit B).
Es können 2 oder mehrere Module miteinander kommunizieren (32 oder mehr Teilnehmehmer sind möglich).
Das Netzwerk braucht Abschlusswiderstände (120 Ohm), diese sind auf den Boards (meist) bereits verbaut. Werden mehrere Module zu einem Neztwerk verbunden, müssen eventuell diese Widerstände (R7) von den Boards entfernt werden – bis auf zwei.
Die Kabellänge darf bis zu 1200 Meter betragen (4000 ft). Es werden Übertragungsraten von bis zu 10 MBit/s unterstützt (aber nur mit kurzen Leitungen). Sterntopologien sind nicht vorgesehen, üblich ist der Aufbau in Kettenform (Daisy Chain). Siehe auch Wikipedia.
Das Verbindugskabel (2polig) sollte im Idealfall Twisted Pair sein (diese hat 120 Ohm – deshalb auch der Abschlusswiderstand mit diesem Wert).
RS485 Praxis
arduino-info: RS485-Modules
Nick Gammon: RS485 mit Arduino und LTC1480
DMX ist ebenfalls RS485
Danke für die schnelle Antwort! Im Link ist genau das beschrieben, was ich sehen wollte!
Hi
Gammon Forum : Electronics : Microprocessors : RS485 communications
Dort ist auch der Anschluss an den Arduino gezeigt - dort siehst Du auch, daß die Pins DE und /RE zusammen gefasst werden, bei HIGH ist DE aktiv, bei LOW /RE (das / symbolisiert eine Negation, also LOW-Aktiv).
Bei HIGH Senden, bei LOW Lesen (das RE heißt ReadEnable, beim D hab ich's vergessen).
DI = Data IN, RO = Read Out.
MfG
... ok, der gleiche Link ...
PS: Wenn Du damit einen Bus aufbauen willst (also nicht eine RS485-Kommunikation belauschen willst), schaue Dir auch Mal CAN an - da ist direkt Empfangs-Kontrolle und Daten-Prüfung integriert, spart jede Menge selber Tippen.
Edit
DU -> Du
Hallo,
jetzt melde ich mich doch nochmal mit einem kleinen Problem:
Ich habe zwei Geräte am RS485, der Master sendet ein Byte, der Slave soll es verarbeiten und zurücksenden (ähnlich dem Beispiel in obigem Link). Ich sende z.B. nur ein Zeichen (oder drücke auch nur Enter), aber der Slaver registriert vier mal was am Eingang (auch wenn dies dann oft 0 ist). Die Baudraten stimmen aber überein. Kann es irgendein Umwandlungsproblem Dez -> Binär oder umgekehrt sein? Ein Gerät ist ein Arduino Mega 2560, das andere ein Controllino, vielleicht gibt es auch hier irgendein Kompatibilitätsproblem, wobei wenn zufällig das richtige am Slave ankommt macht er schon, was er soll. Nur die Rückgabe an den Master ist irgendwie wirr ...
Hi
Zeig die aktuellen SKetche.
Verwendest Du .rpintLN?
Das würde Dir 10/13 (oder Eines davon) an die Daten anhängen - wären zumindest schon Mal ein oder zwei der unerklärlichen Zeichen.
Solange Keiner weiß, Was gesendet wird, ist's schwer zu erkennen, ob man richtig mitgeschnitten hat.
Auch hat RS485 selber keinerlei Kontrolle/Korrektur, Darum muß man sich selber kümmern.
Wie geschrieben - wenn's was Eigenes werden soll, wirf einen Blick auf CAN, 8 Byte Nutzlast aber es wird nicht der Empfänger adressiert, sondern die ID ist eindeutig einem der Sender zuzuordnen (jeder Sender kann mehrere IDs benutzen, aber Die gibt's eben nur 1x im Netzwerk).
Für den Arduino ist Es völlig egal, ob Du den Wert als HEX, Dezimal oder Binär einträgst - für den Arduino sind Das 8 Bit - Dem ist sogar egal, ob Das gesetzte MSB 128 oder -128 aus der Zahl macht.
Wenn Du mit .print eine Zahl versendest, wird Diese zu Zahlzeichen, also Deren Ziffern, umgewandelt!
Also .print(10); -> 0x31 0x30 (1 0)
Vll. ist Das auch der Grund, warum Du mehr empfängst, als Du eigentlich abschicken wolltest.
MfG
Sorry, dass ich erst jetzt antworte, ich habe zwischendrin ein Touch-Display programmiert, was auch schon recht gut funktioniert.
Hier der erste Sketch:
/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX 10 //Serial Receive pin
#define SSerialTX 11 //Serial Transmit pin
#define SSerialTxControl 12 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
#define Pin13LED 13
/*-----( Declare objects )-----*/
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
/*-----( Declare Variables )-----*/
int byteReceived;
int byteSend;
void setup() /****** SETUP: RUNS ONCE ******/
{
// Start the built-in serial port, probably to Serial Monitor
Serial.begin(9600);
Serial.println("YourDuino.com SoftwareSerial remote loop example");
Serial.println("Use Serial Monitor, type in upper window, ENTER");
pinMode(Pin13LED, OUTPUT);
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver
// Start the software serial port, to another device
RS485Serial.begin(9600); // set the data rate
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
digitalWrite(Pin13LED, HIGH); // Show activity
if (Serial.available())
{
byteReceived = Serial.read();
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
RS485Serial.print(11, DEC); // Send byte to Remote Arduino
digitalWrite(Pin13LED, LOW); // Show activity
delay(5);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
}
if (RS485Serial.available()) //Look for data from other Arduino
{
digitalWrite(Pin13LED, HIGH); // Show activity
byteReceived = RS485Serial.read(); // Read received byte
Serial.print(byteReceived, BIN); // Show on Serial Monitor
delay(5);
digitalWrite(Pin13LED, LOW); // Show activity
}
}//--(end main loop )---
Und hier der zweite:
#include <SPI.h>
#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
/*
CONTROLLINO - Demonstration of RS485 interface usage, Version 02.00
Compatible with CONTROLLINO MAXI and MEGA.
IMPORTANT INFORMATION!
Please, select proper target board in Tools->Board->Controllino MAXI/MEGA before Upload to your CONTROLLINO.
(Refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)
This example sketch requires external 12V or 24V power supply for your CONTROLLINO and RS485 communication partner device (e.g. RS485-USB converter and PC).
Created 12 Jan 2017, Updated 20.09.2018
by Lukas
https://controllino.biz/
(Check https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library for the latest CONTROLLINO related software stuff.)
*/
const int LED = 2;
const int LED2 = 3;
int incomingByte = 0; // for incoming serial data
void setup() {
pinMode(LED, OUTPUT);
pinMode(LED2, OUTPUT);
/* Initialize serial port for debug messages. */
Serial.begin(9600);
/* Initialize CONTROLLINO RS485 direction control DE/RE pins and Serial3 */
Controllino_RS485Init(9600);
Controllino_RS485RxEnable();
Serial.println("Recieving RS485...");
}
void loop() {
// send data only when you receive data:
if (Serial3.available() > 0)
{
// read the incoming byte from RS485
incomingByte = Serial3.read();
// say what you got:
Serial.print("I received (DEC): ");
Serial.println(incomingByte, DEC);
// and send it back to RS485
Controllino_RS485TxEnable();
Serial3.print(incomingByte);
Serial3.flush(); // wait until the trasmission is complete
Controllino_RS485RxEnable();
}
if (incomingByte == 254)
digitalWrite (LED, HIGH);
else
digitalWrite (LED,LOW);
if (incomingByte == 25)
digitalWrite (LED2, HIGH);
else
digitalWrite (LED2,LOW);
}
Sicherlich ist nicht optimal, dass ich zwei verschiedene Libraries nehme (SoftwareSerial und SPI.h), aber ich kenne die interne Belegung des RS485 im Controllino nicht, daher das mitgelieferte Beispiel. Die gesendete Zahl gibt im Controllino "254" aus, somit steuert auch die LED an. Hab aber keine Ahnung, warum, auch die Zahl 12 brachte 254 raus.