Comecei com o arduino tem alguns dias e estou tendo algumas dificuldades em integrar com o ScadaBr através do protocolo ModBus.
Meu sistema consiste em ler dados de temperatura e umidade de um sensor e através de um set-point aumentar ou reduzir a velocidade de um motor brushless usando a biblioteca de servo.
Nos primeiros segundos o sistema roda liso, efetuo a escrita do set-point, os dados são aceitos, o motor acelera e tudo vai que é uma beleza. Até que simplesmente a comunicação cai.
Alguém poderia dar uma olhada no code e ajudar?
Como o texto ficou longo, anexei o fonte.
Tem bastante coisa comentada que não utilizei no código original.
Aquilo é uma imensidão de comentários que não precisam necessariamente de lá estar.
Depois coloca apenas o código estritamente necessário para comunicar através de ModBus e vê se o mesmo acontece.
Se não acontecer, vai adicionando partes do programa e testando até veres o que causa o erro. Sem termos aqui o mesmo setup que tu é um pouco complicado perceber qual é mesmo o problema.
Resolvi começar um source novo do zero...
Mas começo a desconfiar da conexão física, pois estou usando o cabo usb ao invés dos adaptadores RS-232 - TTL. Vou procurar algumas referências...
Do que conheço do ScadaBR para usar o arduino apenas com comunicaçao Serial (sem ser com shield Ethernet) tem de se recorrer ao ModBus RTU. Nao conheço que exista outra forma mas posso estar desatualizado porque ja nao o utilizo há muito...
Pesquisando um pouco no fórum acabei me deparando com essa biblioteca: https://code.google.com/p/arduino-modbus-slave/ fiz alguns testes aqui e pimba! o sistema está rodando já tem uma hora e meia, inclusive com uma rotina de comando no loop usando o millis, fato que estava travando a comunicação quando usando a outra lib.
Segue o código que estou rodando...
#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>
#include "DHT11.h" // Importa a Biblioteca do sensor de umidade e temperatura
#include <Servo.h>
/*
This example code shows a quick and dirty way to get an
arduino to talk to a modbus master device with a
device ID of 1 at 9600 baud.
*/
//Setup the brewtrollers register bank
//All of the data accumulated will be stored here
modbusDevice regBank;
//Create the modbus slave protocol handler
modbusSlave slave;
//variaveis de controle do sistema
int ConstMotor = 0;
int FimMotor = 1023;
int val = 0;
int Comando = 0;
Servo myservo; // crie objeto Servo para controlar o servomotor
int ledPin4 = 4;
#define dht11_pin 4 // Usa o pino digital 4 para receber umidade/temperatura
// Cria Instancia da Classe do sensor de temperatura
DHT11 sensor1(dht11_pin);
void setup()
{
myservo.attach(9); // setando o pino do servo
sensor1.Initialize(); //inicializando o sensor de temperatura e umidade
//Assign the modbus device ID.
regBank.setId(1);
/*
modbus registers follow the following format
00001-09999 Digital Outputs, A master device can read and write to these registers
10001-19999 Digital Inputs, A master device can only read the values from these registers
30001-39999 Analog Inputs, A master device can only read the values from these registers
40001-49999 Analog Outputs, A master device can read and write to these registers
Analog values are 16 bit unsigned words stored with a range of 0-32767
Digital values are stored as bytes, a zero value is OFF and any nonzer value is ON
It is best to configure registers of like type into contiguous blocks. this
allows for more efficient register lookup and and reduces the number of messages
required by the master to retrieve the data
*/
/*Add Digital Output registers 00001-00016 to the register bank
regBank.add(1);
regBank.add(2);
regBank.add(3);
regBank.add(4);
regBank.add(5);
regBank.add(6);
regBank.add(7);
regBank.add(8);
regBank.add(9);
regBank.add(10);
regBank.add(11);
regBank.add(12);
regBank.add(13);
regBank.add(14);
regBank.add(15);
regBank.add(16);
//Add Digital Input registers 10001-10008 to the register bank
regBank.add(10001);
regBank.add(10002);
regBank.add(10003);
regBank.add(10004);
regBank.add(10005);
regBank.add(10006);
regBank.add(10007);
regBank.add(10008);
//Add Analog Input registers 30001-10010 to the register bank
regBank.add(30001);
regBank.add(30002);
regBank.add(30003);
regBank.add(30004);
regBank.add(30005);
regBank.add(30006);
regBank.add(30007);
regBank.add(30008);
regBank.add(30009);
regBank.add(30010);
*/
//Add Analog Output registers 40001-40020 to the register bank
regBank.add(40001);
regBank.add(40002);
regBank.add(40003);
regBank.add(40004);
regBank.add(40005);
regBank.add(40006);
regBank.add(40007);
regBank.add(40008);
regBank.add(40009);
regBank.add(40010);
regBank.add(40011);
regBank.add(40012);
regBank.add(40013);
regBank.add(40014);
regBank.add(40015);
regBank.add(40016);
regBank.add(40017);
regBank.add(40018);
regBank.add(40019);
regBank.add(40020);
/*
Assign the modbus device object to the protocol handler
This is where the protocol handler will look to read and write
register data. Currently, a modbus slave protocol handler may
only have one device assigned to it.
*/
slave._device = ®Bank;
// Initialize the serial port for coms at 9600 baud
slave.setBaud(9600);
}
long previousMillis = 0; // previousMillis irá armazenar o ultimo número da função millis()
long interval = 1000; // intervalo em que o motor irá esperar
void loop()
{
while(1)
{
//************** SENSOR DE TEMPERATURA E UMIDADE ***********************
double sensorData[2];
int result;
result = sensor1.Read(sensorData);
//*************** FIM DE SENSOR *****************************************
/*Escrevendo no ModBus = regBank.SET */
regBank.set(40001, (int) 27 + sensorData[0]); //umidade
regBank.set(40002, (int) sensorData[1]); //temperatura
regBank.set(40003, (int) ConstMotor); //velocidade moto
/*Lendo do ModBus = regBank.GET */
Comando = regBank.get(40004); //Lendo o valor do Set-Point da temperatura
//Na impossibilidade de usar o Delay(0 por truncar a execução do script, vamos partir para um millis().
unsigned long currentMillis = millis(); //variável currentMillis irá armazenar o tempo
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis; //armazena a variável currentMillis para previousMillis
//verifico a existencia de comando e solto as rotinas...
if (Comando > 0){
if (Comando < FimMotor){
ConstMotor = ConstMotor + 10;
regBank.set(40003, (int) ConstMotor);
}
}
}
slave.run();
}
}