Do you know EIA-485 and DMX-512? Part 1

In den 1980-er und 1990-er Jahren war ein wiederkehrendes Thema in den Computerzeitschriften die Frage, ob für die externe Datenübertragung die serielle Schnittstelle oder die parallele Schnittstelle besser geeignet sei. Die serielle oder RS232 Schnittstelle (UART= Universal Asynchronous Receiver Transmitter) am PC wurde vorwiegend für die Datenfernübertragung mit Modems (anfänglich im Fernschreibnetz) verwendet, die parallele Centronics-Schnittstelle lieferte Daten an den Drucker.

Sie kennen das Ergebnis des Wettlaufs um höhere Geschwindigkeiten: Prozessor-intern und auf dem Mainboard ist die Breite der Datenbusse immer größer geworden, extern ist die parallele Schnittstelle von USB (=Universal Serial Bus) und den Netzwerken verdrängt worden. Aber auch die RS-232-Schnittstelle ist weitestgehend verschwunden, weil sie einige erhebliche Schwächen aufwies: begrenzte Reichweite und Verbindung nur zwischen genau zwei Geräten.

Als Zwischenschritt zu den heutigen Netzwerken gab es Weiterentwicklungen der seriellen Schnittstelle RS-232, die bis heute Anwendung finden: U.a. die RS-485-Schnittstelle (die Fortschreibung der Standards unter dem heutigen Namen EIA-485 belegt die Aktualität) überbrückt durch den symmetrischen Aufbau der Signale auf den zwei Leitungen größere Distanzen bis 1000m und ermöglicht die Reihenschaltung von bis zu 32 Geräten, solange die jeweils letzten Geräte einen Abschlusswiderstand besitzen. Wie so häufig gibt es bei Wikipedia sehr informative Seiten zu UART, RS-232 und EIA-485 für diejenigen, die mehr wissen wollen.

Um die RS-485-Schnittstelle zu benutzen, die auf heutigen Computern hardwareseitig nicht vorhanden ist, habe ich einen preiswerten USB-RS-485-Adapter für den PC gekauft.

RS-485 USB Adapter

Für die Mikro Controller vom Typ Arduino Uno oder kompatible sowie die bauähnlichen D1 R1 (mit ESP8266) und D1 R32 (mit ESP32) gibt es ein entsprechendes Shield, für den Raspberry Pi einen HAT (Hardware Attached on Top).

RS-485 Pi Hat

Um mich in dieses für mich neue Themengebiet einzuarbeiten, habe ich zunächst Informationen gesammelt, z.B. auf der Homepage unseres Zulieferers für das Shield bzw. den HAT: Fa. zihatec.

Von dort habe ich Datenblatt, Application Note und Beispiel-Sketche heruntergeladen. Aber weil ich das Beispiel anfänglich nicht zum Laufen bekommen habe, möchte ich einen anderen Ansatz für die Erklärung wählen:

Zunächst einmal: Was soll erreicht werden?

In diesem Einstiegsbeitrag geht es um die Realisierung eines MODBUS Slaves, da MODBUS eine der wichtigsten Anwendungen für die RS-485 ist; es handelt sich um ein offenes Protokoll und wurde in der Industrie zu einem De-facto-Standard für speicherprogrammierbare Steuerungen (SPS).

Ein MODBUS-System benötigt immer einen Master und mindestens einen Slave. Man kann mit dem Shield sowohl einen Master als auch Slaves realisieren. Allerdings ist es bei Verwendung eines Micro Controllers mit Atmel 328 nur eingeschränkt möglich, sinnvoll einen Master umzusetzen, da der RAM-Speicher sehr begrenzt ist. Aus diesem Grund wird im Beispiel ein MODBUS-Slave realisiert und als Master ein PC verwendet. 

In der Praxis wäre der Master z.B. eine SPS oder ein zentraler Steuerrechner, an den verschiedene Maschinen oder Geräte mit RS485 Interface als Slaves angeschlossen sind. Der Master kann nun sequenziell alle angeschlossenen Geräte am RS485 BUS über das MODBUS Protokoll abfragen und steuern. Die Geräte haben dazu alle verschiedene Busadressen.

Der Beispiel-Sketch sendet sechs analoge Signale und das digitale Signal eines Tasters über die RS-485-Verbindung zum PC und empfängt von dort die Information, ob eine LED an- oder ausgeschaltet sein soll.

Dazu habe ich das Shield auf den Micro Controller gesteckt sowie die folgende Schaltung mit sechs Potentiometern an den analogen Eingängen A0 bis A5, eine LED mit Vorwiderstand an dem digitalen Pin 12 und einen Taster (button) mit Pulldown-Widerstand an Pin 7 angeschlossen.

Schaltungsaufbau

Fritzing Schaltplan

Auf dem Shield sind noch einige Einstellungen vorzunehmen. Dies geschieht einerseits mit Kurzschlusssteckern (Jumper) und andererseits mit Hilfe kleiner Schalter (DIP switches, „Mäuseklavier“). Die Beschriftung der Platine ist dabei sehr hilfreich.

Für unseren Micro Controller mit Atmega 328 stecken wir den einzelnen Jumper J1 auf 5V, in der Reihe neben den Pins 0 bis 7 stecken wir die Verbindung der RX-Leitung an Port 0 und der TX-Leitung an Port 1, der dritte Jumper wird beim automatischen RX/TX switching nicht benötigt.

UART Pins

Achtung: Bei diesem Versuch benutzen wir die gleichen Pins wie für die USB-Verbindung zur Arduino IDE. Deshalb müssen entweder das gesamte Shield oder diese beiden Pins für die Dauer der Programmierung des Micro Controllers (das Hochladen des Sketches) entfernt werden. Der serielle Monitor in der IDE kann nicht verwendet werden.


Die DIP Schalter stellen Sie bitte wie auf dem folgenden Bild ein:

DIP Switches

Der wichtigste Micro-Schalter ist der erste auf SW 3: Damit wird der Abschlusswiderstand (terminating resistor) aktiviert.

Den Sketch von Hartmut Wendt habe ich minimal modifiziert, nämlich bei der Baudrate 9600 und in der void setup() mit einem kurzen LED-Test: (Download des Sketch-Ordners mit 3 Dateien):

 /*
  * Test program for Arduino RS422/RS485 Shield
  * Version 1.0
  * Copyright (C) 2018 Hartmut Wendt www.zihatec.de
  *  
  * (based on sources of https://github.com/angeloc/simplemodbusng)
  *  
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */  
 
 #include "SimpleModbusSlave.h"
 #define ledPin 12   // led
 #define buttonPin 7 // push button
 
 
 // Using the enum instruction allows for an easy method for adding and
 // removing registers. Doing it this way saves you #defining the size
 // of your slaves register array each time you want to add more registers
 // and at a glimpse informs you of your slaves register layout.
 
 //////////////// registers of your slave ///////////////////
 enum
 {    
   // just add or remove registers and your good to go...
   // The first register starts at address 0
   ADC0,    
   ADC1,        
   ADC2,
   ADC3,
   ADC4,
   ADC5,  
   LED_STATE,
   BUTTON_STATE,
   TOTAL_ERRORS,
   // leave this one
   TOTAL_REGS_SIZE
   // total number of registers for function 3 and 16 share the same register array
 };
 
 unsigned int holdingRegs[TOTAL_REGS_SIZE]; // function 3 and 16 register array
 ////////////////////////////////////////////////////////////
 
 void setup()
 {
   modbus_configure(9600, 1, 6, TOTAL_REGS_SIZE, 0);    // 115200
   pinMode(ledPin, OUTPUT);
   pinMode(buttonPin, INPUT);
 //added as a first test  
   digitalWrite(ledPin,HIGH);
   delay(1000);
   digitalWrite(ledPin,LOW);  
 }
 
 void loop()
 {
   // modbus_update() is the only method used in loop(). It returns the total error
   // count since the slave started. You don't have to use it but it's useful
   // for fault finding by the modbus master.
   holdingRegs[TOTAL_ERRORS] = modbus_update(holdingRegs);
   for (byte i = 0; i < 6; i++)
  {
     holdingRegs[i] = analogRead(i);
     delayMicroseconds(50);        
  }
   
   byte buttonState = digitalRead(buttonPin); // read button states
   
   // assign the buttonState value to the holding register
   holdingRegs[BUTTON_STATE] = buttonState;
   
   // read the LED_STATE register value and set the onboard LED high or low with function 16
   byte ledState = holdingRegs[LED_STATE];
   
   if (ledState) // set led
  {          
     digitalWrite(ledPin, HIGH);
  }  
   else if (ledState == 0) // reset led
  {
     digitalWrite(ledPin, LOW);
     holdingRegs[LED_STATE] = 0;
  }
 }

PC-seitig habe ich den USB-RS-485-Adapter in einen USB-Port gesteckt und das Programm ModbusTester installiert.

Die serielle Verbindung ist ganz einfach: zwei Kabel stellen die Verbindung der jeweiligen Anschlüsse A-A und B-B her. Bei langen Leitungen sollten die Kabel verdrillt sein und es gilt die Faustformel, Kabellänge mal Übertragungsrate sollte nicht größer sein als 100 Millionen, z.B. 50m und max. 2Mbit/s. 

Bei dem Programm Modbus Tester ist die Einstellung der gleichen Baudrate wichtig. Der verwendete virtuelle COM-Port wird unter Windows-Einstellungen angezeigt und muss im Pulldown-Menü ausgewählt werden.

Ausgabe von Werten; Auf diesem Bildschirmfoto werden nach Anklicken von Read (rechts unten) die von mir an den Potis eingestellten Werte in den Registern 1 bis 6 sowie der Zustand des Tasters in Register 8 angezeigt.

Eingabe von Befehlen: Mit Write wird der Wert des Registers 7 (hier 1) an den Micro Controller gesendet, um die LED einzuschalten. Zum Ausschalten 0 vorwählen und Write drücken.

MODBUS Tester

Dies stellt selbstverständlich nur einen ersten Test der verwendeten Geräte dar. Ernsthafte Anwendungen wie z.B. die Einbindung von Geräten auf Wasserfahrzeugen gemäß NMEA-0183 (GPS usw.) finden Sie auf der Seite von zihatec. In einem zweiten Teil möchte ich mich der Lichttechnik mit DMX zuwenden. Auch dafür verwende ich das RS-485 Shield.

Für arduinoProjekte für anfänger

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert

Aanbevolen blog berichten

  1. Installeer ESP32 nu van de raad van bestuur
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP Programmeren via Wi-Fi