iot/modbus_npk.ino
Dodit Suprianto 4476154912 initiation
2024-10-15 10:03:29 +07:00

176 lines
5.8 KiB
C++

#include <ModbusMaster.h>
// Instantiate ModbusMaster object
ModbusMaster sensor;
// Define the pins for RS485 communication
const int RX_PIN = 16; // Set to the RX pin you are using for Serial2
const int TX_PIN = 17; // Set to the TX pin you are using for Serial2
const int RE = 19; // Control the transmit/receive mode of RS485 module
const int DE = 18; // Control the transmit/receive mode of RS485 module
// milis()
unsigned long previousMillis1 = 0; // Store the last time sensor 1 was read
unsigned long previousMillis2 = 0; // Store the last time sensor 2 was read
const long interval1 = 500; // Interval for sensor 1 (500 ms = 0.5 second)
const long interval2 = 1000; // Interval for sensor 1 (1000 ms = 1 second)
// Variables to store sensor data
uint16_t sensor1Data[7]; // Array to store data from Sensor 1
uint16_t sensor2Data[7]; // Array to store data from Sensor 2
void preTransmission() {
digitalWrite(RE, HIGH);
digitalWrite(DE, HIGH);
}
void postTransmission() {
digitalWrite(RE, LOW);
digitalWrite(DE, LOW);
}
void setup() {
Serial.begin(9600); // Serial communication for debugging
Serial2.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); // Configure Serial2 for RS485
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
digitalWrite(RE, LOW);
digitalWrite(DE, LOW);
// Modbus communication setup for sensors
sensor.begin(1, Serial2); // Address of the first sensor
sensor.preTransmission(preTransmission);
sensor.postTransmission(postTransmission);
sensor.begin(2, Serial2); // Address of the first sensor
sensor.preTransmission(preTransmission);
sensor.postTransmission(postTransmission);
delay(1000); // Allow sensor to stabilize
Serial.println("Setup complete, starting communication...");
}
void loop() {
unsigned long currentMillis = millis(); // Get the current time
// Check if it's time to read sensor 1
if (currentMillis - previousMillis1 >= interval1) {
previousMillis1 = currentMillis; // Save the last time you read the sensor
sensor.begin(1, Serial2); // Begin communication with sensor 1
readNPK("Sensor 1", sensor1Data); // Read data from sensor 1
}
// Check if it's time to read sensor 2
if (currentMillis - previousMillis2 >= interval2) {
previousMillis2 = currentMillis; // Save the last time you read the sensor
sensor.begin(2, Serial2); // Begin communication with sensor 2
readNPK("Sensor 2", sensor2Data); // Read data from sensor 2
}
delay(5000);
}
void readNPK(const char* sensorName, uint16_t* data) {
uint8_t result;
Serial.print("Requesting data from ");
Serial.println(sensorName);
result = sensor.readHoldingRegisters(0x0000, 7); // Start address 0x0000, reading 7 registers
if (result == sensor.ku8MBSuccess) {
data[0] = sensor.getResponseBuffer(0x00); // Humidity
data[1] = sensor.getResponseBuffer(0x01); // Temperature
data[2] = sensor.getResponseBuffer(0x02); // Conductivity
data[3] = sensor.getResponseBuffer(0x03); // PH
data[4] = sensor.getResponseBuffer(0x04); // Nitrogen (N)
data[5] = sensor.getResponseBuffer(0x05); // Phosphorus (P)
data[6] = sensor.getResponseBuffer(0x06); // Potassium (K)
Serial.print(sensorName);
Serial.print(" - Humidity: ");
Serial.print(data[0] * 0.1);
Serial.println(" %RH");
Serial.print(sensorName);
Serial.print(" - Temperature: ");
Serial.print(data[1] * 0.1);
Serial.println(" °C");
Serial.print(sensorName);
Serial.print(" - Conductivity: ");
Serial.print(data[2]);
Serial.println(" us/cm");
Serial.print(sensorName);
Serial.print(" - PH: ");
Serial.print(data[3] * 0.1);
Serial.println();
Serial.print(sensorName);
Serial.print(" - Nitrogen (N): ");
Serial.print(data[4]);
Serial.println(" mg/kg");
Serial.print(sensorName);
Serial.print(" - Phosphorus (P): ");
Serial.print(data[5]);
Serial.println(" mg/kg");
Serial.print(sensorName);
Serial.print(" - Potassium (K): ");
Serial.print(data[6]);
Serial.println(" mg/kg");
} else {
Serial.print(sensorName);
Serial.print(" - Failed to read sensor data, Error code: ");
Serial.println(result);
}
}
void verifyAddresses() {
// Scan Modbus addresses from 1 to 10
// check the available address in modbus
for (uint8_t address = 1; address <= 10; address++) {
sensor.begin(address, Serial2); // Set the Modbus address for the current scan
Serial.print("Checking address: ");
Serial.println(address);
// address register from datasheet (0x0000..0xFFFF)
// address register remotely (1..125, enforced by remote device)
uint8_t result = sensor.readHoldingRegisters(0x0000, 1); // Try to read from a known register/address in modbus
// ku8MBSuccess adalah kode hasil (return code) yang menandakan kesuksesan ketika mengirim atau menerima data dalam protokol Modbus.
if (result == sensor.ku8MBSuccess) {
Serial.print("Device found at address: ");
Serial.println(address);
} else {
Serial.print("No response from address: ");
Serial.println(address);
}
delay(200); // Small delay to avoid bus contention during the scan
}
Serial.println("Modbus address scan complete.");
delay(10000); // Wait for 10 seconds before scanning again
}
void changeDeviceAddress() {
// 0x07D0 adalah alamat register yang mengatur slave ID atau alamat Modbus dari perangkat
// 1 pada code ini adalah alamat yang akan digunakan
// jika ingin mengubah alamat menjadi 3.
// maka ubah angka 1 menjadi 3
// saat menjalankan ini pastikan hanya ada satu sensor yang terhubung
uint8_t result = sensor.writeSingleRegister(0x07D0, 1); // Register 0x07D0 is for the slave ID
if (result == sensor.ku8MBSuccess) {
Serial.println("Successfully changed sensor address from 2 to 1.");
} else {
Serial.print("Failed to change sensor address, Error code: ");
Serial.println(result);
}
}