Go Down

Topic: Modbus RTU, Sensor ultrassonico, ScadaBR (Read 2679 times) previous topic - next topic

relristein

Fala Galera,

Tudo belezinha?

Então, abaixo segue script. Sincronizei um sensor ultrassonico com o scadabr, precisão perfeita!! Porém, segue abaixo a minha dúvida:

#include "Ultrasonic.h"
#define echoPin 13 //Pino 13 recebe o pulso do echo
#define trigPin 12 //Pino 12 envia o pulso para gerar o echo
//iniciando a função e passando os pinos
Ultrasonic ultrasonic(12,13);
void configure_mb_slave(long baud, char parity, char txenpin);
int update_mb_slave(unsigned char slave, int *regs,
unsigned int regs_size);
/* Modbus RTU common parameters, the Master MUST use the same parameters */
enum {
        MB_SLAVE = 1,   /* modbus slave id */
};
/* slave registers example */
enum {
        MB_REG0,        /* Condição para LER sensor */
        MB_REG1,        /* Leitura da distancia */
        MB_REGS       /* total number of registers on slave */
};
int regs[MB_REGS];   /* this is the slave's modbus data map */
void setup()
{
        /* Modbus setup example, the master must use the same COM parameters */
        /* 115200 bps, 8N1, two-device network */
        configure_mb_slave(115200, 'n', 0);
         pinMode(echoPin, INPUT); // define o pino 13 como entrada (recebe)
         pinMode(trigPin, OUTPUT); // define o pino 12 como saida (envia)
}
void loop()
{
        /* This is all for the Modbus slave */<br />
   update_mb_slave(MB_SLAVE, regs, MB_REGS);
if(regs[MB_REG0] == 1)
   {
   //seta o pino 12 com um pulso baixo "LOW" ou desligado ou ainda 0
    digitalWrite(trigPin, LOW);
  // delay de 2 microssegundos
    delayMicroseconds(2);
  //seta o pino 12 com pulso alto "HIGH" ou ligado ou ainda 1
    digitalWrite(trigPin, HIGH);
  //delay de 10 microssegundos
    delayMicroseconds(10);
  //seta o pino 12 com pulso baixo novamente
    digitalWrite(trigPin, LOW);
  // função Ranging, faz a conversão do tempo de
  //resposta do echo em centimetros, e armazena
  //na variavel distancia
    int distancia = (ultrasonic.Ranging(CM));
regs[MB_REG1] = distancia;
delay(1000); //espera 1 segundo para fazer a leitura novamente
   }
   else{
     regs[MB_REG1]==0;
   }
}

Como vocês podem ver ao obedecer a primeira condição, entra-se em um IF, para mandar os pulsos do sensor.

Enfim, ele entra no IF e quando seto o 0 pelo scadabr ele simplesmente não obedece. E com certeza não é biblioteca, já testei com todas existentes e o problema permanece.

Estou usando o serial nativo do arduino.
Bem, espero que possam me ajudar e com certeza outros que estejam se aventurando no ScadaBR.

Obrigado

bubulindo

Aquele delay(1000) pode explicar muita coisa...
This... is a hobby.

relristein

Bubulindo,

Uai, então se eu for usar o Modbus RTU não poderei usar Delay dentro do loop?

bubulindo

Sempre que usas delay() o programa para durante o tempo que indicaste no delay. Durante essa paragem algo pode acontecer (como enviares um valor pelo SCADA) que pode não ser lido (porque o programa está parado).

Existe algum motivo para que pretendas parar o programa por 1 segundo?

Esse delay existe para pequenos intervalos de alguns milisegundos, não para esperar segundos. Altera o programa e tira esse delay e vê o que resulta. Pode ser que funcione. Mesmo que não seja esse o problema, não usares delay é uma boa prática de programação.

This... is a hobby.

relristein

Então Bubulindo

Esse um segundo, o script do sensor ultrassônico que estou usando solicita para poder ler novamente. Caso eu tire ele fica muito "louco", medidas totalmente incertas.

O que resolveu um pouco o problema, ou seja, ele conseguiu sair do loop, foi reduzir o delay. Mesmo assim a precisão reduz drasticamente.
Não sei o que acontece, provavelmente a biblioteca do modbus deve solicitar um tempo semelhante e ele deve conflitar nesse momento.

Vc já usou essa biblioteca antes?

bubulindo

Eu não compreendi completamente o problema... mas porque não fazes algo deste género:

Code: [Select]


unsigned long agora = 0, antes = 0;


void loop()
{
        /* This is all for the Modbus slave */<br />
   update_mb_slave(MB_SLAVE, regs, MB_REGS);
   agora = millis();
if(regs[MB_REG0] == 1 && ((agora - antes) >=1000))
   {
   //seta o pino 12 com um pulso baixo "LOW" ou desligado ou ainda 0
    digitalWrite(trigPin, LOW);
  // delay de 2 microssegundos
    delayMicroseconds(2);
  //seta o pino 12 com pulso alto "HIGH" ou ligado ou ainda 1
    digitalWrite(trigPin, HIGH);
  //delay de 10 microssegundos
    delayMicroseconds(10);
  //seta o pino 12 com pulso baixo novamente
    digitalWrite(trigPin, LOW);
  // função Ranging, faz a conversão do tempo de
  //resposta do echo em centimetros, e armazena
  //na variavel distancia
    int distancia = (ultrasonic.Ranging(CM));
regs[MB_REG1] = distancia;
   // O DELAY ESTAVA AQUI
   antes = millis();
   }
   else{
     regs[MB_REG1]==0;
   }
}


Isto evita que tenhas problemas com o programa parado e esta parte só é executada de segundo a segundo.
Experimenta se é isso que pretendes.
This... is a hobby.

relristein

Galera,
Enfim, consegui!
Para quem não acompanhou o sufoco, leia os posts anteriores. O perrengue foi ao sincronizar um sensor ultrassônico com o scadabr (usando a biblioteca Modbus RTU). Enfim, resumo da opera, reduzi o baud rate, retirei os delays do script, através de um script que encontrei na internet para esse modelo e pronto..UFAAA..

Fica aí o scrípt para quem quiser usar ao sincronizar esse sensor.

#include "Ultrasonic.h"
#define echoPin 13 //Pino 13 recebe o pulso do echo
#define trigPin 12 //Pino 12 envia o pulso para gerar o echo
//iniciando a função e passando os pinos
Ultrasonic sensor(12,13);
void configure_mb_slave(long baud, char parity, char txenpin);
int update_mb_slave(unsigned char slave, int *regs,
unsigned int regs_size);

/* Modbus RTU common parameters, the Master MUST use the same parameters */
enum {
MB_SLAVE = 1, /* modbus slave id */
};
/* slave registers example */
enum {
MB_REG0, /* Condição para LER sensor */
MB_REG1, /* Leitura da distancia */
MB_REGS /* total number of registers on slave */
};
int regs[MB_REGS]; /* this is the slave's modbus data map */
int distancia;

void setup()
{
/* Modbus setup example, the master must use the same COM parameters */
/* 9600 bps, 8N1, two-device network */
configure_mb_slave(9600, 'n', 0);
pinMode(echoPin, INPUT); // define o pino 13 como entrada (recebe)
pinMode(trigPin, OUTPUT); // define o pino 12 como saida (envia)
}

void loop()
{
/* This is all for the Modbus slave */
update_mb_slave(MB_SLAVE, regs, MB_REGS);

if(regs[MB_REG0] == 1)
{
distancia = sensor.Ranging ( CM );
regs[MB_REG1]=distancia;
delay(30); //Esse delay é fundamental, achei ele na tentativa e erro.
}
 else{
   regs[MB_REG1]=regs[MB_REG1];
       }


BUBULINDO, obrigado cara, teus posts deram uma grande luz!!! :)

}

bubulindo

This... is a hobby.

Go Up