Dans le cadre d'un projet, je souhaite lire des données de temperature et d'hygrométrie à partir de capteurs branchés sur le port RS485 MODBUS de mon Arduino OPTA.
Avec l'aide du forum et de ses anciens sujets, j'ai réussi à programmer sans trop de soucis pour lire les valeurs de mes capteurs un par un. Il faut maintenant que j'attribue une adresse esclave à chacun de mes capteurs afin de pouvoir les utiliser tous les trois en même temps mais c'est ici que je bloque.
Auriez vous une solution pour reprogrammer mes capteurs sur une nouvelle adresse ? J'ai la doc de mes capteurs que je vous partage avec. J'ai fais plusieurs tentatives mais rien de concluant, je pense que je m'y prend mal pour coder...
What you posted does not help much. You need to post links to the user manual and the programing/applications manual for this device. From what I can determine it is designed to be the only one on the bus.
J'ai moi aussi rencontré ce problème il y a quelques semaine. Tu peux essayer ce code, il devrait fonctionner. Tu as simplement à spécifier les adresses esclaves d'origine ainsi que la nouvelle. Tu peux également modifier le baud rates. Ce code fonctionne avec tous ces types de capteurs. Pour d'autres, je ne sais pas, je n'ai jamais essayé.
/* Opta WiFi – ID →13 puis baud →9600
– Un seul capteur branché
– Bus RS-485 : UART2, 4800 bps pendant toute la procédure
*/
#include <Arduino.h>
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
constexpr uint32_t BAUD4800 = 4800;
constexpr uint32_t BAUD9600 = 9600;
constexpr uint8_t OLD_ID = 1; // adresse d’origine
constexpr uint8_t NEW_ID = 13; // nouvelle adresse souhaitée
constexpr uint16_t REG_ID = 0x07D0;
constexpr uint16_t REG_BR = 0x07D1;
void initBus(uint32_t b)
{
RS485.begin(b, SERIAL_8N1, 2);
uint32_t bitUs = 1'000'000UL / b;
uint32_t t3_5 = bitUs * 96 / 10 * 35 / 10; // délai 3,5 caractères
RS485.setDelays(t3_5, t3_5);
ModbusRTUClient.begin(RS485, b, SERIAL_8N1);
}
bool writeReg(uint8_t id, uint16_t reg, uint16_t val)
{
return ModbusRTUClient.holdingRegisterWrite(id, reg, val);
}
void setup()
{
Serial.begin(115200);
while (!Serial);
/* 1 – bus à 4800 bps */
initBus(BAUD4800);
Serial.print(F("ID 1 → 11 : "));
if (writeReg(OLD_ID, REG_ID, NEW_ID)) Serial.println(F("OK"));
else { Serial.println(F("échec")); while (1); }
delay(300); // le capteur répond déjà sous ID 11
Serial.print(F("4800 → 9600 : "));
if (writeReg(NEW_ID, REG_BR, 2)) // ← utiliser **la nouvelle adresse**
Serial.println(F("OK"));
else { Serial.println(F("échec")); while (1); }
delay(600); // le capteur redémarre en 9600
/* 2 – maître Opta passe à 9600 bps, toujours ID 11 */
initBus(BAUD9600);
// lecture de contrôle (1 registre) :
if (ModbusRTUClient.requestFrom(NEW_ID, INPUT_REGISTERS, 0x0000, 1))
Serial.println(F("🎉 Capteur trouvé sous ID 11 à 9600 bps"));
else {
Serial.print(F("⛔ Pas de réponse, code "));
Serial.println(ModbusRTUClient.lastError());
}
}
void loop() {}
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
constexpr auto baudrate { 4800 };
constexpr auto btime { 1.0f / baudrate };
constexpr auto predl { btime * 9.6f * 3.5f * 1e6 };
constexpr auto postdl { btime * 9.6f * 3.5f * 1e6 };
float temperature;
float humidity;
void setup() {
Serial.begin(115200);
delay(2000);
RS485.setDelays(predl, postdl);
if (!ModbusRTUClient.begin(baudrate, SERIAL_8N1)) {
Serial.println("Erreur Modbus");
while (1);
}
}
void loop() {
// Demande la lecture de 2 registres d'entrée du capteur esclave ID 1, à partir du registre 0x00
if (!ModbusRTUClient.requestFrom(1, INPUT_REGISTERS, 0x00, 2)) {
Serial.print("Échec lecture des registres ! Erreur : ");
Serial.println(ModbusRTUClient.lastError());
} else {
if (ModbusRTUClient.available() == 2) { // Vérifie que deux registres sont disponibles
// Lecture des valeurs brutes
short rawHumidity = ModbusRTUClient.read();
short rawTemperature = ModbusRTUClient.read();
// Conversion en valeurs réelles
temperature = rawTemperature / 10.0;
humidity = rawHumidity / 10.0;
// Affichage des valeurs
Serial.print("Température : ");
Serial.print(temperature);
Serial.println(" °C");
Serial.print("Humidité : ");
Serial.print(humidity);
Serial.println(" %");
} else {
Serial.println("Nombre de registres lus incorrect !");
}
}
delay(5000);
}
PS : ce code est en partie généré avec de l'intelligence artificiel après pas mal d'itérations pour enfin trouver la bonne version.