ESP32 Seriell senden

Hallo
Ich habe mir ein Prog geschrieben. Ich mochte damit das Register mit 8 Werte schreiben.
Leider funktioniert das nicht. Hardware funktioniert soweit. Ich bekomme im sekundentakt in "HTerm" ein Byte rein. Immer alles 0. Leider kann ich keine sinnvollen Daten empfangen. Wo liegt der Fehler?

#include <String.h>




#define RS485_PIN_DIR 4
#define RXD2 16
#define TXD2 17





byte byte0 = 36;
byte byte1 = 86;
byte byte2 = 0;
byte byte3 = 33;
byte byte4 = 3; //(2 byte watts as short integer xaxb)
byte byte5 = 123; //(2 byte watts as short integer xaxb) "0"
byte byte6 = 128;
byte byte7 = 138; // checksum "8"
byte serialpacket[8];



HardwareSerial rs485(1);

#define RS485_WRITE     1
#define RS485_READ      0



void setup() {
  Serial.begin(115200);
  rs485.begin(4800, SERIAL_8N1, RXD2, TXD2);


  Serial.print("Info: Intial gpio...");
  pinMode(RS485_PIN_DIR,OUTPUT);
  digitalWrite(RS485_PIN_DIR,RS485_READ);
  Serial.println("done"); 

}

void loop() {

  serialpacket[0]=byte0;
    serialpacket[1]=byte1;
    serialpacket[2]=byte2;
    serialpacket[3]=byte3;
    serialpacket[4]=byte4;
    serialpacket[5]=byte5;
    serialpacket[6]=byte6;
    serialpacket[7]=byte7;

    
    
    Serial.printf("TEST_Eintrag");
    //Serial.write(serialpacket,8);
    digitalWrite(RS485_PIN_DIR,RS485_WRITE);
    rs485.write(serialpacket,8);
    //rs485.write(1);

        
     delay(10); 
     digitalWrite(RS485_PIN_DIR,RS485_READ);
 
       delay(1000);
  
}

Ich habe deinen Post ins deutschsprachige Forum verschoben. Bitte verwenden Sie Englisch im allgemeinen Forum. (auch dein Post gehört nicht in die Kategorie: Projects Discussion and ShowcaseHome Automation)


➜ welchen Arduino verwendest du?


PS:so ist es wahrscheinlich einfacher

const byte serialpacket[] = {36,86,0,33,3,123,128,138};
...
    rs485.write(serialpacket,sizeof serialpacket);

Ich verwende einen ESP32 Wroom mit einer RS485 Erweiterung.

Welche Pins sind wo angeschlossen?

Hallo

Mein DI ist an PIN 4 angeschlossen
RX2 ist pin 16
TX2 ist pin 17

Das bekomme ich gesendet. Jede Sekunde ein weiterer Eintrag

Mit meinem UNO bekomme ich das hin.
Dort schreibe ich ohne Probleme das Register.
Jedoch will der ESP 32 die Bibliotheken vom Uno nicht.
Ich habe schon etwas im neuen Prog reduziert.


#include <SoftwareSerial.h>
#include <MAX485.h>
#include<ModbusRtu.h>       //Library for using Modbus in Arduino


// Setup SoftSerial Port to send TTL data to driver 
SoftwareSerial FirstSerial(10, 11); // RX(10)->RO, TX(11)->DI
// Setup max485 Control Input
MAX485 FirstMax485(8, 9); // 8->RE, 9->DE


Modbus bus;                          //Define Object bus for class modbus 

uint16_t modbus_array[] = {0};    //Array initilized with three 0 values



byte byte0 = 36;
byte byte1 = 86;
byte byte2 = 0;
byte byte3 = 33;
byte byte4 = 3; //(2 byte watts as short integer xaxb)
byte byte5 = 123; //(2 byte watts as short integer xaxb) "0"
byte byte6 = 128;
byte byte7 = 138; // checksum "8"
byte serialpacket[8];
int importingnow = 0; //amount of electricity being imported from grid
int demand = 0; //current power inverter should deliver (default to zero)

               
void setup()
{

  bus = Modbus(3,1,4);            //Modbus slave ID as 1 and 1 connected via RS-485 and 4 connected to DE & RE pin of RS-485 Module 
  bus.begin(4800);                //Modbus slave baudrate at 4800
    // set the data rate for the SoftwareSerial port connected to the TTL to RS-485 module
  FirstSerial.begin(4800);
  // set Master-Mode
  FirstMax485.setMaster();
}


void loop()
{
   bus.poll(modbus_array,sizeof(modbus_array)/sizeof(modbus_array[0]));       //Used to receive or write value from Master 

    serialpacket[0]=byte0;
    serialpacket[1]=byte1;
    serialpacket[2]=byte2;
    serialpacket[3]=byte3;
    serialpacket[4]=byte4;
    serialpacket[5]=byte5;
    serialpacket[6]=byte6;
    serialpacket[7]=byte7;
     


  int geforderte_Leistung = modbus_array[0]; //Depends upon value in modbus_array[1] written by Master Modbus

 if (geforderte_Leistung !=99999)
{
  
 if (geforderte_Leistung > 0)    //Abfrage Leistung größer 0 Watt
{
   if (geforderte_Leistung >3000)    //Abfrage Leistung größer 3000 Watt
{
  Serial.println("Leistung >3000");
}

else {

demand=geforderte_Leistung;
    
    // -- Compute serial packet to inverter (just the 3 bytes that change) --
    byte4 = int(demand/256); // (2 byte watts as short integer xaxb)
    if (byte4 < 0 or byte4 > 256){
        byte4 = 0;}
    byte5 = int(demand)-(byte4 * 256); // (2 byte watts as short integer xaxb)
    if (byte5 < 0 or byte5 > 256) {
        byte5 = 0;}
    byte7 = (264 - byte4 - byte5); //checksum calculation
    if (byte7 > 256){
        byte7 = 8;}

    serialpacket[4]=byte4;
    serialpacket[5]=byte5;
    serialpacket[7]=byte7;



  
  Serial.println(geforderte_Leistung);
   // set carrier
  FirstMax485.sending(true);
  // send to SoftSerial
  FirstSerial.write(serialpacket,8);
  //FirstSerial.println(i);
  // lower carrier
  FirstMax485.sending(false);
    //Serial.write(serialpacket,8);
 

  modbus_array[0]=99999;

}
  
}

else {
 // Serial.println("Leistung=0");
}
}

 

  delay(500); 

}




 

ist deine RS485 Erweiterung 3.3V kompatibel?

Der ESP32 hat drei UARTs in Hardware, eine für USB, Serial1 an belegten Pins, aber Serial2 an RX=16 und TX=17 ist frei zu verwenden. Das paßt mit Deiner Verdrahtung.

grafik

Also kannst Du Serial2 verwenden (ungetestet):

const byte RS485_PIN_DIR = {4};

byte byte0 = 36;
byte byte1 = 86;
byte byte2 = 0;
byte byte3 = 33;
byte byte4 = 3; //(2 byte watts as short integer xaxb)
byte byte5 = 123; //(2 byte watts as short integer xaxb) "0"
byte byte6 = 128;
byte byte7 = 138; // checksum "8"
byte serialpacket[8];

#define RS485_WRITE     1
#define RS485_READ      0

void setup() {
  Serial.begin(115200);
  Serial2.begin(4800);

  Serial.print("Info: Intial gpio...");
  pinMode(RS485_PIN_DIR, OUTPUT);
  digitalWrite(RS485_PIN_DIR, RS485_READ);
  Serial.println("done");
}

void loop() {
  serialpacket[0] = byte0;
  serialpacket[1] = byte1;
  serialpacket[2] = byte2;
  serialpacket[3] = byte3;
  serialpacket[4] = byte4;
  serialpacket[5] = byte5;
  serialpacket[6] = byte6;
  serialpacket[7] = byte7;

  Serial.printf("TEST_Eintrag");
  digitalWrite(RS485_PIN_DIR, RS485_WRITE);
  Serial2.write(serialpacket, 8);

  delay(10);
  digitalWrite(RS485_PIN_DIR, RS485_READ);

  delay(1000);
}

Hallo
Das war nicht die Lösung.
Es bringt exakt das gleiche an den Seriellen Port2.
Ich wünsche mir aber, dass 8 bytes gesendet werden mit den entsprechenden Werten.
Aktuell kommt nur ein Byte pro Sekunde rüber. Immer "00000000".
Gruß
Henrik

kannst du das versuchen?

const byte RS485_PIN_DIR = 4;
const byte RXD2 = 16;
const byte TXD2 = 17;
#define rs485 Serial2

#define RS485_WRITE     HIGH
#define RS485_READ      LOW

const byte serialpacket[] = {36, 86, 0, 33, 3, 123, 128, 138};

void sendPacket() {
  digitalWrite(RS485_PIN_DIR, RS485_WRITE);
  rs485.write(serialpacket, sizeof serialpacket);
  rs485.flush(); // wait for all bytes to be sent before changing the DIR pin
  digitalWrite(RS485_PIN_DIR, RS485_READ);

}

void setup() {
  pinMode(RS485_PIN_DIR, OUTPUT);
  Serial.begin(115200); while (!Serial);
  rs485.begin(4800, SERIAL_8N1, RXD2, TXD2);
  Serial.println("done");
  Serial.printf("TEST_Eintrag");
}

void loop() {
  sendPacket();
  delay(1000);
}

Hallo
Auch das habe ich jetzt versucht. Ich bekomme das gleiche am Seriellen Port angezeigt. "00000000"
Ich habe auch den RS485 Adapter geprüft.

Schade, denn bei mir funktioniert es mit zwei ESP32.

Noch besser funktioniert es allerdings mit

Serial2.flush(); // wait for all bytes to be sent before changing the DIR pin

anstelle delay(10);, denn das reicht nur für fünf Bytes. THX Jackson :slightly_smiling_face:

36 86 00 33 03 123 128 138
36 86 00 33 03 123 128 138
36 86 00 33 03 123 128 138
36 86 00 33 03 123 128 138
36 86 00 33 03 123 128 138
36 86 00 33 03 123 128 138
36 86 00 33 03 123 128 138

Meine Verbindungen:

  • GPIO4 an DE/RE
  • GPIO16 an RO
  • GPIO17 an DI

Kannst du mal versuchen DE und RE mit HIGH zu verbinden

image

Dadurch bleibt das Modul in permanenter Übertragung.

was hast du auf der anderen seite ➜ setze DE und RE auf LOW für permanenten Empfang.

Ich habe als TTL zu 485 folgendes Board
Ich denke auch, dass es funktioniert, da es im Sekundentakt pollt.

Warum hast du in Hterm das Protokoll auf "5N1" gestellt? Das passt nicht zu den 8N1 auf dem ESP32.

Sie sollten niemals das Timing eines asynchronen Protokolls erraten :slight_smile:

➜ Betriebsspannung: 5V
image

Welches Board sollte ich denn nutzen?
Ich habe nur 3,3V Boards gefunden, die ohne DE und RE sind.
Ich habe aktuell die Versorgung mit 5 V für das TTL Board.
DI und RO werden mit 3,3V angesteuert. Liegt hier der Fehler?

ESP Tx ➜ RS485-Modul ist in Ordnung, da Sie 3,3 V senden, sodass es bei einem 5-V-Modul als HIGH angezeigt wird
RS485 Modul ➜ ESP Rx ist nicht OK, da Sie 5V an ein 3,3V Gerät senden.

Die gezeigte Platinen arbeiten bei mir mit 3,3V ohne Probleme (ESP8266), lesen und Schreiben aber über Modbus Protokoll

OK (Die mit 3,3V habe ich noch nie probiert)