bonjour les amis je suis entrain de programmer mon arduino nano pour la communication avec mon automate , je travaille avec la bibliotheque <SimpleModbusSlave.h> j'arrive a envoyer les informations des sonde a l'automate tel que la température .. la question qui me perturbe c'est que je veux que l'automate puisse écrire dans un registre que je l'ai déja déclarer dans mon programme pour que je puisse faire des condition .
Merci kamil ,j'ai une question hort sujet de la cummunication modbus
vous savais que j'utilise un multiplexeur tca9548a pour communiquer avec mes sonde en i2c et je ne veux pas passer par la boucle
vu que je vais travailler avec des condition dans chaque sonde il faut que je les sépare à mon avis
je veux passer par chaque adresse indépendamment comme ca
oui pas c'est pas ca le probleme je pense bon voila le code que j'ai fait si vous pouvez jeté un oeil j'essaye d'envoyer les valeur en modbus et il y as une erreur de communication
#include <Wire.h>
#include <SHTSensor.h>
#include <SimpleModbusSlave.h>
#define TCAADDR 0x70
const byte NBSENSORS =2;
byte i=0;
SHTSensor sht;
// To use a specific sensor instead of probing the bus use this command:
// SHTSensor sht(SHTSensor::SHT3X);
float Humidity ;
float Temperature;
enum
{
SHT_ETAT, // etat du premier sht
SHT_TEMP, // température lue sur le premier sht
SHT_HUM, // humidité lue sur le premier sht
SHT_NBREGS, // nombre de registres par sht
BOITIER,
TOTAL_ERRORS = SHT_NBREGS * NBSENSORS, // reserve la place et numéro du registre d'erreur
HOLDING_REGS_SIZE // nombre total de registres
};
unsigned int holdingRegs[HOLDING_REGS_SIZE];
void setup() {
modbus_configure(&Serial1, 38400, SERIAL_8E1, 199, 2, HOLDING_REGS_SIZE, holdingRegs);
modbus_update_comms(38400, SERIAL_8E1, 199);
// put your setup code here, to run once:
//Serial.begin(9600);
Wire.begin();
// Serial.begin(38400);
//delay(1000); // let serial console settle
tcaselect(0); // sélectionne le sht qui va bien
if (sht.init()) {
//Serial.print("init(): success\n");
// holdingRegs[3i+2]=(int16_t) (1);
} else {
// Serial.print("init(): failed\n");
//holdingRegs[3i+3]=(int16_t) (0);
}
sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM); // only supported by SHT3x
}
void loop() {
tcaselect(0);
//Serial.print("SHT: ");
if (sht.readSample()) {
Humidity = sht.getHumidity();
holdingRegs[0] = (int16_t)(100 * Humidity);
Temperature = sht.getTemperature();
holdingRegs[1] = (int16_t)( 100 * Temperature);
holdingRegs[2] = 1; // indique etat OK
}
}
void tcaselect(uint8_t i) {
//if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << 7);
Wire.endTransmission();
}
vu que je vais utiliser de capteur i2c et des capteur analogique et numérique et envoyer ces information en modbus , j'ai pensé , a attribuer chaque capteur avec ces registre manuellement sans l'utilisation des boucle
voila le code
#include <Wire.h>
#include <SHTSensor.h>
#include <SimpleModbusSlave.h>
#define TCAADDR 0x70
const byte NBSENSORS =2;
byte i;
SHTSensor sht;
// To use a specific sensor instead of probing the bus use this command:
// SHTSensor sht(SHTSensor::SHT3X);
float Humidity ;
float Temperature;
enum
{
//SHT_ETAT, // etat du premier sht
//SHT_TEMP, // température lue sur le premier sht
// SHT_HUM, // humidité lue sur le premier sht
//SHT_NBREGS, // nombre de registres par sht
// BOITIER,
// TOTAL_ERRORS = SHT_NBREGS * NBSENSORS, // reserve la place et numéro du registre d'erreur
HOLDING_REGS_SIZE, // nombre total de registres
};
unsigned int holdingRegs[HOLDING_REGS_SIZE];
void setup() {
modbus_configure(&Serial1, 38400, SERIAL_8E1, 199, 2, HOLDING_REGS_SIZE, holdingRegs);
modbus_update_comms(38400, SERIAL_8E1, 199);
// put your setup code here, to run once:
//Serial.begin(9600);
Wire.begin();
// Serial.begin(38400);
//delay(1000); // let serial console settle
for (byte i = 0; i < NBSENSORS; i++)
{
tcaselect(i); // sélectionne le sht qui va bien
if (sht.init()) {
// Serial.print("init(): success\n");
holdingRegs[3] = 1;
sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM); // only supported by SHT3x
}
else
{
// Serial.print("init(): failed\n");
holdingRegs[3] = 0;
}
}
}
void loop() {
tcaselect(0);
if (sht.readSample()) {
Humidity = sht.getHumidity();
// Serial.print(Humidity);
holdingRegs[0] = (int16_t)(100 * Humidity);
Temperature = sht.getTemperature();
holdingRegs[1] = (int16_t)( 100 * Temperature);
holdingRegs[2] = 1; // indique etat OK
}
tcaselect(1);
if (sht.readSample()) {
Humidity = sht.getHumidity();
Serial.print(Humidity);
holdingRegs[3] = (int16_t)(100 * Humidity);
Temperature = sht.getTemperature();
holdingRegs[4] = (int16_t)( 100 * Temperature);
holdingRegs[5] = 1; // indique etat OK
}
modbus_update();
}
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1<<i);
Wire.endTransmission();
}
Bonjour Kamill effectivement j'ai corriger la faute et ça marche ,
le soucis maintenant c'est que j'ai déclarer 34 registre et quand je dépasse les 28 registre,le Programme QmodbusSlave commence par m'afficher une erreur et inférieur ou egale à 28 ca fonctionne normal
Quand tu parles du programme QmodbusSlave, je suppose que tu veux parler de QmodMaster.
Je ne sais pas si le problème vient de la librairie ou de QmodMaster.
En tout cas tu n'es pas obligé de lire tous les registres à la fois. Tu peux lire uniquement les registres qui t'intéressent ou lire les registres en plusieurs fois.
Note:
The Arduino serial ring buffer is 64 bytes or 32 registers.
Most of the time you will connect the arduino to a master via serial
using a MAX485 or similar.
In a function 3 request the master will attempt to read from your
slave and since 5 bytes is already used for ID, FUNCTION, NO OF BYTES
and two BYTES CRC the master can only request 58 bytes or 29 registers.
In a function 16 request the master will attempt to write to your
slave and since a 9 bytes is already used for ID, FUNCTION, ADDRESS,
NO OF REGISTERS, NO OF BYTES and two BYTES CRC the master can only write
54 bytes or 27 registers.
Using a USB to Serial converter the maximum bytes you can send is
limited to its internal buffer which differs between manufactures.
*/
Bonjour j'ai trouvé ca dans les commentaires du programme , j'ai pas bien compris mais je pense que c'est un probleme de librairie
j'ai pas bien compris quand vous dites que je suis pas obligé de lire tous les registres à la fois