ModbusMaster icon indicating copy to clipboard operation
ModbusMaster copied to clipboard

multiple slave id

Open heydan98 opened this issue 1 year ago • 2 comments

I want to use esp32 read multiple Rs485 but i don't find way to set multiple slave id. Can you help me, please! This is my code: // Define an array of sensor addresses const uint8_t SENSOR_ADDRESSES[] = {0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08}; const int NUM_SENSORS = sizeof(SENSOR_ADDRESSES) / sizeof(SENSOR_ADDRESSES[0]);

// ... existing code ...

void setup() { // ... existing setup code ...

// Initialize ModbusMaster without specifying an address node.begin(0, Serial2); node.preTransmission(preTransmission); node.postTransmission(postTransmission);

// ... rest of setup code ... }

void loop() { // ... existing loop code ...

if (start_init == false && dataSent == true && (millis() - lastMsg >= 1000) && modeWifiSelect == "AWS") { // ... existing connection code ...

// Loop through each sensor address
for (int i = 0; i < NUM_SENSORS; i++) {
  uint8_t currentAddress = SENSOR_ADDRESSES[i];
  
  // Set the current sensor address
  node.setSlaveID(currentAddress);

  Serial.print("Reading sensor at address: 0x");
  Serial.println(currentAddress, HEX);

  // Perform read operation for the current sensor
  // You'll need to adjust the register addresses and data processing for each sensor type
  uint8_t result = node.readHoldingRegisters(0x0000, 4);

  if (result == node.ku8MBSuccess) {
    // Process and publish data for the current sensor
    processSensorData(currentAddress);
  } else {
    handleReadError(currentAddress, result);
  }

  // Add a small delay between sensor reads
  delay(100);
}

// ... rest of your loop code ...

}

// ... rest of your loop code ... }

void processSensorData(uint8_t sensorAddress) { // Process and publish data based on the sensor address switch (sensorAddress) { case 0x01: // O3 sensor processO3Data(); break; case 0x02: // NH4 sensor processNH4Data(); break; // Add cases for other sensor types default: Serial.println("Unknown sensor type"); } }

void processO3Data() { // Extract O3 value uint16_t O3_high = node.getResponseBuffer(2); uint16_t O3_low = node.getResponseBuffer(3);

uint32_t O3_combined = (uint32_t)O3_low << 16 | O3_high; float O3_value = ((float)&O3_combined);

String payload_O3 = "{"O3":" + String(O3_value, 2) + "}"; client.publish("v1/devices/me/telemetry", payload_O3.c_str()); }

void processNH4Data() { // Process NH4 data similarly to O3 // Adjust based on the actual data format of your NH4 sensor }

void handleReadError(uint8_t sensorAddress, uint8_t errorCode) { Serial.print("Failed to read from sensor at address 0x"); Serial.print(sensorAddress, HEX); Serial.print(". Error code: "); Serial.println(errorCode, HEX);

String sensorType = getSensorType(sensorAddress); String payload = "{"" + sensorType + "":NaN}"; client.publish("v1/devices/me/telemetry", payload.c_str()); }

String getSensorType(uint8_t sensorAddress) { switch (sensorAddress) { case 0x01: return "O3"; case 0x02: return "NH4"; case 0x03: return "NO3"; case 0x04: return "DO"; case 0x06: return "NO2"; case 0x07: return "Cl"; case 0x08: return "pH"; default: return "Unknown"; } }

// ... rest of your code ...

heydan98 avatar Sep 28 '24 04:09 heydan98

Use node.begin or change library

nikito7 avatar Nov 07 '24 00:11 nikito7

The code is set up to handle multiple slave IDs, and it reads data from the connected sensors sequentially. Here, I have made some changes that will be helpful to you.

Code

// I want to use ESP32 to read multiple RS485 sensors, but I don't find a way to set multiple slave IDs. Can you help me, please? This is my code:

// Define an array of sensor addresses
const uint8_t SENSOR_ADDRESSES[] = { 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08 };  // SlaveID
const int NUM_SENSORS = sizeof(SENSOR_ADDRESSES) / sizeof(SENSOR_ADDRESSES[0]);

// ... existing code ...

void setup() {
  // ... existing setup code ...

  // Initialize ModbusMaster without specifying an address
  /* Remove this
  node.begin(0, Serial2);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  */

  // ... rest of setup code ...
}

void loop() {
  // ... existing loop code ...

  if (start_init == false && dataSent == true && (millis() - lastMsg >= 1000) && modeWifiSelect == "AWS") {
    // ... existing connection code ...

    // Loop through each sensor address
    for (int i = 0; i < NUM_SENSORS; i++) {
      int currentAddress = SENSOR_ADDRESSES[i];

      // Set the current sensor address
      // node.setSlaveID(currentAddress);  // Remove

      // Changes
      node.begin(currentAddress, Serial2);
      node.preTransmission(preTransmission);
      node.postTransmission(postTransmission);
      // put some delay to start proper communication
      // Half second delay
      long int waitTime = millis();
      while ((waitTime + 500) > millis()) {
      }

      Serial.print("Reading sensor at address: 0x");
      Serial.println(currentAddress, HEX);

      // Perform read operation for the current sensor
      // You'll need to adjust the register addresses and data processing for each sensor type
      uint8_t result = node.readHoldingRegisters(0x0000, 4);

      if (result == node.ku8MBSuccess) {
        // Process and publish data for the current sensor
        processSensorData(currentAddress);
      } else {
        handleReadError(currentAddress, result);
      }

      // Add a small delay between sensor reads
      delay(100);
    }

    // ... rest of your loop code ...
  }

  // ... rest of your loop code ...
}

void processSensorData(uint8_t sensorAddress) {
  // Process and publish data based on the sensor address
  switch (sensorAddress) {
    case 0x01:  // O3 sensor
      processO3Data();
      break;
    case 0x02:  // NH4 sensor
      processNH4Data();
      break;
    // Add cases for other sensor types
    default:
      Serial.println("Unknown sensor type");
  }
}

void processO3Data() {
  // Extract O3 value
  uint16_t O3_high = node.getResponseBuffer(2);
  uint16_t O3_low = node.getResponseBuffer(3);

  uint32_t O3_combined = (uint32_t)O3_low << 16 | O3_high;
  float O3_value = ((float)&O3_combined);

  String payload_O3 = "{" O3 ":" + String(O3_value, 2) + "}";
  client.publish("v1/devices/me/telemetry", payload_O3.c_str());
}

void processNH4Data() {
  // Process NH4 data similarly to O3
  // Adjust based on the actual data format of your NH4 sensor
}

void handleReadError(uint8_t sensorAddress, uint8_t errorCode) {
  Serial.print("Failed to read from sensor at address 0x");
  Serial.print(sensorAddress, HEX);
  Serial.print(". Error code: ");
  Serial.println(errorCode, HEX);

  String sensorType = getSensorType(sensorAddress);
  String payload = "{"
                   " + sensorType + "
                   ":NaN}";
  client.publish("v1/devices/me/telemetry", payload.c_str());
}

String getSensorType(uint8_t sensorAddress) {
  switch (sensorAddress) {
    case 0x01: return "O3";
    case 0x02: return "NH4";
    case 0x03: return "NO3";
    case 0x04: return "DO";
    case 0x06: return "NO2";
    case 0x07: return "Cl";
    case 0x08: return "pH";
    default: return "Unknown";
  }
}

// ... rest of your code ...

miteshrabadiaaru avatar Dec 26 '24 07:12 miteshrabadiaaru