Arduino modbus Slave read multiple DS18B20

Hi
I want to use Arduino as an slave modbus device and read value of multiple DS18b20 Sensor , multiple DHT22 Sensor and Control the Slave from Raspberry pi as Master modbus.
In my scenario, Arduino has several instruments plugged as I2C, 1-Wire or SPI and a serial port with Modbus.

I use OnWire.h library for reading the Value of DS18B20, the problem is It use delay() function in its code that cause a modbus does’t work fine , how can i remove delay() from my code and ds18b20 works fine , I use DHT22 with millis() that work fine and every 2 second update the value of it,
but for multiple ds18b20 i could not remove delay()

#include <ModbusRtu.h>
#include <OneWire.h>
#include <DHT.h>

#define TXEN  2           // Arduino  PIN2  must be connected to RE-DE RS485 transceiver 
#define DHTPIN 4          // Digital PIN4  is connected to DHTxx
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
OneWire ds(10);           // DS18B20 is on PIN10 
byte k;
long lastUpdatedht=0;

enum {
        MBS_ds1,
        MBS_ds2,
        MBS_ds3,
        MBS_ds4,
        MBS_ds5,
        MBS_ds6,
        MBS_ds7,
        MBS_ds8,
        MBS_DHT_h,
        MBS_DHT_t,
        MBS_relay1,
        MBS_relay2,
        MBS_relay3,
        MBS_relay4,
        MBS_REGS        
  };
uint16_t regs[MBS_REGS];
Modbus slave(1,0,TXEN); // this is slave @1 and RS-485


void setup()
{
  dht.begin();
  slave.begin( 9600 ); // baud-rate at 9600
}

void loop()
{
  byte i;
  byte data[12];
  byte addr[8];
  

  if ( !ds.search(addr))
  {
    ds.reset_search();
    k=0;
    delay(250);                               // first delay() function
    return;
  }
  
  ds.select(addr);
  ds.write(0x44, 1);
  delay(1000);                                // Second delay() function
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);           // Read Scratchpad
  for ( i = 0; i < 9; i++)
  {   
     data[i] = ds.read();
  }
           
   //Convert the data to actual temperature
   int16_t raw = (data[1] << 8) | data[0];
   byte cfg = (data[4] & 0x60);
   if (cfg == 0x00) raw = raw & ~7;        
   else if (cfg == 0x20) raw = raw & ~3;   
   else if (cfg == 0x40) raw = raw & ~1;
   regs[MBS_ds1+k]= (uint16_t) ( ((float)raw / 16.0) * 100); // celsius = 23.75 -> celsius_int = 2375
   k=k+1;
    
     
  
  if((millis() - lastUpdatedht) > 2000) // time to update DHT22 Sensor
    {
        lastUpdatedht = millis();
        regs[MBS_DHT_t] = (uint16_t)(dht.readTemperature()*100);
        regs[MBS_DHT_h] = (int)(dht.readHumidity()*100);
        
    }
 
  slave.poll( regs, MBS_REGS );
}

impluse:
I use OnWire.h library for reading the Value of DS18B20, the problem is It use delay() function in its code that cause a modbus does't work fine , how can i remove delay() from my code and ds18b20 works fine , I use DHT22 with millis() that work fine and every 2 second update the value of it,
but for multiple ds18b20 i could not remove delay()

Not trying to sound mean, but are your fingers broken? Why can't you remove delay() from your code for the multiple ds18b20s? Try just deleting them. You might not even need them in the first place.

if i remove delay from the code Arduino can't get value of ds18b20 sensors because at least needed
750 ms for conversion that is why it used second delay in code delay(1000)

impluse:
if i remove delay from the code Arduino can't get value of ds18b20 sensors because at least needed
750 ms for conversion that is why it used second delay in code delay(1000)

Ok, then why not write the code to where you request the data, use millis() to wait 750ms, and then check for the data from the sensors?

I tried to write the code without delay for ds18b20 but it doesn’t work , that’s my code that remove delay and use milis :

    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);        // start conversion, with parasite power on at the end
                                    // needed 1000ms delay 
                                    
    if((millis() - lastUpdate) > 1000) // time to update
    {
        lastUpdate = millis();
        ds.reset();
        ds.select(addr);    
        ds.write(0xBE);           // Read Scratchpad
        for ( i = 0; i < 9; i++)
        {   // we need 9 bytes
          data[i] = ds.read();
        }
           
        //Convert the data to actual temperature
        int16_t raw = (data[1] << 8) | data[0];
        byte cfg = (data[4] & 0x60);
        if (cfg == 0x00) raw = raw & ~7;        
        else if (cfg == 0x20) raw = raw & ~3;   
        else if (cfg == 0x40) raw = raw & ~1;
        regs[k]= (uint16_t) ( ((float)raw / 16.0) * 100); // celsius = 23.75 -> celsius_int = 2375
        k=k+1;
        
    }

It’s necessary to put at least 750ms delay between ds.write(0x44,1) and ds.reset() :

    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);        // start conversion, with parasite power on at the end
    
    //delay(1000);

    ds.reset();
    ds.select(addr);    
    ds.write(0xBE);           // Read Scratchpad
    for ( i = 0; i < 9; i++)
    {   // we need 9 bytes
       data[i] = ds.read();
    }

I think something else is going on. The delay should not cause a problem, it just stops Arduino from doing anything. You are right in that the DS18B20 needs time to do its job, and this is a fair way of ensuring that, so the problem is more likely to lie with the other stuff, not DS18B20.

Having said that, the DS18B20 code is obsolete junk and you would be better off, and likely get better assistance if you use the Dallas temperature library like everybody else does, thereby simplifying the matter.

An example is at
http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html

Why you need to do all this is far from clear. What you describe seems well within the ambit of Arduino and, if you really need a Raspberry Pi for whatever, I would imagine the Arduino is redundant.

I Solved the problem and removed delay() func from my code without causes any problem to reading temeprature of DS18B20 .
It’s my code that works fine: (DS18B20 part)
I used Flag and millis instead of delay

  if( !ds.search(addr) && k==7 )
  {
    ds.reset_search();
    k=0;
    //delay(250);
    return;
  }

  if(next == 1 && ((millis() - lastUpdateds) > 750) ) // time to update
  {
    lastUpdateds = millis();
    ds.reset();
    ds.select(addr);    
    ds.write(0xBE);           // Read Scratchpad
    for ( i = 0; i < 9; i++)
    {   
       data[i] = ds.read();
    }
    //Convert the data to actual temperature
    int16_t raw = (data[1] << 8) | data[0];
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw & ~7;        
    else if (cfg == 0x20) raw = raw & ~3;   
    else if (cfg == 0x40) raw = raw & ~1;
    regs[MBS_ds1+k]= (uint16_t) ( ((float)raw / 16.0) * 100); // celsius = 23.75 -> celsius_int = 2375
    k=k+1;
    next = 0;
  }

  if(next == 0 )
  {
    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);
    next = 1;
  }

Nick_Pyner:
Why you need to do all this is far from clear. What you describe seems well withing the ambit of Arduino and, if you really need a Raspberry Pi for whatever, I would imagine the Arduino is redundant.

I want to control multiple Arduino(slave) from one Raspberry(master), in the other words slaves work with sensors , do actions and … But Master which i connect to it through the internet show me the status of slaves and control them.