Buongiorno a tutti
vorrei chiedere gentilmente un piccolo aiuto ad implementare sul mio codice la lettura di più slave.
riesco a far comunicare master e slave ma non ho capito come inserire più ID slave da leggere.
non sono sicuro ma credo che utilizzando switch case si possa fare (ho letto che é possibile cosi)
allego codice master grazie a tutti
MASTER_ev_4_stati_pulsanti_slave___pulsante_comando_coil_slave.ino (3.98 KB)
ciao
dovresti usare uil metodo della classe:
void setSlave(uint8_t);
Ciao Orso mi puoi dare qualche link o esempio grazie..
cmq ho cercato di risolvere cosi ma non funziona tanto bene.
in pratica lo slave 1 funziona invece il 2 lavora lento e se nel master non stampo più niente
non funziona del tutto, credo dipenda dalla chiamata che il master fa allo slave. Allego il codice
MASTER_ev_4_stati_pulsanti_slave___pulsante_comando_coil_slave.ino (4.29 KB)
ciao,
semplicemente tu crei il tuo oggetto ModBus tipo:
ModbusMaster node;
poi lo inizializzi passandogli l'ID 1 e la tua seriale:
node.begin(1, RS485Serial);
quando ti serve nel tuo programma gli cambi ID con:
node.setSlave(2);
da quel momento il tuo Oggetto node avrà l'ID su cui "punta" impostato a 2...per ritornare ad 1 devi richiamare ancora il metodo setSlave().
detto questo una mia opinione sul tuo programma...non mi pare di aver visto nessun "interblocco" tra i due pulsanti...anche se i metodi di lettura e scrittura della libreria modBus sono "bloccanti" ci metterei sembre un qualche cosa che se premuto un pusante l'altro non fa nulla.
seconda cosa...nel verificare se un pulsante è premuto tu invii una richiesta modbus solo se node.ku8MBSuccess vale "0"...e se non lo fosse per un errore precedente!?...generalmente si invia la richiesta...dopo si valuta il risultato...e nel caso si gestiscono le eccezioni...anzi le eccezioni si gestiscono nel modo corretto!
poi alla fine del programma vedo una serie di node.readDiscreteInputs "liberi" nel loop()...come to dicevo i vari metodi della classe modBus sono bloccanti in quanto inviano il comando ed attendono la risposta.
Ciao Orso
non ho capito come fai a cambiare id con il metodo setslave(1)/ setslave(2).
quando ho:
if (ingresso1 == HIGH)
{
result1 = node.writeSingleCoil(0x000C, led1);
if (result1 == node.ku8MBSuccess)
{
led1 = HIGH;
Serial.println("comando ON relè 1 slave modulo relè");
}
}
else if (ingresso1 == LOW)
{
result1 = node.writeSingleCoil(0x000C, led1);
if (result1 == node.ku8MBSuccess)
{
led1 = LOW;
}
}
come faccio a puntare all'id 1 o 2.
penso di aver corretto quello che intendevi dire riguardo all'invio di richiesta node.ku8MBSuccess vale "0"
quello che dovresti fare è una cosa tipo (vale solo per l'ID 1):
if (ingresso1 == HIGH)
{
node.setSlave(1);
result1 = node.writeSingleCoil(0x000C, led1);
if (result1 == node.ku8MBSuccess)
{
led1 = HIGH;
Serial.println("comando ON relè 1 slave modulo relè");
}
else {
//fare qualche cosa per getire l'eccezione!
}
}
else if (ingresso1 == LOW)
{
node.setSlave(1);
result1 = node.writeSingleCoil(0x000C, led1);
if (result1 == node.ku8MBSuccess)
{
led1 = LOW;
}
else {
//fare qualche cosa per getire l'eccezione!
}
}
comunque dato che l'ingresso o sarà sempre alto o basso tu scriverai continuamente...dovresti gestire solo il cambio stato dell'ingresso.
questa prova l'avevo già fatta ma mi da errore. sicuramente sbaglio a impostare node.setSlave(1).
//master
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#define MAX485_DE 2
SoftwareSerial RS485Serial(10, 11); // RX, TX
ModbusMaster node;
//Buttons
int button1 = 4;
int button2 = 6;
//Relays
int rl1 = 5;
int ingresso1 ;
//States for Relay and Button (1)
int LED_state1 = LOW; // the current state of the output pin
int reading1; // the current reading from the input pin
int previous1 = HIGH; // the previous reading from the input pin
int led1 = LOW;
int result = 0;
long time1 = 0;
long debounce1 = 200; // the debounce time, increase if the output flickers
void preTransmission()
{
digitalWrite(MAX485_DE, HIGH);
}
void postTransmission()
{
digitalWrite(MAX485_DE, LOW);
}
void setup()
{
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_DE, LOW);
// Modbus communication runs at 115200 baud
Serial.begin(9600);
RS485Serial.begin(9600);
// Modbus slave ID 1
node.begin(1, RS485Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
Serial.println("rs485 connessione...");
pinMode(4, INPUT);
pinMode(5, OUTPUT);
}
void loop()
{
reading1 = digitalRead(button1);
//Condition Relay 1
if (reading1 == HIGH && previous1 == LOW && millis() - time1 > debounce1)
{
if (LED_state1 == HIGH)
{
LED_state1 = LOW;
ingresso1 = LOW;
}
else
{
LED_state1 = HIGH;
ingresso1 = HIGH;
}
if (ingresso1 == HIGH)
{
node.setSlave(2);
result1 = node.writeSingleCoil(0x000C, led1);
if (result1 == node.ku8MBSuccess)
{
led1 = HIGH;
}
}
else if (ingresso1 == LOW)
{
node.setSlave(2);
result1 = node.writeSingleCoil(0x000C, led1);
if (result1 == node.ku8MBSuccess)
{
led1 = LOW;
}
}
time1 = millis();
}
previous1 = reading1;
result = node.readDiscreteInputs(0x4100,16);
if (result == node.ku8MBSuccess)
{
node.setSlave(1);
unsigned int nn = node.getResponseBuffer(0);
Serial.print("digital read 1: ");
Serial.println(nn);
if (nn == 1)
{
digitalWrite (5, HIGH);
}
else
{
digitalWrite (5, LOW);
}
}
}
qual'è l'errore?
di compilazione o di eccezione modbus?
nella compilazione. Penso nel dichiarare node.setSlave(1) o node.setSlave(2)
se guardi il codice ho cercato di correggerlo e quando inserisco id 1 o 2 non va
dammi il link di dove hai scaricato la libreria...magari stiamo parlando di due librerie diverse
se compili il codice oltre all'errore id slave ti da anche errore result1 non farci caso mi sono dimenticato a rinominare
ciao...ok...non è la libreria che intendevo io...in questa non c'è un metodo per cambiare l'ID dello slave...ma con poco lo puoi aggiungere....se vuoi ti spiego come.
ho provato cosi ma penso che non sia corretto
//master
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#define MAX485_DE 2
SoftwareSerial RS485Serial(10, 11); // RX, TX
ModbusMaster node;
//Buttons
int button1 = 4;
int button2 = 6;
//Relays
int rl1 = 5;
int ingresso1 ;
//States for Relay and Button (1)
int LED_state1 = LOW; // the current state of the output pin
int reading1; // the current reading from the input pin
int previous1 = HIGH; // the previous reading from the input pin
int deviceID = 1;
int led1 = LOW;
int result = 0;
long time1 = 0;
long debounce1 = 200; // the debounce time, increase if the output flickers
void preTransmission()
{
digitalWrite(MAX485_DE, HIGH);
}
void postTransmission()
{
digitalWrite(MAX485_DE, LOW);
}
void setup()
{
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_DE, LOW);
// Modbus communication runs at 115200 baud
Serial.begin(9600);
RS485Serial.begin(9600);
// Modbus slave ID 1
node.begin(deviceID, RS485Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
Serial.println("rs485 connessione...");
pinMode(4, INPUT);
pinMode(6, INPUT);
pinMode(5, OUTPUT);
}
void loop()
{
reading1 = digitalRead(button1);
//Condition Relay 1
if (reading1 == HIGH && previous1 == LOW && millis() - time1 > debounce1)
{
if (LED_state1 == HIGH)
{
LED_state1 = LOW;
ingresso1 = LOW;
}
else
{
LED_state1 = HIGH;
ingresso1 = HIGH;
}
if (ingresso1 == HIGH)
{
result = node.writeSingleCoil(0x000C, led1);
if (result == node.ku8MBSuccess)
{
led1 = HIGH;
}
}
else if (ingresso1 == LOW)
{
result = node.writeSingleCoil(0x000C, led1);
if (result == node.ku8MBSuccess)
{
led1 = LOW;
}
}
time1 = millis();
}
previous1 = reading1;
result = node.readDiscreteInputs(0x4100,16);
if (result == node.ku8MBSuccess)
{
unsigned int nn = node.getResponseBuffer(0);
Serial.print("digital read 1: ");
Serial.println(nn);
if (nn == 1)
{
digitalWrite (5, HIGH);
}
else
{
digitalWrite (5, LOW);
}
}
deviceID++;
if (deviceID == 5)
{
deviceID = 1;
}
}
ciao...no, non è corretto.
basta che guardi com'è scritta la libreria per capirlo.
il node.begin(id, seriale) è usato per passare una sola volta quei valori al tuo Oggetto modbus...
allora...nella cartella della libreria c'è una sotto cartella dal nome "src"; in questa cartella ci sono due files "ModbusMaster.h" e "ModbusMaster.cpp"...nel file ".h" inserisci alla riga 204 queste righe:
void setSlave(uint8_t);
nel file ".cpp" alla riga 75 (e comunque non all'interno di altre funzioni) aggiungi:
void ModbusMaster::setSlave(uint8_t slave)
{
_u8MBSlave = slave;
}
salvi i due file e riprovi