Guten Tag ! Ich müsste das Gewicht einer Waage welches über eine RS-232 Schnittstelle im Sekundentakt per ASCII 5 Datenbyte und 1 Stopbyte, Screenshot vom Signal mit Hterm ist im Anhang, ausgegeben wird mittels Gateway, Konverter oder ähnliches in ein RS-485 Modbus RTU Slave umwandel das ich es mit dem vorhandenen Modbus RTU Master abfragen kann. Kennt jemand so ein Gateway bzw. Konverter der das ankommende Signal verwerten kann und es als Modbus RTU Slave zur Verfünung stellen Kann ? Danke im Voraus
Als fertiges gerät hab ich so was noch nie gesehen. Es müsste ja auch die Spezielle Kommunikation der Waage kennen. Mit Arduino sollte das in wenigen Minuten umgesetzt sein.
Hallo Lichtmensch Danke für die Antwort, da ich von Arduino kein Ahnung habe frag ich mal einfach ob Sie mir die Bauteile die ich benötigen würde nennen können, welches Board und welche Bauteile für die RS-232 und RS-485 Schnittstelle. M.f.G. Markus
https://github.com/CMB27/ModbusRTUSlave/tree/main/examples/ModbusRTUSlaveExample Zeigt einen beispielhaften Hardware-Aufbau. Dazu brauchst du noch einen RS232->TTL Wandler. Im Beispiel-Source schmeißt du die Taster- und Analgoeingänge raus, und auch die Ausgänge brauchst du nicht, sondern nur ein Register was dein Master auslesen kann. In der loop dann an der RS232 lauschen, und neue Werte in dein register speichern. Bei 9600 baud tut's auch Soft-Serial, damit eignet sich so gut wie jedes Platinchen, was sich "Arduino-Kompatibel" schimpft.. Nur aufpassen, dass die loop nicht zulange blockiert wird, also zeichenweise lesen, damit modbus.poll(); nicht verhungert...
Achte drauf das die Werte konsistent sind, also einen 2 Werte Ringpuffer verwenden z.B. Sonst wind aus zwei aufeinanderfolgenden Werten 4,99und 5,01 plötzlich 5,99.
Danke für die Antworten. Ich habe einen Mega 2560 verwendet mit einem RS232 und einem RS485 Adapter. https://www.amazon.de/dp/B07B667STP?ref=ppx_yo2ov_dt_b_fed_asin_title https://www.amazon.de/dp/B09DYDFZRW?ref=ppx_yo2ov_dt_b_fed_asin_title Die 2 Adapter habe ich auf Serial1 und Serial2 angeklemmt. Dann habe ich aus einer Modbus RTU Slave Vorlage einen Sketch mehr oder weniger zusammen gebastelt, der nun auch funktioniert, das blöde ist nur das nach ein paar Tagen die Verbindung mit dem Modbus RS485 RTU abbricht. Momentane Lösung ist, ich Kontrolliere mit der UVR610 den Modbus Eingang wenn der als defekt angezeigt wird, wird die Spannungsversorgung vom Mega 2560 kurz getrennt und dann läuft wieder alles normal. Ich gehe davon aus das der Sketch starken Optimierungsbedarf hat. Vielleicht kann mir jemand weiterhelfen. #include <ModbusRTUSlave.h> #define MODBUS_SERIAL Serial1 #define MODBUS_BAUD 9600 #define MODBUS_CONFIG SERIAL_8N1 #define MODBUS_UNIT_ID 100 #if (defined(ARDUINO_NANO_RP2040_CONNECT) && !defined(ARDUINO_ARCH_MBED)) || defined(ARDUINO_NANO_ESP32) // These boards operate unsing GPIO numbers that don't correspond to the numbers on the boards. // However they do have D# values #defined to correct this. const int8_t buttonPins[2] = {D2, D3}; const int8_t ledPins[4] = {D5, D6, D7, D8}; const int8_t dePin = D13; #else // Other boards do not have D# values, and will throw an error if you try to use them. const int8_t buttonPins[2] = {2, 3}; const int8_t ledPins[4] = {5, 6, 7, 8}; const int8_t dePin = 13; #endif const int8_t knobPins[2] = {A0, A1}; ModbusRTUSlave modbus(Serial1); const uint8_t numInputRegisters = 2; uint16_t inputRegisters[2]; float wert; String scaleOutput; void setup() { Serial2.begin(9600); pinMode(knobPins[0], INPUT); pinMode(knobPins[1], INPUT); pinMode(buttonPins[0], INPUT_PULLUP); pinMode(buttonPins[1], INPUT_PULLUP); modbus.configureInputRegisters(inputRegisters, numInputRegisters); MODBUS_SERIAL.begin(9600, SERIAL_8N1); modbus.begin(MODBUS_UNIT_ID, MODBUS_BAUD, MODBUS_CONFIG); } void loop() { if (Serial2.available()) scaleOutput = Serial2.readStringUntil(B00001101); wert = scaleOutput.substring(1,5).toFloat(); inputRegisters[0] = (wert); inputRegisters[1] = (12345); modbus.poll(); }
Markus schrieb: > Dann habe ich > aus einer Modbus RTU Slave Vorlage einen Sketch mehr oder weniger > zusammen gebastelt, der nun auch funktioniert, das blöde ist nur das > nach ein paar Tagen die Verbindung mit dem Modbus RS485 RTU abbricht. Problem, vermute ich: > Serial2.readStringUntil(B00001101); Blockiert den Program-Ablauf, bis das Zeichen kommt. Das dauert bei 9600 Baud schon lange, noch viel länger wenn durch eine Störung auf der RS232 das Zeichen garnicht kommt. Das ist, was ich hier meinte: Εrnst B. schrieb: > Nur aufpassen, dass die loop nicht zulange blockiert wird, also > zeichenweise lesen, damit modbus.poll(); nicht verhungert... also in etwa:
1 | String buffer; |
2 | void loop() { |
3 | if (Serial2.available()) { |
4 | int zeichen=Serial2.read(); |
5 | if (zeichen=='\r') { |
6 | wert = buffer.trim().toFloat(); |
7 | buffer = String(); |
8 | if (wert ist plausibel) |
9 | inputRegisters[0]=wert; |
10 | } else { |
11 | buffer += (char)zeichen; |
12 | }
|
13 | }
|
14 | modbus.poll(); |
15 | }
|
ggfs. timeout&Abbruch einbauen (wenn zulange kein weiteres Zeichen kommt, während schon eins im Buffer steht, oder buffer > 5 Zeichen hat, buffer wieder leeren) PS: warum "toFloat"? Sind da Nachkomma-Stellen?
:
Bearbeitet durch User
Hallo Ernst danke für die Antwort
Das mit dem
> Serial2.readStringUntil(B00001101);
habe ich eingebaut, weil die Waage den Wert ca. alle 200ms schickt und
ich ohne das "Until(B00001101)" falsche Werte bekommen habe. Ohne hat es
nur bis zu einem Intervall von ca. 500ms funktioniert.
Float brauch ich eigentlich nicht, es wird kein Komma Zeichen gesendet,
ich habe das in einem anderen Waagen Sketch gelesen und eingebaut und da
es funktioniert hat nicht mehr geändert. Es kann nur sein das die Waage
ein Minus Vorzeichen sendet, also z.B. Leerzeichen, Leerzeichen,
Leerzeichen, Minus, Zwei, und das Stopzeichen "00001101"
Ich werde mal einen Zweiten Aufbau machen und es mit deiner Änderung
versuchen
.
Aber jetzt habe ich noch eine Frage wie wird bei deinem Sketch das
Stopzeichen ausgewertet, wird das mit
if (zeichen=='\r')
erledigt ?
Danke im Voraus
Markus schrieb: > Aber jetzt habe ich noch eine Frage wie wird bei deinem Sketch das > Stopzeichen ausgewertet, wird das mit > if (zeichen=='\r') ja, 0b00001101 ist 0x0D ist 13 ist der "Wagenrücklauf" '\r'. Kannst du auf alle 4 Arten reinschreiben, ich persönlich finde '\r' übersichtlicher. Da erkenne ich gleich, dass das ein Zeilenende sein soll... Markus schrieb: > Leerzeichen, Leerzeichen, Leerzeichen, Minus, Zwei, dafür hab ich das "buffer.trim()" drinnen. Das entfernt Leerzeichen am Anfang und Ende von einem String. Hab den Code aber "blind" getippt, da sind noch Fehler drinnen. z.B. kann es gut sein dass du statt >> buffer.trim().toInt(); Zwei Zeilen, >> buffer.trim(); >> wert=buffer.toInt(); bauchst. Und es kann sein, dass "String.toInt()" bei Arduino keine negativen Zahlen kennt... Insofern ist der weg über toFloat vielleicht einfacher. Für ungenutzten Flash-Speicher & Rechenzeit gibt's ja kein Geld zurück.
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.