Hola.
Mi nombre es Lluís, y soy tecnico en sistemas de detección de incendios. Normalmente,
uso un software de comunicaciónes con las centrales de la casa DESICO llamado VIGIPLUS.
https://www.desico.com/es/vigiplus
Este software, funciona mas o menos bien, pero no aprendes nada. El otro dia, un cliente me planteó el reto de automatizar 2 invernaderos para la producción de setas para laboratorios. Acepté el reto ![]()
Al ponerme manos a la obra, me empieza a ilusionar el ver la cantidad y calidad de proyectos que arduino puede llevar acabo, llego incluso a leer sondas analógicas y mostrarlas en Monitoriza.
con el siguiente skech (copiado del tuto
2) SCADA PARA ARDUINO--(Lectura Análoga - Parte_1 ) - YouTube) .
/*
Modbus over serial line - RTU Slave Arduino Sketch
By Juan Pablo Zometa : jpmzometa@gmail.com
http://sites.google.com/site/jpmzometa/
and Samuel Marco: sammarcoarmengol@gmail.com
and Andras Tucsni
and Emilio Sanchis: emilio.sanchis at acimut.es
and Antonio Canet
http://www.acimut.com/en/monitoriza/monitorizaforarduino.html
These functions implement functions 3, 6, 16 and 43 (read holding registers,
preset single register, preset multiple registers and read device information) of the
Modbus RTU Protocol, to be used over the Arduino serial connection.
This implementation DOES NOT fully comply with the Modbus specifications.
This Arduino adaptation is derived from the work
By P.Costigan email: phil@pcscada.com.au http://pcscada.com.au
These library of functions are designed to enable a program send and
receive data from a device that communicates using the Modbus protocol.
Copyright (C) 2000 Philip Costigan P.C. SCADA LINK PTY. LTD.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The functions included here have been derived from the
Modicon Modbus Protocol Reference Guide
which can be obtained from Schneider at www.schneiderautomation.com.
This code has its origins with
paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk)
who wrote a small program to read 100 registers from a modbus slave.
I have used his code as a catalist to produce this more functional set
of functions. Thanks paul.
*/
/*
* configure_mb_slave(baud, parity, tx_en_pin)
*
* sets the communication parameters for of the serial line.
*
* baud: baudrate in bps (typical values 9600, 19200... 115200)
* parity: a single character sets the parity mode (character frame format):
* 'n' no parity (8N1); 'e' even parity (8E1), 'o' for odd parity (8O1).
* tx_en_pin: arduino pin number that controls transmision/reception
* of an external half-duplex device (e.g. a RS485 interface chip).
* 0 or 1 disables this function (for a two-device network)
* >2 for point-to-multipoint topology (e.g. several arduinos)
*/
void configure_mb_slave(long baud, char parity, char txenpin);
/*
* update_mb_slave(slave_id, holding_regs_array, number_of_regs)
*
* checks if there is any valid request from the modbus master. If there is,
* performs the action requested
*
* slave: slave id (1 to 127)
* regs: an array with the holding registers. They start at address 1 (master point of view)
* regs_size: total number of holding registers.
* returns: 0 if no request from master,
* NO_REPLY (-1) if no reply is sent to the master
* an exception code (1 to 4) in case of a modbus exceptions
* the number of bytes sent as reply ( > 4) if OK.
*/
int update_mb_slave(unsigned char slave, int *regs,
unsigned int regs_size);
/* HERE BEGINS THE EXAMPLE CODE */
/* Modbus RTU common parameters, the Master MUST use the same parameters */
enum {
COMM_BPS = 19200, /* baud rate */
MB_SLAVE = 1, /* modbus slave id */
PARITY = 'n' /* even parity */
};
/* slave registers */
enum { MB_POT, /*variable potenciometro */
MB_LED,
MB_REGS /* numero registros del esclavo */
};
int regs[MB_REGS];
int potenciometro;
void setup()
{
/* configure modbus communication
* 19200 bps, 8N1, two-device network */
configure_mb_slave(COMM_BPS, PARITY, 0);
}
void loop()
{
/* check for master requests*/
if(update_mb_slave(MB_SLAVE, regs, MB_REGS))
/*==========================================*/
potenciometro=analogRead(0);
regs[MB_POT]=potenciometro;
}
/****************************************************************************
* BEGIN MODBUS RTU SLAVE FUNCTIONS
todo bien. adaptando el sketch, consigo mostrar los valores en el puerto serie, pero no consigo pasar esos valores a una variable que reconozca el Scada. El sketch lo he escrito así:
// Instancia a las clases OneWire y DallasTemperature
OneWire oneWireObjeto(pinDatosDQ);
DallasTemperature sensores(&oneWireObjeto);
DeviceAddress s1 = {0x28, 0x50, 0x2F, 0x0D, 0x28, 0x19, 0x01, 0x8B};
float valor1=0; // variable donde guardaremos la temperatura leida del sensor 1
float valor2=0; // variable donde guardaremos la temperatura leida del sensor 2
void configure_mb_slave(long baud, char parity, char txenpin);
int update_mb_slave(unsigned char slave, int *regs,
unsigned int regs_size);
enum {
COMM_BPS = 19200, /* baud rate */
MB_SLAVE = 1, /* modbus slave id */
PARITY = 'n' /* even parity */
};
enum {
MB_SENSOR,
//MB_POT,
//MB_LED,
MB_REGS
};
int regs[MB_REGS];
float sondas;
unsigned long wdog = 0; /* watchdog */
unsigned long tprev = 0; /* previous time*/
int i = 0;
float Counter = 0;
void setup()
{
configure_mb_slave(COMM_BPS, PARITY, 0);
pinMode(12,OUTPUT);
sensores.begin();
}
void loop()
{
sensores.requestTemperatures(); //Enviamos el comando para obtener la temperatura
float valor1 = sensores.getTempCByIndex(0); // Almacenamos la temperatura leida por el sensor 1
float valor2 = sensores.getTempCByIndex(1); //Almacenamos la temperatura leida por el sensor 2
regs[MB_SENSOR]=valor1;
regs[MB_SENSOR]=valor2;
if(update_mb_slave(MB_SLAVE, regs, MB_REGS))
wdog = millis();
{
// potenciometro=analogRead(0);
// regs[MB_POT]=potenciometro;
delay(1000);
pero no funciona, y no encuentro ningún ejemplo donde aprender.
Alguno de vosotros puede ayudarme, o ponerme algún ejemplo?
Puede ser que el problema esté en el Scada?
Grácias!!