Hallo, ich bin Anfänger und muss ein Projekt umsetzen, bei dem ich einen Windmesser und eine Windfahne (wurden mir übergeben) mittels NodeMCU ESP32 auslesen soll. Ich habe die Anleitung zum Windmesser/Anemometer angehängt. Es kommuniziert über RS485. Soweit ich bisher weiß, kann ich als RX 16 und TX 17 nutzen. Ich muss eine Anfrageadresse eingeben: "0x01, 0x03, 0x00, 0x16, 0x00, 0x01, 0x65, 0xCE" und weiß auch, an welcher Stelle dann die Windgeschwindigkeit ausgegeben wird in HEX. Nun die Frage, wie ich das ganze verkable und ansteuere. Hatte jemand ein ähnliches Projekt oder will mir auch so helfen? Das wäre super. Liebe Grüße Stefanie
:
Verschoben durch Moderator
Dann schreibe oder male doch mal, wie du dir das vorstellst. Wir helfen hier gerne, aber machen ungerne deine ganzen Hausaufgaben. Was du brauchst, ist ein RS485-Leitungstreiber. Ich nehme an, das ist der MAX485 und eine Leitung zum Sensor. Abschlusswiderstände nicht vergessen! Und dann kannst du über die 2. serielle Schnittstelle auf deinem ESP mit dem Sensor kommunizieren. Achte auf die richtige Baudrate und das Timing RX/TX.
:
Bearbeitet durch User
Da es sich um ein Bus-System handelt, habe ich ModbusMaster zur Bibliothek hinzugefügt von https://github.com/4-20ma/ModbusMaster Mein Anemometer wird an 12V und GND angeschlossen und hat eine 485-A- und B-Leitung. Nach der Anleitung von http://www.bizkit.ru/en/2019/02/21/12563/ habe ich das MAX485 (es ist ein 5V-Teil, ESP32 liefert aber nur 3.3V, habe aber schon mehrmals gelesen, dass das nicht stören sollte) mit dem ESP32 und A und B des Anemometers verkabelt. Folgenden Code habe ich dann erstmal ins Arduiono IDE reingeladen: "#include "ModbusMaster.h" //https://github.com/4-20ma/ModbusMaster /*! We're using a MAX485-compatible RS485 Transceiver. Rx/Tx is hooked up to the hardware serial port at 'Serial'. The Data Enable (DE) and Receiver Enable (RE) pins are hooked up as follows: */ #define MAX485_RE_NEG 4 //D4 RS485 has a enable/disable pin to transmit or receive data. Arduino Digital Pin 2 = Rx/Tx 'Enable'; High to Transmit, Low to Receive #define Slave_ID 1 #define RX_PIN 16 //RX2 #define TX_PIN 17 //TX2 // instantiate ModbusMaster object ModbusMaster modbus; void preTransmission() { digitalWrite(MAX485_RE_NEG, HIGH); //Switch to transmit data } void postTransmission() { digitalWrite(MAX485_RE_NEG, LOW); //Switch to receive data } void setup() { pinMode(MAX485_RE_NEG, OUTPUT); // Init in receive mode digitalWrite(MAX485_RE_NEG, LOW); // Modbus communication runs at 9600 baud Serial.begin(9600, SERIAL_8N1); Serial2.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); modbus.begin(Slave_ID, Serial2); // Callbacks allow us to configure the RS485 transceiver correctly modbus.preTransmission(preTransmission); modbus.postTransmission(postTransmission); } long lastMillis = 0; void loop() { long currentMillis = millis(); if (currentMillis - lastMillis > 1000) { uint8_t result = modbus.readInputRegisters(0x01, 2); if (getResultMsg(&modbus, result)) { Serial.println(); double res_dbl = modbus.getResponseBuffer(0) / 10; String res = "Temperature: " + String(res_dbl) + " C\r\n"; res_dbl = modbus.getResponseBuffer(1) / 10; res += "Humidity: " + String(res_dbl) + " %"; Serial.println(res); } lastMillis = currentMillis; } } bool getResultMsg(ModbusMaster *node, uint8_t result) { String tmpstr2 = "\r\n"; switch (result) { case node->ku8MBSuccess: return true; break; case node->ku8MBIllegalFunction: tmpstr2 += "Illegal Function"; break; case node->ku8MBIllegalDataAddress: tmpstr2 += "Illegal Data Address"; break; case node->ku8MBIllegalDataValue: tmpstr2 += "Illegal Data Value"; break; case node->ku8MBSlaveDeviceFailure: tmpstr2 += "Slave Device Failure"; break; case node->ku8MBInvalidSlaveID: tmpstr2 += "Invalid Slave ID"; break; case node->ku8MBInvalidFunction: tmpstr2 += "Invalid Function"; break; case node->ku8MBResponseTimedOut: tmpstr2 += "Response Timed Out"; break; case node->ku8MBInvalidCRC: tmpstr2 += "Invalid CRC"; break; default: tmpstr2 += "Unknown error: " + String(result); break; } Serial.println(tmpstr2); return false; }" Der Autor hat zwar andere Sensoren angebaut, aber das stört m.E. nicht. Nun frage ich mich, wohin ich mein Inquiry Frame hinschreiben soll. Laut Anleitung vom Anemometer ist das folgendermaßen: Address Function Start Address DataLength CRC-L CRC_H 0x01 0x03 0x00 0x16 0x00 0x01 0x65 0xCE ich hatte das folgendermaßen eingebaut, ist aber Käse, weil Antworten angezeigt werden, egal ob sich das Anemometer dreht oder nicht. Siehe Datei.ino Vielleicht gibts jetzt einen Tipp? ;-) Vielen Dank schon mal
Stefanie F. schrieb: > es ist ein 5V-Teil, ESP32 liefert aber nur 3.3V Da gehören auf jeden Fall Pegelwandler hin. Dein ESP wird's dir danken. Jedes Mal, wenn du Daten haben willst, musst du das Inquiry Frame schicken und dein Sensor antwortet drauf.
dann habe ich entweder die falsche Stelle für das Frame gewählt oder falsch formuliert. Mir wird immer die selbe Antwort ausgegeben, egal, ob das Anemometer am Netzteil hängt oder nicht oder stillsteht oder angedreht wird. :-(
So, hier der aktuelle Code: #include "ModbusMaster.h" //https://github.com/4-20ma/ModbusMaster #define MAX485_RE_NEG 18 //D4 RS485 has a enable/disable pin to transmit or receive data. Arduino Digital Pin 2 = Rx/Tx 'Enable'; High to Transmit, Low to Receive #define MAX485_DE 19 #define Slave_ID 1 #define RX_PIN 16 //RX2 #define TX_PIN 17 //TX2 // instantiate ModbusMaster object ModbusMaster modbus; void preTransmission() { digitalWrite(MAX485_RE_NEG, HIGH); //Switch to transmit data digitalWrite(MAX485_DE, HIGH); delay(1); } void postTransmission() { delay(3); digitalWrite(MAX485_RE_NEG, LOW); //Switch to receive data digitalWrite(MAX485_DE, LOW); } void setup() { pinMode(MAX485_RE_NEG, OUTPUT); pinMode(MAX485_DE, OUTPUT); // Init in receive mode //digitalWrite(MAX485_RE_NEG, LOW); //digitalWrite(MAX485_DE, LOW); // Modbus communication runs at 9600 baud Serial.begin(9600); Serial2.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); modbus.begin(Slave_ID, Serial2); // Callbacks allow us to configure the RS485 transceiver correctly modbus.preTransmission(preTransmission); modbus.postTransmission(postTransmission); delay(1000); } void loop() { digitalWrite(MAX485_RE_NEG, HIGH); preTransmission(); byte Anemometer_request[] = {0x01, 0x03, 0x00, 0x16, 0x00, 0x01, 0x65, 0xCE}; // inquiry frame Anemometer // byte Anemometer_request[] = {0x02, 0x03, 0x00, 0x17, 0x00, 0x01, 0x34, 0xC0E}; // inquiry frame Windfahne Serial2.write(Anemometer_request,8); //Serial2.flush(); delay(10); postTransmission(); delay(100); byte Anemometer_buf[8]; Serial2.readBytes(Anemometer_buf, 8); Serial.print("HEX : "); for( byte i=0; i<7; i++ ) { if ((Anemometer_buf[0]=(0x01)) and (Anemometer_buf[1]=(0x03)) and (Anemometer_buf[2]=(0x02)) ) //for Anemometer //if ((Anemometer_buf[0]=(0x02)) and (Anemometer_buf[1]=(0x03)) and (Anemometer_buf[2]=(0x02)) ) //for Anemoscope { Serial.print(Anemometer_buf[i], HEX); // this is for test only Serial.print(" "); } } Serial.print(" ==> "); int Windgeschwindigkeit=Anemometer_buf[4]; Serial.print((Windgeschwindigkeit/10.0)); // here is the result Serial.print(" m/s"); Serial.println(); if (Serial2.available()) { Serial.println("available"); } else Serial.println("not available"); } Antwort wird dann so angezeigt: 12:12:55.077 -> HEX : 1 3 2 B8 44 0 0 ==> 6.80 m/s 12:12:55.153 -> not available 12:12:56.187 -> HEX : 1 3 2 44 44 0 0 ==> 6.80 m/s 12:12:56.234 -> not available Laut Anleitung ist die Windgeschwindigkeit an Stelle 5, gezählt wird von 0. Nur steht das Teil. hat jemand eine Idee?
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.