Go Down

Topic: Envió de datos vía MODBUS TCP (Read 274 times) previous topic - next topic

rodsal13

Buen día.

Estoy trabajando con una nodeMCU 1.0 (ESP12-E Module), la programe para que envié un número en especial cuando se cierre un circuito, el dato lo estoy leyendo desde Productivity Suite un programa para programación de PLC, mi problemas es que cuando el circuito se cierra y hace el envio de datos se manda al PLC solo 1 y 0, y yo necesito que envié el número en especial, alguien podría ayudarme por favor.

Code: [Select]

#include <ESP8266WiFi.h>
#include <Modbus.h>
#include <ModbusIP_ESP8266.h>

#define medida1 16 // Echo Pin GPIO 12 (D6)
#define medida2 5 // Trigger Pin GPIO 13 (D7)
#define medida3 4
#define medida4 0
#define medida5 14
#define medida6 12

long duration, distance; // Duration used to calculate distance
long ts;

IPAddress ip(192, 168, 15, 164);
IPAddress gateway(192, 168, 15, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(142, 240, 118, 40);

//Used Pins//ModbusIP object
ModbusIP mb;

const int SENSOR_IREG = 100;

///////////////////////////////////////////////RECONEXIÓN/////////////////////////
void reconnect() {
  WiFi.mode(WIFI_STA);
  WiFi.begin("Interactive PA", "ISTPA2017");
  mb.config("Interactive PA", "ISTPA2017");
 // WiFi.begin("BMS", "IST-1234");
 // mb.config("BMS", "IST-1234");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Reconectando ");
  }
}

void setup()
{

  WiFi.mode(WIFI_STA);
  WiFi.begin("BMS", "IST-1234");
  mb.config("BMS", "IST-1234");

  //WiFi.begin("Interactive PA", "ISTPA2017");
  //mb.config("Interactive PA", "ISTPA2017");

  Serial.begin (115200);

  pinMode(medida1, INPUT);
  pinMode(medida2, INPUT);
  pinMode(medida3, INPUT);
  pinMode(medida4, INPUT);
  pinMode(medida5, INPUT);
  pinMode(medida6, INPUT);
   

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(":::");}

  WiFi.config(ip, gateway, subnet, dns);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println(WiFi.macAddress());

  mb.addIreg(SENSOR_IREG);
  ts = millis();
}
 
void loop()
{

  ////////////////////////////////////////////////
  if (WiFi.status() != WL_CONNECTED) {
    reconnect();
  }
  ////////////////////////////////////////////////
  if(medida1 == HIGH){
  distance = 170;}
  if(medida2 == HIGH){
  distance = 340;}
  if(medida3 == HIGH){
  distance = 510;}
  if(medida4 == HIGH){
  distance = 680;}
  if(medida5 == HIGH){
  distance = 850;}
  if(medida6 == HIGH){
  distance = 1020;}
  mb.task();
     if (millis() > ts + 200) {
       ts = millis();
       //Setting raw value (0-1024)
       mb.Ireg(SENSOR_IREG, distance); }
       Serial.println("MOBUS");
       Serial.println( mb.Ireg(SENSOR_IREG));

}

surbyte

Estas escribiendo en la direccion 100 y creo que esa dirección es para las Coils o sea 1 / 0
Busca donde corresponde para tu PLC que escribas un Holding Register generalmente es desde 4000 en algunos PLC o 40000 en otros

rodsal13

#2
Oct 09, 2018, 11:09 pm Last Edit: Oct 10, 2018, 05:02 pm by surbyte
Claro, pero eso es lo más logicio. PLC y Arduino conversan o intercambian mensajes en las direcciones que dispongan. No en cualquier lugar.
Si tu PLC esta esperando datos en la dirección 100H (de hexa) y eso corresponde a un Holding Register entonces tienes dos posibles caminos.

Prueba con 4100 en el arduino o con 40100.

Usaste algun Modbus Tester para enviar los datos con una PC a ver donde los recibe tu PLC?

rodsal13

#3
Oct 10, 2018, 11:56 pm Last Edit: Oct 11, 2018, 04:59 am by surbyte
El modulo MODBUS en el PLC ya lo coloque así, y ya cambie el valor de la dirección, en la imagen del serial de Arduino mande a imprimir ciertos datos, y este es el resultado, aun sigue sin mandarme los datos que quiero. Y no utilice ningún tester




surbyte

#4
Oct 11, 2018, 05:00 am Last Edit: Oct 11, 2018, 05:02 am by surbyte
Un programa para testear, a eso me refería.
Desde una PC le envias al PLC los datos como para que el los reciba correctamente. Y luego con esa prueba sabras que enviarle usando el Arduino.

Algo como Modbus Poll o QModubs

rodsal13

Ya logre hacer la comunicación entre el Arduino y el PLC, solo que todavía no me envía los datos que le estoy especificando al final del código. Me esta llegando el valor del const int SENSOR_IREG = 4100;
Y si le pongo mi variable "distance" me manda solo 0.

Code: [Select]


#include <ESP8266WiFi.h>
#include <Modbus.h>
#include <ModbusIP_ESP8266.h>

#define medida1 D0
#define medida2 D1
#define medida3 D2
#define medida4 D3
#define medida5 D4
#define medida6 D5

long duration;
int distance = 100; // Duration used to calculate distance
long ts;

///////////////////////////////////////////////////////////Modbus Registers Offsets (0-9999)
const int LED_COIL = 100;  //Direccion 000100
const int LED_ISTS = 10; //Direccion 100010

////////////////////////////////////////////////////DIRECCIONAMIENTO DE MODBUS
IPAddress ip(192, 168, 15, 164);
IPAddress gateway(192, 168, 15, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(142, 240, 118, 40);

//Used Pins//ModbusIP object
ModbusIP mb;

const int SENSOR_IREG = 4100;

///////////////////////////////////////////////RECONEXIÓN/////////////////////////
void reconnect() {
  WiFi.mode(WIFI_STA);
  WiFi.begin("Interactive PA", "ISTPA2017");
  mb.config("Interactive PA", "ISTPA2017");
 // WiFi.begin("BMS", "IST-1234");
 // mb.config("BMS", "IST-1234");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Reconectando ");
  }
}

///////////////////////////////////////////////////////////////////////////SET UP
void setup()
{
///////////////////////////////INCIALIZACIÓN DE COMUNICACIÓN SERIAL Y WIFI
  Serial.begin (115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin("BMS", "IST-1234");
  mb.config("BMS", "IST-1234");
  WiFi.config(ip, gateway, subnet, dns);
  //WiFi.begin("Interactive PA", "ISTPA2017");
  //mb.config("Interactive PA", "ISTPA2017");

  Serial.begin (115200);

  pinMode(medida1, INPUT);
  pinMode(medida2, INPUT);
  pinMode(medida3, INPUT);
  pinMode(medida4, INPUT);
  pinMode(medida5, INPUT);
  pinMode(medida6, INPUT);
   
///////////////////////////////////////////////CONFIGURACIÓN DE RECONEXIÓN
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(":::");}

  WiFi.config(ip, gateway, subnet, dns);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println(WiFi.macAddress());
 
//////////////////////////////////////////DEFINICIÓN DE DIRECCIONES MODBUS
  mb.addIreg(SENSOR_IREG);
  ts = millis();
}

////////////////////////////////////////////////////////////////////////////LOOP
void loop()
{

  ////////////////////////////////////////////////RECONEXIÓN
  if (WiFi.status() != WL_CONNECTED) {
    reconnect();
  }
  ////////////////////////////////////////////////
 digitalRead (medida1);
  if(medida1 ==   LOW){
  distance = 170;}
  digitalRead (medida2);
  if(medida2 == HIGH){
  distance = 340;}
  digitalRead (medida3);
  if(medida3 == HIGH){
  distance = 510;}
  digitalRead (medida4);
  if(medida4 == HIGH){
  distance = 680;}
  digitalRead (medida5);
  if(medida5 == LOW){
  distance = 850;}
  digitalRead (medida6);
  if(medida6 == HIGH){
  distance = 1020;}
  mb.task();
     if (millis() > ts + 200) {
       ts = millis();
       //Setting raw value (0-1024)
       mb.Ireg(SENSOR_IREG, 4100); }
       Serial.println("MOBUS");
       Serial.println(medida1);
       Serial.println(distance);
       Serial.println(SENSOR_IREG, 4100);

}


surbyte

Tal vez esto sea una tontería pero probaste el ejemplo de tu librería TestHoldingReg.ino

Code: [Select]
#include <ESP8266WiFi.h>
#include <Modbus.h>
#include <ModbusIP_ESP8266.h>

// Modbus Registers Offsets (0-9999)
const int TEST_HREG = 4100;


//ModbusIP object
ModbusIP mb;
 
void setup() {
  Serial.begin(115200);
 
  mb.config("your_ssid", "your_password");
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected"); 
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  mb.addHreg(TEST_HREG, 0xABCD);  // aca envia el dato
}
 
void loop() {
   //Call once inside loop() - all magic here
   mb.task();

}



Porque te puse este ejemplo?
Por lo que siempre digo, en los ejemplos siempre estan las respuestas.

En tu código no hay un solo envio de datos modbus.. dime: cuando envias el dato distance? jamas, lo envias por puerto Serie a tu Monitor serie.
Deberías usar esto


Code: [Select]
  mb.addHreg(SENSOR_IREG, distance);  // aca envia el dato

rodsal13

#7
Oct 15, 2018, 06:26 pm Last Edit: Oct 15, 2018, 06:27 pm by rodsal13
Hice lo que me dijiste, pero los datos que esta enviando el Arduino al PLC siguen siendo diferentes a los que yo quiero, y tienes razón antes no estaba mandando el dato distance, pero ahora no se por que no le llega el valor correcto

surbyte

Pero no vayas rapido.
Aprende a usar bien la rutina enviando Holding Registers.

Te deje un ejemplo, lo probaste? Se recibe el valor enviado? Hasta no leer lo que se envia, no resolviste el problema.
Luego pasa a las modificaciones a tu código para enviar distancia.

rodsal13

#9
Oct 17, 2018, 02:31 am Last Edit: Oct 17, 2018, 07:25 pm by rodsal13
Ya logre enviar el dato que yo quiero en el TestHoldingReg, pase el

Code: [Select]
mb.addHreg(TEST_HREG, ZZZ );  // aca envia el dato

a mi programa y lo subi, el valor que yo le ponga en donde esta ZZZ me lo da sin ningún problema, pero si le pongo mi variable "distance " ya no me envía los números que pongo así:
 
Code: [Select]

  if(medida1 == HIGH){
  distance = 1111;}
  if(medida2 == HIGH){
  distance = 2222;}
  if(medida3 == HIGH){
  distance = 3333;}
  if(medida4 == HIGH){
  distance = 4444;}
  if(medida5 == HIGH){
  distance = 5555;}
  if(medida6 == HIGH){
  distance = 6666;}
  mb.task();
     if (millis() > ts + 200) {
       ts = millis();

Me eh puesto ah pensar y veo que  no estoy llamando estos valores cuando se activa una entrada del NodeMCU, y es que no se como hacerle, si por medio de una subrutina o como.

surbyte

distance esta definido como long, y debería ser unsigned long.

Prueba a ver si es eso.

rodsal13

Este es mi ultimo codigo

Code: [Select]



#include <ESP8266WiFi.h>
#include <Modbus.h>
#include <ModbusIP_ESP8266.h>

// Modbus Registers Offsets (0-9999)
const int TEST_HREG = 4100;
int distance;

#define medida1 16 // Echo Pin GPIO 12 (D6)
#define medida2 5 // Trigger Pin GPIO 13 (D7)
#define medida3 4
#define medida4 0
#define medida5 14
#define medida6 12

long duration; // Duration used to calculate distance
long ts;

///////////////////////////////////////////////////////////Modbus Registers Offsets (0-9999)


////////////////////////////////////////////////////DIRECCIONAMIENTO DE MODBUS
IPAddress ip(192, 168, 15, 73);
IPAddress gateway(192, 168, 15, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(142, 240, 118, 40);

//Used Pins//ModbusIP object
ModbusIP mb;


///////////////////////////////////////////////RECONEXIÓN/////////////////////////
void reconnect() {
  WiFi.mode(WIFI_STA);
  WiFi.begin("Interactive PA", "ISTPA2017");
  mb.config("Interactive PA", "ISTPA2017");
 // WiFi.begin("BMS", "IST-1234");
 // mb.config("BMS", "IST-1234");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Reconectando ");
  }
}

///////////////////////////////////////////////////////////////////////////SET UP
void setup()
{
///////////////////////////////INCIALIZACIÓN DE COMUNICACIÓN SERIAL Y WIFI
  WiFi.mode(WIFI_STA);
  WiFi.begin("BMS", "IST-1234");
  mb.config("BMS", "IST-1234");

  //WiFi.begin("Interactive PA", "ISTPA2017");
  //mb.config("Interactive PA", "ISTPA2017");

  Serial.begin (115200);

  pinMode(medida1, INPUT);
  pinMode(medida2, INPUT);
  pinMode(medida3, INPUT);
  pinMode(medida4, INPUT);
  pinMode(medida5, INPUT);
  pinMode(medida6, INPUT);
   
///////////////////////////////////////////////CONFIGURACIÓN DE RECONEXIÓN
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(":::");}

  WiFi.config(ip, gateway, subnet, dns);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println(WiFi.macAddress());

//////////////////////////////////////////DEFINICIÓN DE DIRECCIONES MODBUS

  mb.addHreg(TEST_HREG, distance);  // aca envia el dato
  ts = millis();
}
////////////////////////////////////////////////////////////////////////////LOOP
void loop()
{

  ////////////////////////////////////////////////RECONEXIÓN
  if (WiFi.status() != WL_CONNECTED) {
    reconnect();
  }
  ////////////////////////////////////////////////
  if(medida1 == HIGH){
  distance = 1111;}
  if(medida2 == HIGH){
  distance = 2222;}
  if(medida3 == HIGH){
  distance = 3333;}
  if(medida4 == HIGH){
  distance = 4444;}
  if(medida5 == HIGH){
  distance = 5555;}
  if(medida6 == HIGH){
  distance = 6666;}
  mb.task();
     if (millis() > ts + 200) {
       ts = millis();
  }
     

}

surbyte

Posteas el código luego de haberte recomendado que definieras distance como unsigned long.

Son 4 bytes sin signo.

Go Up