Arduino lest immer 0 aus RS485 Verbindung

Hallo, ich habe das Problem, dass ein Register immer mit 0 ausgelesen wird, obwohl sich nicht 0 darin befindet. Ich hoffe ihr könnt mir helfen.

#include <ModbusRtu.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

/*  Modbus object declaration
    node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI 
              or any pin number > 1 for RS-485 */
 
Modbus master(0,0,2); // this is master and RS-232 or USB-FTDI
modbus_t telegram[4];
unsigned long u32wait;
uint16_t au16data[16]; //!< data array for modbus network sharing
uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query
int sprayungen;
int kg;
int kali;
int schalter;
int a = 0;
int maxwert ; 
int zeithilfe;
int tasterplusZeit;
int tasterplusGedrueckt;
int tasterminusZeit;
int tasterminusGedrueckt;

//                    addr, en,rw,rs,d4,d5,d6,d7,bl,backlight-polarity
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 3, 4, 5, 6, 7, POSITIVE);

void setup() {
  lcd.begin(16, 2);
  lcd.backlight();
//         (Zeichen, Zeile)
    lcd.setCursor(0,0); 
  
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
 
  // telegram 0: read registers
  telegram[0].u8id = 3; // slave address
  telegram[0].u8fct = 3; // function code (this one is registers read)
  telegram[0].u16RegAdd = 0; // start address in slave
  telegram[0].u16CoilsNo = 6; // number of elements (coils or registers) to read
  telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino

 //telegram 1: write a single register
  telegram[1].u8id = 1; // slave address
  telegram[1].u8fct = 6; // function code (this one is write a single register)
  telegram[1].u16RegAdd = 0; // start address in slave
  telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read
  telegram[1].au16reg = au16data+6  ; // pointer to a memory array in the Arduino 

  telegram[2].u8id = 1; // slave address
  telegram[2].u8fct = 3; // function code (this one is registers read)
  telegram[2].u16RegAdd = 1; // start address in slave
  telegram[2].u16CoilsNo = 1; // number of elements (coils or registers) to read
  telegram[2].au16reg = au16data+7;
    
  telegram[3].u8id = 2; // slave address
  telegram[3].u8fct = 6; // function code (this one is registers read)
  telegram[3].u16RegAdd = 1; // start address in slaven
  telegram[3].u16CoilsNo = 1; // number of elements (coils or registers) to read
  telegram[3].au16reg = au16data+8; // pointer to a memory array in the Arduino
  
  master.begin( 115200 );
  master.setTimeOut( 2000 ); // if there is no answer in 1000 ms, roll over
  u32wait = millis() + 1000;
  u8state = u8query = 0; 

}

void loop(){


  switch( u8state ) {
  case 0: 
    if (millis() > u32wait) u8state++; // wait state
    break;
  case 1: 
    master.query( telegram[u8query] ); // send query (only once)
    u8state++;
  u8query++;
  if (u8query > 10) u8query = 0;
    break;
  case 2:
    master.poll(); // check incoming messages
    if (master.getState() == COM_IDLE) {  //IDLE = Leerlauf   
      u8state = 0;
      u32wait = millis() + 1000; 
    }
    break;
  }
     master.poll();
  digitalWrite(3, au16data[0]);   //LED(3)
  digitalWrite(4, au16data[1]);
  digitalWrite(5, au16data[2]);
  digitalWrite(6, au16data[3]);
  digitalWrite(7, au16data[4]);
  digitalWrite(8, au16data[5]);
  
  au16data[6] = digitalRead(9);  //Sprayer(1)
  sprayungen = au16data[7]; //Spray-Zaehler
  master.query(telegram[3]);
  kg = au16data[8];               //Waegezelle(2) 
   if(digitalRead(10) == HIGH){
    tasterplusZeit = millis();     
    tasterplusGedrueckt = 1;       
  }      
  
  if((millis() - tasterplusZeit > 100) && tasterplusGedrueckt == 1){
    master.query(telegram[3]);
    //  telegram[3].u8fct = 6;
      int a = au16data[9];
      au16data[8] = a + 1;
      master.poll();
     // telegram[3].u8fct = 3;             
      tasterplusGedrueckt = 0;     
    }

     if(digitalRead(11) == HIGH){
    tasterminusZeit = millis();    
    tasterminusGedrueckt = 1;      
  }
 
  if((millis() - tasterminusZeit > 100) && tasterminusGedrueckt == 1){
     // telegram[3].u8fct = 6;
     master.query(telegram[3]);
      int a = au16data[9];
      au16data[8] = a - 1;
      master.poll();
     // telegram[3].u8fct = 3;             
      tasterminusGedrueckt = 0;    
    }
  
  if(digitalRead(12) == HIGH){  //Tare
   // telegram[3].u8fct = 6;
    au16data[10] = 1;
    master.poll();
    //telegram[3].u8fct = 3 ;
  }

  if(kg >= maxwert){
    maxwert = kg;
    zeithilfe = millis();
  }
  if(millis() - zeithilfe > 15000 && kg <= maxwert){
    maxwert = 0;
    zeithilfe = millis();
  }
   
  //LCD
  //lcd.clear();
  lcd.setCursor(0,0);

  if(stellen(kg) == 1){   //KG(derzeit)
    lcd.print("  ");
  }
  else if(stellen(kg) == 2){
    lcd.print(" ");
  }
  lcd.print(kg);
  lcd.print("kg");
  lcd.print("  max:");
  

  if(stellen(maxwert) == 1){   //KG(max)
    lcd.print("  ");
  }
  else if(stellen(maxwert) == 2){
    lcd.print(" ");
  }
  lcd.print(maxwert);
  lcd.print("kg");
  lcd.setCursor(0,1);

  
  if(stellen(sprayungen) == 1){  //Sprayungen
    lcd.print("    ");
  }
  else if(stellen(sprayungen) == 2){
    lcd.print("   ");
  }
  else if(stellen(sprayungen) == 3){
    lcd.print("  ");
  }
  else if(stellen(sprayungen) == 4){
    lcd.print(" ");
  }                                                 
  lcd.print(sprayungen);
  lcd.print(" Sprayungen");    
}


  int stellen(int x){
    if ( x < 10 )
      return 1;
    else if ( x < 100 )
      return 2;
    else if ( x < 1000 )
      return 3;
    else if ( x < 10000)
      return 4;
  }

Bei diesem Codestück habe ich das Problem das int a immer = 0 ist. Ich habe es getestet, dass mein Slave nicht 0 ins Register schreibt

   if(digitalRead(10) == HIGH){
    tasterplusZeit = millis();     
    tasterplusGedrueckt = 1;       
  }      
  
  if((millis() - tasterplusZeit > 100) && tasterplusGedrueckt == 1){
    master.query(telegram[3]);
    //  telegram[3].u8fct = 6;
      int a = au16data[9];
      au16data[8] = a + 1;
      master.poll();
     // telegram[3].u8fct = 3;             
      tasterplusGedrueckt = 0;     
    }

     if(digitalRead(11) == HIGH){
    tasterminusZeit = millis();    
    tasterminusGedrueckt = 1;      
  }
 
  if((millis() - tasterminusZeit > 100) && tasterminusGedrueckt == 1){
     // telegram[3].u8fct = 6;
     master.query(telegram[3]);
      int a = au16data[9];
      au16data[8] = a - 1;
      master.poll();
     // telegram[3].u8fct = 3;             
      tasterminusGedrueckt = 0;    
    }

Du hast 2 variable namens a, beide vom Datentyp int.

Hab deinen Code nicht genau angesehen, aber ...

~~ int~~ a = au16data[9]; // lass hier das int mal weg

Ich habe die variable a nun durch b und c ersetzt, jedoch habe ich das selbe Problem noch immer

#include <ModbusRtu.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

/*  Modbus object declaration
    node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI 
              or any pin number > 1 for RS-485 */
 
Modbus master(0,0,2); // this is master and RS-232 or USB-FTDI
modbus_t telegram[4];
unsigned long u32wait;
uint16_t au16data[16]; //!< data array for modbus network sharing
uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query
int sprayungen;
int kg;
int kali;
int schalter;
int a = 0;
int b;
int c;
int maxwert ; 
int zeithilfe;
int tasterplusZeit;
int tasterplusGedrueckt;
int tasterminusZeit;
int tasterminusGedrueckt;

//                    addr, en,rw,rs,d4,d5,d6,d7,bl,backlight-polarity
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 3, 4, 5, 6, 7, POSITIVE);

void setup() {
  lcd.begin(16, 2);
  lcd.backlight();
//         (Zeichen, Zeile)
    lcd.setCursor(0,0); 
  
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
 
  // telegram 0: read registers
  telegram[0].u8id = 3; // slave address
  telegram[0].u8fct = 3; // function code (this one is registers read)
  telegram[0].u16RegAdd = 0; // start address in slave
  telegram[0].u16CoilsNo = 6; // number of elements (coils or registers) to read
  telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino

 //telegram 1: write a single register
  telegram[1].u8id = 1; // slave address
  telegram[1].u8fct = 6; // function code (this one is write a single register)
  telegram[1].u16RegAdd = 0; // start address in slave
  telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read
  telegram[1].au16reg = au16data+6  ; // pointer to a memory array in the Arduino 

  telegram[2].u8id = 1; // slave address
  telegram[2].u8fct = 3; // function code (this one is registers read)
  telegram[2].u16RegAdd = 1; // start address in slave
  telegram[2].u16CoilsNo = 1; // number of elements (coils or registers) to read
  telegram[2].au16reg = au16data+7;
    
  telegram[3].u8id = 2; // slave address
  telegram[3].u8fct = 6; // function code (this one is registers read)
  telegram[3].u16RegAdd = 1; // start address in slaven
  telegram[3].u16CoilsNo = 1; // number of elements (coils or registers) to read
  telegram[3].au16reg = au16data+8; // pointer to a memory array in the Arduino
  
  master.begin( 115200 );
  master.setTimeOut( 2000 ); // if there is no answer in 1000 ms, roll over
  u32wait = millis() + 1000;
  u8state = u8query = 0; 

}

void loop(){


  switch( u8state ) {
  case 0: 
    if (millis() > u32wait) u8state++; // wait state
    break;
  case 1: 
    master.query( telegram[u8query] ); // send query (only once)
    u8state++;
  u8query++;
  if (u8query > 10) u8query = 0;
    break;
  case 2:
    master.poll(); // check incoming messages
    if (master.getState() == COM_IDLE) {  //IDLE = Leerlauf   
      u8state = 0;
      u32wait = millis() + 1000; 
    }
    break;
  }
     master.poll();
  digitalWrite(3, au16data[0]);   //LED(3)
  digitalWrite(4, au16data[1]);
  digitalWrite(5, au16data[2]);
  digitalWrite(6, au16data[3]);
  digitalWrite(7, au16data[4]);
  digitalWrite(8, au16data[5]);
  
  au16data[6] = digitalRead(9);  //Sprayer(1)
  sprayungen = au16data[7]; //Spray-Zaehler
  master.query(telegram[3]);
  kg = au16data[8];               //Waegezelle(2) 
   if(digitalRead(10) == HIGH){
    tasterplusZeit = millis();     
    tasterplusGedrueckt = 1;       
  }      
  
  if((millis() - tasterplusZeit > 100) && tasterplusGedrueckt == 1){
    master.query(telegram[3]);
    //  telegram[3].u8fct = 6;
       b = au16data[9];
      au16data[8] = b + 1;
      master.poll();
     // telegram[3].u8fct = 3;             
      tasterplusGedrueckt = 0;     
    }

     if(digitalRead(11) == HIGH){
    tasterminusZeit = millis();    
    tasterminusGedrueckt = 1;      
  }
 
  if((millis() - tasterminusZeit > 100) && tasterminusGedrueckt == 1){
     // telegram[3].u8fct = 6;
     master.query(telegram[3]);
      c = au16data[9];
      au16data[8] = c - 1;
      master.poll();
     // telegram[3].u8fct = 3;             
      tasterminusGedrueckt = 0;    
    }
  
  if(digitalRead(12) == HIGH){  //Tare
   // telegram[3].u8fct = 6;
    au16data[10] = 1;
    master.poll();
    //telegram[3].u8fct = 3 ;
  }

  if(kg >= maxwert){
    maxwert = kg;
    zeithilfe = millis();
  }
  if(millis() - zeithilfe > 15000 && kg <= maxwert){
    maxwert = 0;
    zeithilfe = millis();
  }
   
  //LCD
  //lcd.clear();
  lcd.setCursor(0,0);

  if(stellen(kg) == 1){   //KG(derzeit)
    lcd.print("  ");
  }
  else if(stellen(kg) == 2){
    lcd.print(" ");
  }
  lcd.print(kg);
  lcd.print("kg");
  lcd.print("  max:");
  

  if(stellen(maxwert) == 1){   //KG(max)
    lcd.print("  ");
  }
  else if(stellen(maxwert) == 2){
    lcd.print(" ");
  }
  lcd.print(maxwert);
  lcd.print("kg");
  lcd.setCursor(0,1);

  
  if(stellen(sprayungen) == 1){  //Sprayungen
    lcd.print("    ");
  }
  else if(stellen(sprayungen) == 2){
    lcd.print("   ");
  }
  else if(stellen(sprayungen) == 3){
    lcd.print("  ");
  }
  else if(stellen(sprayungen) == 4){
    lcd.print(" ");
  }                                                 
  lcd.print(sprayungen);
  lcd.print(" Sprayungen");    
}


  int stellen(int x){
    if ( x < 10 )
      return 1;
    else if ( x < 100 )
      return 2;
    else if ( x < 1000 )
      return 3;
    else if ( x < 10000)
      return 4;
  }

Um dieses Problem zu lösen, solltest du an geeigneter Stelle die Inhalte im sweriellen Monitor anzeigen lassen.
Evtl. ist ja auch die Übertragung schon fehlerhaft.

Wie soll ich das machen? Da es ModBus RTU ist spuckt mir der Serielle Monitor nur Sonderzeichen aus

Ok, da ich ModBus nicht kenne, kann ich dazu nichts sagen
Aber du kannst dir doch den Inhalt anzeigen lassen, wenn er einer Variable übergeben wird.

So z.B. sollte sollten die binären "Sonderzeichen" lesbar sein:

Serial.println((uint16_t)au16data[8], HEX);

Entschuldigung, dass ich lange nicht geantwortet habe. Ich war sehr stressig.

mit Serial.println((uint16_t)au16data[8], HEX); bekomme ich auch nur FFFF. Also 0.

Mal abgesehen davon, dass 0xFFFF so ungefähr "das Gegenteil" von 0 ist, würde ich mal bei den Telegrammen einzeln schauen, was passiert.

Mirt ist übrigens noch aufgefallen, dass du 4 Telegramme definiert hast

  modbus_t telegram[4];

aber dass du 10 verschiedene Telegramme aufrufst

    master.query( telegram[u8query] ); // send query (only once)
  ... 
  u8query++;
  if (u8query > 10) u8query = 0;

Da greift Arduino gnadenlos irgendwo hin, und nachvollziehen was dann passiert ist erheblich mühsamer, als es richtig zu machen.

Achso Tschuldige. Hab gedacht weil zuerst 0 und dann FFFF stand, dass das das (nein keine Wortwiederholung :slight_smile: ) selbe ist ist. Aber stimmt, ist es nicht 65535 oder so? Ich hab mich noch nie mit dem Hexadezimalsystem beschäftigt.

Die 10 hab ich auf 4 geändert und mein LCD zeigt mir jetzt manchmal 0 und manchmal -1 an

ist es nicht 65535 oder so?

Ja, oder -1, wenn man es als vorzeichenbehaftete Zahl interpretiert.

Die 10 hab ich auf 4 geändert und mein LCD zeigt mir jetzt manchmal 0 und manchmal -1 an

HotSystems:
Ok, da ich ModBus nicht kenne, kann ich dazu nichts sagen
Aber du kannst dir doch den Inhalt anzeigen lassen, wenn er einer Variable übergeben wird.

Da sind wir jetzt. Warum dir 0 oder -1 nicht gefällt, musst du selber wissen :wink:

0 und -1 gefällt mir nicht :slight_smile: . Wenn ich den Slave mit einem RS485 zu USB Adapter betribe zeigt er mir andere Werte an!

Hier hast du die volle Kontrolle. Musst es nur richtig machen. Und bei Modbus Details bin ich leider auch überfragt.

telegram[0].u8id = 3; // slave address
...
telegram[1].u8id = 1; // slave address

?

Du musst es nur richtig machen... Dann bräuchte ich ja kein Forum :grinning:
Meine Einstellungen, mit denen der Slave in qModMaster (ModBus Master Software) funktioniert sind: Slave ID 2, Read Holding Registers, TimeOut = 2000

Slave ID : 1 2 oder 3 ?

Guck eventuell auch mal die Library an, ob die nicht Fehler melden würde, die dein Sketch ignoriert...

Oder hast du dieses Problem?

Der brauchte allerdings ein Oszi, um zu sehen, dass der Modbus Slave dem Arduino gar nicht geantwortet hat. (Falls ich das richtig überflogen habe)

Ich schau nachher mit dem Oszi. Slave 1, 2 und 3 :slight_smile: Ich habe drei Slaves, nur dieser funktioniert nicht