Change i2c communication (one master n slave) to UART RS485 MODBUS

Hi I have one master and ask in loop n slaves for data, for example sensor data, if is button clicked, ...
And for example, when I have info about button, I send same data to slave.
I ask data from slave, and also can send data to slave.

Is this possible do with UART RS485 MODBUS?, And if yes how?

// MASTER
#include <Wire.h>

const byte START_BYTE = 254;
const byte END_BYTE = 255;

enum {StartByte, Id, Type, ValueHight, ValueLow, EndByte};

// type: 1:button, 2:humidity, 3:temperaure
enum {TypeButton = 1, TypeHumidity = 2, TypeTemperaure = 3};

byte devices[] = { 2, 3, 66 } ;
byte message[6];
byte light1;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  for ( int i = 0; i < sizeof(devices); ++i ) {
    int device = devices[i];
    memset(message, 0, 6);

    Wire.requestFrom(device, 6);
    while (Wire.available()) {

      message[StartByte] = Wire.read();
      message[Id] = Wire.read();
      message[Type] = Wire.read();

      message[ValueHight] = Wire.read();
      message[ValueLow] = Wire.read();

      message[EndByte] = Wire.read();
    }

    // validation
    if (message[StartByte] == START_BYTE and message[EndByte] == END_BYTE) {

      int value = message[ValueLow] + message[ValueHight] * 256;

      switch (message[Type]) {
        case TypeButton:
          processButton(device, message[Id], value);
          break;
        case TypeHumidity:
          processHumidity(device, message[Id], value);
          break;
        case TypeTemperaure:
          processTemperaure(device, message[Id], value);
          break;
      }
    }
  }
}

void processButton(int device, int id, int value) {
  Serial.println("Button:" );
  Serial.print(device);
  Serial.print(".");
  Serial.print(id);
  Serial.print(" : ");
  Serial.println(value);
  Serial.println("-------------" );

  if (device == 2 and id == 1) {
    light1 = !light1;
    processLight(LED_BUILTIN, light1);

    Wire.beginTransmission(device);
    Wire.write(light1);
    Wire.endTransmission();
  }
}

void processHumidity(int device, int id, int value) {
  Serial.println("Humidity:" );
  Serial.print(device);
  Serial.print(".");
  Serial.print(id);
  Serial.print(" : ");
  Serial.println(value);
  Serial.println("-------------" );
}

void processTemperaure(int device, int id, int value) {
  Serial.println("Temperaure:" );
  Serial.print(device);
  Serial.print(".");
  Serial.print(id);
  Serial.print(" : ");
  Serial.println(value);
  Serial.println("-------------" );
}

void processLight(byte no, byte value) {
  digitalWrite(no, value);
}
// Slave
#include <util/delay.h>
#include <Wire.h>

enum {StartByte, Id, Type, ValueHight, ValueLow, EndByte};

// type: 1:button, 2:humidity, 3:temperaure
enum {TypeButton = 1, TypeHumidity = 2, TypeTemperaure = 3};

const byte MY_ADDRESS = 2;
const byte START_BYTE = 254;
const byte END_BYTE = 255;
const byte CLEAR_BYTE = 253;

byte button1[6];
byte humidity[6];
byte temperaure[6];

unsigned long previousMillis = 0;
const long interval = 10000; // reset sensors

unsigned long previousMillis2 = 0;
const long interval2 = 1000;
int ledState = LOW;

void setup() {
  Wire.begin(MY_ADDRESS);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);

  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(2, INPUT);

  attachInterrupt(digitalPinToInterrupt(2), checkTicks, RISING);
}

void loop() {

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    memset(humidity, 0, sizeof(humidity));
    memset(temperaure, 0, sizeof(temperaure));
  }

  unsigned long currentMillis2 = millis();
  if (currentMillis2 - previousMillis2 >= interval2) {
    previousMillis2 = currentMillis2;

    ledState = !ledState;
    digitalWrite(8, ledState);
  }

  if (humidity[StartByte] == 0 and humidity[EndByte] != CLEAR_BYTE) {
    int value1 = random(0, 1023);
    createMeaagage(humidity, 1, TypeHumidity, value1);
  }

  if (temperaure[StartByte] == 0 and temperaure[EndByte] != CLEAR_BYTE) {
    int value2 = random(0, 1023);
    createMeaagage(temperaure, 1, TypeTemperaure, value2);
  }
}

void checkTicks() {
  createMeaagage(button1, 1, TypeButton, sizeof(button1));
}

void createMeaagage(byte mb[6], byte id, byte type, int value) {
  mb[StartByte] = START_BYTE;
  mb[Id] = id;
  mb[Type] = type;

  mb[ValueHight] = (value - (value % 256)) / 256; //byte s vyšší hodnotou
  mb[ValueLow] = value % 256; //byte s nižší hodnotou - 1

  mb[EndByte] = END_BYTE;
}

void requestEvent() {
  if (button1[StartByte] == START_BYTE and button1[EndByte] == 255) {
    Wire.write(button1, 6);
    clearMessage(button1);
  } else if (temperaure[StartByte] == START_BYTE and temperaure[EndByte] == 255) {
    Wire.write(temperaure, 6);
    clearMessage(temperaure);
  } else if (humidity[StartByte] == START_BYTE and humidity[EndByte] == 255) {
    Wire.write(humidity, 6);
    clearMessage(humidity);
  }
}

void clearMessage(byte mb[6]) {
  memset(mb, 0, 6);
  mb[EndByte] = CLEAR_BYTE;
}


void receiveEvent(int howMany)
{
  byte value = Wire.read();
  digitalWrite(7, value);
}

Do I understand that right, you want to replace the existing communication on I2C by Modbus RTU?

Yes, this is possible. Provide an RS485 converter chip (p.e. MAX485) to every node (including the master) and connect all A and all B and all GND. Select the Modbus master and slave library that fits your needs best.

If you need more information provide details about your setup and what exactly you're trying to achieve.