Distanz ausmessen über Modbus

Hallo zusammen,

ich bin gerade dabei mit einem RS485 ultraschall Sensor eine Distanz auszumessen. Ich nutze dafür einen MAX485 und einen Arduino Uno.

Mein Code dazu lautet:

#include <SoftwareSerial.h>

// RS485 Pins
#define RS485_TX 3
#define RS485_RX 4
#define RS485_DE 2
int kontrolle = 9;
// Sensoradresse
#define SENSOR_ADDRESS 0x0100

// SoftwareSerial für RS485
SoftwareSerial rs485(RS485_RX, RS485_TX);

void setup() {
  pinMode(RS485_DE, OUTPUT);
  pinMode(kontrolle, OUTPUT);
  // Empfängermodus

  rs485.begin(14400); // Baudrate anpassen
  Serial.begin(9600); // Für Debugging
}

void loop() {
  digitalWrite(RS485_DE, HIGH); 
  digitalWrite(kontrolle, HIGH);
  while (rs485.available()) {
    rs485.read(); // Empfangspuffer leeren
  }
  sendRequest(SENSOR_ADDRESS);
  delay(1000); // Warten auf Antwort
  readResponse();
  
  delay(100); // Abfrageintervall
}

void sendRequest(uint16_t address) {
  // Protokoll anpassen
  uint8_t request[] = {
    0x01,             // Slave-ID (z. B. 1)
    0x03,             // Funktionscode (z. B. 0x03 für Lesen von Registern)
    (address >> 8),   // High Byte der Adresse
    (address & 0xFF), // Low Byte der Adresse
    0x00, 0x01,       // Anzahl der Register
    0x85, 0xF6        // CRC 
  };
  int i = 0;


  digitalWrite(RS485_DE, HIGH); // Senden
  rs485.write(request, sizeof(request));
  rs485.flush();
  digitalWrite(RS485_DE, LOW); // Empfangsmodus
}

void readResponse() {
  //delay(100);
  while (rs485.available()) {
    uint8_t byte = rs485.read();
    Serial.print(byte, HEX);
    Serial.print(" ");
  }
  digitalWrite(kontrolle, LOW);
  Serial.println();
}

Vom Sensor bekomme ich folgense zurück:
1 3 2 0 48 B8 72

An der viertel Stelle sollte anstatt einer 0 eine 2 stehen, weil sich meine Distanz aus zwei Bytes zusammensetzt.

Ich habe schon probiert, ob es an der Baudrate oder an einem zu kleinen Delay liegt. Zudem gibt mir ein Logic Analyzer genau das gleiche zurück.

Wenn jemand weiß, was ich noch probieren könnte oder woran das liegt, wäre ich sehr dankbar. :slight_smile:

Gruß Melanie

Das bedeutet: Server ID=1, Read Holding Register (FC=0x03), 2 Byte folgen. Dann kommen deine erwarteten 2 Byte (0x0048), dann noch 2 Byte CRC, die du ignorieren könntest.

Das Ding liefert also 72 zurück :wink:

Hallo,

was ist das für ein Sensor?
Gibt es ein Datenblatt dazu?
Warum bist du dir sicher das eine 2 statt 0 empfangen werden müsste, wenn der Logic Analyzer auch 0 zeigt?

dein Sensor ist ein ModBus Sensor.
Nimm dazu eine Modbus Library.
Ich würde dir die ModbusMaster von DocWalker empfehlen.

(wobei die Hinweise von @Miq1 schon korrekt sind, das dritte Byte ist die Längenangabe).

Genau so hatte ich es auch verstanden, aber durch eine Messung mit einem Zollstock welches ca 580mm ergeben hat müsste ich dann ja eigentlich 0x0248 zurück bekommen. Daher hatte ich vermutet, dass das eine Byte bei der übertragung verloren geht.

Nein, das ist meldungsmäßig stimmig. Mag sein, dass du den Sensor kalibrieren musst?

Entschuldige hatte das erst vergessen :slight_smile:

Hallo,

mich wundert das du Werte bekommst. Du nutzt die Serielle zum Sensor mit 14400 Baud. Dafür müßte das dem Sensor mittels Wert 0x04 im Register 0x0201 mitgeteilt werden. Wie machst du das? Was passiert mit Default 9600 Baud?

Danke für eure Hilfe und Inspirationen, ich habe das Problem gelöst. :slight_smile: Ich hättte das Register für "Real-time distance value " nehmen müssen.

Zu der Baudrate: ich hatte mir noch ein Programm mit dem Modbusmaster geschrieben, mit dem ich auf das Register 0x0201 schreibe und hatte dann damit die Baudrate geändert.

Hallo,

sehr schön, die eigene Lösung ist immer die Beste. :+1: :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.