Modbus via Controllino

Hallo Freunde,

und zwar habe ich eine Frage zur Modbus Kommunikation. Ich habe einen Sensor ( OLS20-BB1118142 | Lokalisierungs- und Positionierlösungen | SICK ), welcher Modbus fähig ist und einen Controllino ( CONTROLLINO MAXI – CONTROLLINO ). Ich habe vor dem Controllino als Master zu nutzen und habe daher schon folgenden Code drauf geladen:

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h" /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */

// This MACRO defines Modbus master address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!

#define MasterModbusAdd 0
#define SlaveModbusAdd 10

// This MACRO defines number of the comport that is used for RS 485 interface.
// For MAXI and MEGA RS485 is reserved UART Serial3.
#define RS485Serial 3

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch - RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);

// This uint16 array specified internal registers in the Modbus slave device.
// Each Modbus device has particular internal registers that are available for the Modbus master.
// In this example sketch internal registers are defined as follows:
// (ModbusSlaveRegisters 0 - 3 read only and ModbusSlaveRegisters 4 - 7 write only from the Master perspective):
// ModbusSlaveRegisters[0] - Read an analog value from the CONTROLLINO_A0 - returns value in the range from 0 to 1023.
// ModbusSlaveRegisters[1] - Read an digital value from the CONTROLLINO_D0 - returns only the value 0 or 1.
// ModbusSlaveRegisters[2] - Read the number of incoming messages - Communication diagnostic.
// ModbusSlaveRegisters[3] - Read the number of number of outcoming messages - Communication diagnostic.
// ModbusSlaveRegisters[4] - Sets the Relay output CONTROLLINO_R0 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[5] - Sets the Relay output CONTROLLINO_R1 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[6] - Sets the Relay output CONTROLLINO_R2 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[7] - Sets the Relay output CONTROLLINO_R3 - only the value 0 or 1 is accepted.
uint16_t ModbusSlaveRegisters[8];

// This is an structe which contains a query to an slave device
modbus_t ModbusQuery[2];

uint8_t myState; // machine state
uint8_t currentQuery; // pointer to message query

unsigned long WaitingTime;

void setup() {
 // initialize serial communication at 9600 bits per second:
 Serial.begin(9600);
 Serial.println("-----------------------------------------");
 Serial.println("CONTROLLINO Modbus RTU Master Test Sketch");
 Serial.println("-----------------------------------------");
 Serial.println("");
 // ModbusQuery 0: read registers
 ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[0].u8fct = 3; // function code (this one is registers read)
 ModbusQuery[0].u16RegAdd = 0; // start address in slave
 ModbusQuery[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
 ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO

 // ModbusQuery 1: write a single register
 ModbusQuery[1].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[1].u8fct = 6; // function code (this one is write a single register)
 ModbusQuery[1].u16RegAdd = 4; // start address in slave
 ModbusQuery[1].u16CoilsNo = 1; // number of elements (coils or registers) to write
 ModbusQuery[1].au16reg = ModbusSlaveRegisters+4; // pointer to a memory array in the CONTROLLINO
 ModbusSlaveRegisters[4] = 1; // initial value for the relays 
 
 ControllinoModbusMaster.begin( 9600 ); // baud-rate at 19200; jetzt 9600 
 ControllinoModbusMaster.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
 
 WaitingTime = millis() + 1000;
 myState = 0;
 currentQuery = 0; 
}

void loop() {
 switch( myState ) {
 case 0: 
 if (millis() > WaitingTime) myState++; // wait state
 break;
 case 1: 
 Serial.print("---- Sending query ");
 Serial.print(currentQuery);
 Serial.println(" -------------");
 ControllinoModbusMaster.query( ModbusQuery[currentQuery] ); // send query (only once)
 myState++;
 currentQuery++;
 if (currentQuery == 2) 
 {
 currentQuery = 0;
 }
 break;
 case 2:
 ControllinoModbusMaster.poll(); // check incoming messages
 if (ControllinoModbusMaster.getState() == COM_IDLE) 
 {
 // response from the slave was received
 myState = 0;
 WaitingTime = millis() + 1000; 
 // debug printout
 if (currentQuery == 0)
 {
 // registers write was proceed
 Serial.println("---------- WRITE RESPONSE RECEIVED ----");
 Serial.println("");
 }
 if (currentQuery == 1)
 {
 // registers read was proceed
 Serial.println("---------- READ RESPONSE RECEIVED ----");
 Serial.print("Slave ");
 Serial.print(SlaveModbusAdd, DEC); 
 Serial.print(" ADC0: 0x");
 Serial.print(ModbusSlaveRegisters[0], HEX);
 Serial.print(" , Digital0: ");
 Serial.print(ModbusSlaveRegisters[1], BIN);
 Serial.print(" , ModbusCounterIn: ");
 Serial.print(ModbusSlaveRegisters[2], DEC);
 Serial.print(" , ModbusCounterOut: ");
 Serial.println(ModbusSlaveRegisters[3], DEC);
 Serial.println("-------------------------------------");
 Serial.println("");

 // toggle with the relays
 ModbusQuery[1].u16RegAdd++;
 if (ModbusQuery[1].u16RegAdd == 8)
 {
 ModbusQuery[1].u16RegAdd = 4;
 if (ModbusSlaveRegisters[4]) 
 {
 ModbusSlaveRegisters[4] = 0;
 }
 else 
 {
 ModbusSlaveRegisters[4] = 1;
 }
 }
 }
 }
 break;
 }
}

Jetzt würde ich gerne fragen, ob sich jemand mit dem Thema etwas besser auskennt als ich, da ich leider noch recht neu in diesem Thema bin.
Das was ich bisher weiss ist, dass mein Sensor die Baudrate 9600 und die Slaveadresse 10 besitzt ( Im Code, so weit ich weiss, angepasst)
Weiterhin weiss ich, dass der Master ein Request schicken muss, damit der Slave darauf antworten kann.
Die Statusabfrage in HEX, ob der Sensor etwas erkennt order nicht, wäre in dem Fall:
0A 04 00 C0 00 01 30 8D
dabei steht 0A für die Slave adresse, 04 ist mein Function Code, 00C0 ist meine Startadresse, 0001 meine Registeranzahl und die 308D ist dabei meine Checksumme.

Wenn der sensor was erkennt ( OK ), gibt der die Anwort: 0A 04 02 00 02 9D 30 und bei NOK wäre es 0A 04 02 00 00 10 F1.

weiss einer vieleicht wie ich den oberen Code verändern muss um eine Kommunikation herzustellen?
ich habe auch versucht hier alles einzutragen aber es ändert sich leider nichts.

// ModbusQuery 0: read registers
 ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[0].u8fct = 3; // function code (this one is registers read)
 ModbusQuery[0].u16RegAdd = 0; // start address in slave
 ModbusQuery[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
 ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO

ordr brauche ich einen einfachen if - else Befehl? Ich wäre sehr dankbar, wenn mir einer dabei helfen könnte :smiley:

Vielen Dank schonmal und Gruß
Aram

schon mal hier nachgelesen?

vgs

1 Like

hey,
danke dir aufjedenfall schonmal für den Link. Der Code der da steht ist aufjedenfall schonmal einfacher um damit anzufangen. Ich habe da auch schon alles gegebene, in DEC, eingetragen, bekomme aber leider nichts raus.

#include <SPI.h>
#include <Controllino.h>



/**
 *  Modbus master example 1:
 *  The purpose of this example is to query an array of data
 *  from an external Modbus slave device. 
 *  The link media can be USB or RS232.
 *
 *  Recommended Modbus slave: 
 *  diagslave http://www.modbusdriver.com/diagslave.html
 *
 *  In a Linux box, run 
 *  "./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1"
 *   This is:
 *    serial port /dev/ttyUSB0 at 19200 baud 8N1
 *    RTU mode and address @1
 */

#include <ModbusRtu.h>


// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;

/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  port : serial port
 *  u8txenpin : 0 for RS-232 and USB-FTDI 
 *               or any pin number > 1 for RS-485
 */
Modbus master(0,Serial,0); // this is master and RS-232 or USB-FTDI

/**
 * This is an structe which contains a query to an slave device
 */
modbus_t telegram;

unsigned long u32wait;

void setup() {
  Serial.begin( 19200 ); // baud-rate at 19200
  master.start();
  master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
  u32wait = millis() + 1000;
  u8state = 0; 
}

void loop() {
  switch( u8state ) {
  case 0: 
    if (millis() > u32wait) u8state++; // wait state
    break;
  case 1: 
    telegram.u8id = 10; // slave address
    telegram.u8fct = 4; // function code (this one is registers read)
    telegram.u16RegAdd = 192; // start address in slave
    telegram.u16CoilsNo = 1; // number of elements (coils or registers) to read
    telegram.au16reg = au16data; // pointer to a memory array in the Arduino

    master.query( telegram ); // send query (only once)
    u8state++;
    break;
  case 2:
    master.poll(); // check incoming messages
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 100; 
    }
    break;
  }
}

was ich verändert habe ist nur folgender Teil:

    telegram.u8id = 10; // slave address
    telegram.u8fct = 4; // function code (this one is registers read)
    telegram.u16RegAdd = 192; // start address in slave
    telegram.u16CoilsNo = 1; // number of elements (coils or registers) to read

und ich habe noch die Controllio Bibliothek eingefügt.

Bekomme aber halt immmer nur folgende Ausgabe:

ich habe auch schon die Baudrate auf 9600 gestellt, da mein Sensor so eingestellt ist, aber leider ändert sich da nichts.

ich sehe das gerade und denke dass es wahrscheinlich daran liegt, da meine Geräte eine RS485 Verbindung haben

also diese GiPo habe ich über quoogeln mit dem library-namen gefunden

GitHub ModbusRtu.h

Ich habe Modbus schon mal gehört aber noch nie etwas damit gemacht.
Also sich einlesen:
Wikipedia Zitat:

Modbus RTU (RTU: Remote Terminal Unit, entfernte Terminaleinheit) überträgt die Daten in binärer Form. Dies sorgt für einen guten Datendurchsatz, allerdings können die Daten nicht direkt vom Menschen ausgewertet werden, sondern müssen zuvor in ein lesbares Format umgesetzt werden.

Das könnte erklären warum da im serial monitor nur kauderwelsch steht.

RS-485 ist ein bestimmter Standard wie elektrische Signale übertragen werden.
Da geht es nur um wie werden die Nullen / Einsen elektrisch übertragen.
Da kommt noch nicht einmal eine baudrate darin vor. Diese Definition ist sozusagen unterhalb der Baudrate.

Im Gegensatz zu anderen Bussen sind bei EIA-485 nur die elektrischen Schnittstellenbedingungen definiert. Das Protokoll kann anwendungsspezifisch gewählt werden.

Daran liegt es also nicht.

Wenn die Gesamtanwendung nicht funktioniert. Zurück zu gaaanz elementaren Testprogrammen.

Und wahrscheinlich wäre auch so ein 24 MHz 8 channel Logic-analyzer nützlich der das Spannungspegel rauf/runter-Gehüpfe aufzeichnet und dann die Interpretation was das je nach Protokoll zu bedeuten hätte durchführt.

Dafür gibt es eine Freeware namens SigRok PulseView
https://sigrok.org/wiki/Downloads
die kann eine Menge Protokolle analysieren. Auch Modbus RTU

Aber vielleicht fragst du als erstes mal bei Sick nach ob die nicht ein Testprogramm haben. Sick ist ja ein namhafter Hersteller für Profi-equipment.
vgs

2 Likes

ja daran könnte es liegen. Ich hätte gedacht, dass der Code die Übersetzung übernimmt und direkt in lesbare Infos umwandelt.

Den Sensor an sich habe ich schon getestet bzw. habe schon mit ihm gearbeitet, weiß daher nicht ob der logic-analyzer nötig ist. Ich habe den Sensor mit Hilfe eines Adapters an meinen PC angeschlossen und über eine Software mit dem Gerät gearbeitet. Mit den richtigen Voreinstellung (Baudrate, Parität, …) kann man noch die Slaveadresse, Funktions-Code usw., eintragen und das abfragen was man sucht und bekommt dann die entsprechende Antwort.

Das was im Bild eingetragen ist sind die Daten für die Statusabfrage. Daher dachte ich, dass ich diese Daten auch direkt in mein Code eintragen kann und das selbe bzw. ein ähnliches Ergebnis erwarten kann.

Da habe ich schon angefragt. Also die konnten mir noch so einen extra Gerät anbieten den ich dann an meinem Sensor anschließe. Damit kann ich dann halt über ne SICK Software die Einstellung wie zb die Slave Adresse ändern aber der würde mir halt, laut eigenen Aussagen, nicht bei meinem Problem helfen.
Danke dir aufjedenfall für deine Hilfe.

in deinem Programm stehr s
Serial.begin(9600)
aber im seroellen Monitor hast du 19200 baud eingestellt.
das muss übereinstimmen.

Du hast die serielle Verbingung per USB-Kabel zum PC Das ist die Verbindung Serial

Und dann hast du die Verbindung Controllino zum Sick. Die hat ihre eigene Baudrate
vgs

ja das lag daran, dass ich es einmal mit 19200 und einmal mit 9600 probiert habe. Also ich hab das dann im Code und Monitor angepasst, sorry falls das für Verwirrung gesorgt hat :smiley: . Aber haben leider beide nicht funktioniert.

und bei dem Code den ich ganz oben gepostet habe bekomme ich eine lesbares Ergebnis, aber auch nach Anpassungen steht da halt immer das selbe und ich weiß daher nicht, ob die beiden Geräte miteinander kommunizieren.

der angepasste Code:

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h" /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */

// This MACRO defines Modbus master address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!

#define MasterModbusAdd 0
#define SlaveModbusAdd 10

// This MACRO defines number of the comport that is used for RS 485 interface.
// For MAXI and MEGA RS485 is reserved UART Serial3.
#define RS485Serial 3

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch - RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);

// This uint16 array specified internal registers in the Modbus slave device.
// Each Modbus device has particular internal registers that are available for the Modbus master.
// In this example sketch internal registers are defined as follows:
// (ModbusSlaveRegisters 0 - 3 read only and ModbusSlaveRegisters 4 - 7 write only from the Master perspective):
// ModbusSlaveRegisters[0] - Read an analog value from the CONTROLLINO_A0 - returns value in the range from 0 to 1023.
// ModbusSlaveRegisters[1] - Read an digital value from the CONTROLLINO_D0 - returns only the value 0 or 1.
// ModbusSlaveRegisters[2] - Read the number of incoming messages - Communication diagnostic.
// ModbusSlaveRegisters[3] - Read the number of number of outcoming messages - Communication diagnostic.
// ModbusSlaveRegisters[4] - Sets the Relay output CONTROLLINO_R0 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[5] - Sets the Relay output CONTROLLINO_R1 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[6] - Sets the Relay output CONTROLLINO_R2 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[7] - Sets the Relay output CONTROLLINO_R3 - only the value 0 or 1 is accepted.
uint16_t ModbusSlaveRegisters[8];

// This is an structe which contains a query to an slave device
modbus_t ModbusQuery[2];

uint8_t myState; // machine state
uint8_t currentQuery; // pointer to message query

unsigned long WaitingTime;

void setup() {
 // initialize serial communication at 9600 bits per second:
 Serial.begin(9600);
 Serial.println("-----------------------------------------");
 Serial.println("CONTROLLINO Modbus RTU Master Test Sketch");
 Serial.println("-----------------------------------------");
 Serial.println("");
 // ModbusQuery 0: read registers
 ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[0].u8fct = 4; // function code (this one is registers read)
 ModbusQuery[0].u16RegAdd = 192; // start address in slave
 ModbusQuery[0].u16CoilsNo = 1; // number of elements (coils or registers) to read
 ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO

 // ModbusQuery 1: write a single register
 ModbusQuery[1].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[1].u8fct = 6; // function code (this one is write a single register)
 ModbusQuery[1].u16RegAdd = 4; // start address in slave
 ModbusQuery[1].u16CoilsNo = 1; // number of elements (coils or registers) to write
 ModbusQuery[1].au16reg = ModbusSlaveRegisters+4; // pointer to a memory array in the CONTROLLINO
 ModbusSlaveRegisters[4] = 1; // initial value for the relays 
 
 ControllinoModbusMaster.begin( 9600 ); // baud-rate at 19200
 ControllinoModbusMaster.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
 
 WaitingTime = millis() + 1000;
 myState = 0;
 currentQuery = 0; 
}

void loop() {
 switch( myState ) {
 case 0: 
 if (millis() > WaitingTime) myState++; // wait state
 break;
 case 1: 
 Serial.print("---- Sending query ");
 Serial.print(currentQuery);
 Serial.println(" -------------");
 ControllinoModbusMaster.query( ModbusQuery[currentQuery] ); // send query (only once)
 myState++;
 currentQuery++;
 if (currentQuery == 2) 
 {
 currentQuery = 0;
 }
 break;
 case 2:
 ControllinoModbusMaster.poll(); // check incoming messages
 if (ControllinoModbusMaster.getState() == COM_IDLE) 
 {
 // response from the slave was received
 myState = 0;
 WaitingTime = millis() + 1000; 
 // debug printout
 if (currentQuery == 0)
 {
 // registers write was proceed
 Serial.println("---------- WRITE RESPONSE RECEIVED ----");
 Serial.println("");
 }
 if (currentQuery == 1)
 {
 // registers read was proceed
 Serial.println("---------- READ RESPONSE RECEIVED ----");
 Serial.print("Slave ");
 Serial.print(SlaveModbusAdd, DEC); 
 Serial.print(" ADC0: 0x");
 Serial.print(ModbusSlaveRegisters[0], HEX);
 Serial.print(" , Digital0: ");
 Serial.print(ModbusSlaveRegisters[1], BIN);
 Serial.print(" , ModbusCounterIn: ");
 Serial.print(ModbusSlaveRegisters[2], DEC);
 Serial.print(" , ModbusCounterOut: ");
 Serial.println(ModbusSlaveRegisters[3], DEC);
 Serial.println("-------------------------------------");
 Serial.println("");

 // toggle with the relays
 ModbusQuery[1].u16RegAdd++;
 if (ModbusQuery[1].u16RegAdd == 8)
 {
 ModbusQuery[1].u16RegAdd = 4;
 if (ModbusSlaveRegisters[4]) 
 {
 ModbusSlaveRegisters[4] = 0;
 }
 else 
 {
 ModbusSlaveRegisters[4] = 1;
 }
 }
 }
 }
 break;
 }
}

also wenn du das PC-Testprogramm mit dem Sick-Teil ansprichst dann kommt eine Antwort.

Hast du einen zweiten USB-Seriell-Adapter?
Wenn ja hat der die gleichen TTL-Spannungspegel wie der erste USB-Seriell-Adapter?

Wenn ja den zweiten USB-Seriell-adapter so anschliessen, dass der Rx-Anschluss mit dem Tx-Anschluss des Computers verbunden ist und sich dann ausgeben lassen was für bytewerte sendet denn der Computer per Testprogramm an das Sick-Teil?

Dann Arduino mit dem Sick verbinden
Und dann den Rx-Anschluss des zweiten USB-seriell-Adapter an den Arduino-Tx-Anschluss anschließen und dort mitlesen was der Arduino sendet.

Wenn du keinen zweiten Wandler hast dann wenigstens den einen parallel zum Arduino anschliessen.
andere "Serial-Monitor"-Programme können die empfangen Zeichen auch hexadecimal anzeigen lassen. Das scheint mir in diesem Fall günstiger zu sein.
Ich benutze dafür br@ys terminal weil es auto-connect/Disconnect mit Fenster im Vorderrund/Hintergrund kann

es gibt aber noch jede Menge andere serielle terminal Programme.

1 Like

hab leider keinen zweiten Adapter, hab es daher mit dem Terminal probiert. Dort bekomme ich aber leider auch nichts vernünftiges angezeigt.
Ich habe das Gefühl dass der Controllino nicht "merkt" dass ein Gerät angeschlossen ist. Wenn ich die Slaveadresse etc. ändere bekomme ich zwar weiterhin nur komische Zeichen raus aber halt andere. Wenn ich den Sensor aber abschalte bekomm ich die selben Zeichen. Kann es sein dass der Controllino den Sensor nicht erfasst? Wenn ja, woran liegt das? Man muss den Sensor eigentlich nur mit 2 Drähten an die RS485 Eingänge vom Controllino anschließen, also viel zum verkabeln gibt es nicht wirklich. Und mit der selben Verkabelung funktioniert es ja auch am PC

Jetzt müssen wir erst einmal präzise klären was du mit

meinst.

Kannst du mal die genaue Typenbezeichnung oder wenigstens ein Foto von dem Gerät posten das du zusammen mit dem PC-Testprogramm benutzt?

Dann kann ich mir anschauen mit was für Spannungspegeln dieses Gerätchen arbeitet und dann sehen ob man dieses Gerätchen zum "mithören" der Kommunikation zwischen Arduino und dem Sick-OLS-Sensor ich nenne ihn jetzt der Einfachheit halber "Sickol" .

In deinem PC-Testprpgramm wird durch ganz genau angezeigt was da für bytes gesendet und empfangen werden
image

Kannst du mir mal auflisten was du an seriellen Kommunikationsgeräten zu Hause hast?

also welche und wie viele TTL-RS485-module
wie viele und welche Microcontroller
wie viele und welche USB-seriell Wandler

Du scheinst in größeren Zeitabständen an dem Projekt zu arbeiten
Dann könntest du doch tatsächlich mal einen RS232 / TTL-Wandler

Einen RS485 zu TTL-wandler
https://www.makershop.de/module/kommunikation-module/ttl-rs485-adapter/

und einen TTL nach USB-Interface bestellen.
https://www.makershop.de/module/kommunikation-module/micro-usb-uart-ttl/

Der Controllino Maxi hat einen Atmel Atmega 2560-microcontroller der hat drei serielle hardware-Schnittstellen.
1x RS485 und 2x TTL. Dann kann man auch eine TTL-Schnittstelle zum "mithören" benutzen.

Dazu muss man aber klären was du für RS485-module du genau hast und ob man da an die TTL-pegel drankommt.

vgs

1 Like

naja egal ob ich das Gerät angeschlossen habe oder nicht, der serielle Monitor zeigt immer das selbe an.

Also zusammengefasst, womit ich arbeite:

Sensor: OLS20-BB1114142 | Lokalisierungs- und Positionierlösungen | SICK
OLS20, 8023751 (sick.com)

Controllino: CONTROLLINO MAXI - Controllino Shop
CONTROLLINO-Bedienungsanleitung-V1.2-2018-04-23.pdf (controllinoshop.eu)

Adapter: DIGITUS USB auf Seriell Adapter - RS485 Konverter - USB 2.0 Typ-A zu DSUB 9M - FTDI FT232RL Chipsatz - Inkl. 80 cm Kabel: Amazon.de: Computer & Zubehör

Software: QModMaster download | SourceForge.net

hab leider nichts ausser die Geräte oben, einen Arduino Uno und Kleinigkeiten aus nem Eleggo Uno Starter Kit ( ELEGOO UNO R3 Ultimate Starter Kit, Kompatibel mit Arduino IDE Vollständigster Elektronik Projekt Baukasten mit deutschem Tutorial, UNO R3 Mikrocontroller Board und Zubehör: Amazon.de: Computer & Zubehör )

Ja ist ein etwas größeres Projekt, bestehend aus mehreren Sensoren. Ich wollt den Controllino als Steuereinheit für alles nutzen aber naja...dauert anscheind nocht etwas :smiley:

hlefen die Geräte beim mithören? und was glaubst du woran es liegen könnte dass da nichts bei raus kommt?

Und Danke dir vielmals für deine Hilfe.

So habe mir jetzt noch einmal den Sketch angeschaut

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch - RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);

In der Beschreibung steht das der erste Parameter die Adresse des slaves sein muss
Du hast da MasterModbusAdd eingetragen (= Adressnummer 0)
Probiere mal aus ob es funktioniert wenn du da SlaveModbusAdd (also die Zahl 10) einträgst.

vgs

// This MACRO defines Modbus master address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!

#define SlaveModbusAdd 10
#define MasterModbusAdd 0

meinst du also einfach so vertauscht?

Nein
statt

Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);
Modbus ControllinoModbusMaster(SlaveModbusAdd, RS485Serial, 0);

Ich habe inzwischen noch mehr nachgelesen. Ein Versuch kann nicht schaden. Ist ja nur Byteübertragung.

Mit dem Digitus USB auf seriell zusammen mit dem RS485-konverter kann man unter einer Bedingung mithören wenn der Controllino mit dem Sickol kommuniziert:

RS485 hat an beiden Enden einen "Abschlusswiderstand von 120 Ohm.
Wenn man jetzt ein "Standard"-RS485-Gerät mit anschliesst und dieses Standardgerät hat auch einen Abschlusswiderstand dann ist der Gesamtwiderstand zu klein.

Ob da ein Abschlusswiderstand drauf ist bzw. ob man den auch abschalten kann ist auf dem Amazon-Foto nicht zu sehen.
Gibt es da eine Bedienungsanleitung dazu?
vgs

Wenn ich das richtig verstehe dann hast du diesen Typ hier
Artikelnummer: 8023751

Titel: OLS20 Spurführungssensoren

Ich habe jetzt in der Bedienungsanleitung nachgelesen:
Beim OLS20 muss eine korrekte slave address eingestellt sein.
Korrekt ist:
°
Eine slave address, die im Modbus-Netzwerk frei ist
°
Eine slave address, die der Master erwartet
• Beim OLS20 muss dieselbe Baudrate wie beim Master eingestellt sein.
Werksseitig sind beim OLS20 folgende Parameter eingestellt:
• Slave address: 10 (Einstellmöglichkeit 1 ... 247)
• Baudrate: 9600 bps

sowie
Die slave address und die Baudrate können alternativ über die Kommunikationssoft‐
ware SOPAS ET eingestellt werden.
Diese steht hier zum download bereit: www.sick.com/SOPAS.
SOPAS Engineering Tool (Portable-Version) | SICK

Da braucht man dann aber noch eine SDD-Datei (Gerätebeschreibungsdatei)
Das scheint mir diese hier zu sein

Da bin ich mir aber nicht sicher. Im Zweifelsfall würde ich den Sick-Support anrufen und die Bitten sie sollend ich durch alle Schritte wie man die Software und die SSD-Datei installiert durchführen. Der Sensor hat ja schließlich ordentlich Geld gekostet.

vgs

1 Like

hab ich auch shon probiert, leider nicht funktioniert.

hab leider keine, sorry.

genau den habe ich, und das mit der voreingestellten slave adresse und baudrate stimmt. Ich musste diese einstellungen auch in der Qmodmaster Software einstellen, damit ich den Sensor ansprechen kann. Mit der Software hatte ich auch keine Probleme dort hat alles funktioniert. Nur der Controllino macht Schwierigkeiten und will nicht so ganz. Egal welchen Code ich benutze und was ich einstelle, es funktioniert leider nicht.

die Software besitze ich schon und kann einen anderen Sensor darüber einrichten. Um den OLS20 aber mit der Software zu verbinden bräuchte ich noch n extra Gerät, müsste diesen aber bestellen. Ich hab mit dem SICK Support Team auch schon gesprochen. Diese meinte dass die Software bei meinem Problem alt nicht viel hilft, da ich dort die Slaveadresse z.B. ändern kann, das aber ja anscheinend nicht mein Problem ist. Mit der voreingestellten Slaveadresse müsste die Kommunikation auch möglich sein.

Und in der Software habe ich noch folgende Einstellungen, neben Slaveadresse und Baudrate, unternommen:

image

Erst mit diesen Einstellungen, konnte der Sensor mit der Software kommunizieren. Kann es sein dass ich meinen Code da noch umschreiben oder die Arduino IDE dementsprechend verändern muss? Denn die Standardeinstellung ist ja =8 Datenbits, no parity, 1 Stoppbit. Kann ich die Parität ändern?
Das wäre ne Erklärung, wieso der nicht mit dem Sensor kommuniziert.

Ja sicher das geht.

vgs

1 Like