sexta-feira, 12 de abril de 2013

Finalmente

Agora acho que finalmente consegui manter a comunicação rodando constante sem perda de sinal quando atuo em equipamentos. Não tive tempo de estudar o código da biblioteca, mas ela tem me atendido muito bem.



Outra implementação interessante e quem tem funcionado bem, foi a gravação de dados na memória do Arduino (EEPROM), que ajuda no caso de reset do equipamento. 

Abaixo o código:



#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>
#include <EEPROM.h>

#include "DHT11.h" // Importa a Biblioteca do sensor de umidade e temperatura
#include <Servo.h>

modbusDevice regBank;
modbusSlave slave;


//variaveis de controle do sistema
int constMotorT = 0;
int ConstMotor = constMotorT;
int FimMotor = 1023;
int val = 0;
int Comando = 0;
int TempAtual = 0;
int TempSETPT = 0;

Servo myservo; // crie objeto Servo para controlar o motor de HD

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
  
        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
*/

/* ************************** IMPORTANTE ************************************
   OS BLOCOS ABAIXO SÃO IMPORTANTES AO TRABALHARMOS COM OUTROS SCADAS COMO O ELIPSE SCADA
*/

/*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 - No ScadaBr vou usar somente a faixa de registradores do holding, lembre-se que o ScadaBr tem faixa 0 de endereçamento
  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 = &regBank;  

// 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()
{

  //lendo a constante do motor salva na emprom - endereços 0 e 1 da Eprom
  //Essa foi a última implementação, interessante pois em caso de reset do equipamento eu posso recuperar a última leitura e assim não travo o processo
  byte hiByteT = EEPROM.read(0);
  byte lowByteT = EEPROM.read(0 +1);
  constMotorT  = word(hiByteT, lowByteT);
  ConstMotor = constMotorT;
  
  regBank.set(40004, (int) EEPROM.read(2)); //Set-Point
  regBank.set(40001, (int) EEPROM.read(3)); //umidade
  regBank.set(40002, (int) EEPROM.read(4)); //temperatura  
  

 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 */
    int Comando = regBank.get(40004); //Lendo o valor do Set-Point da temperatura
    int TempAtual =  regBank.get(40002); //Lendo o valor 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 (ConstMotor < FimMotor){ 
                if (Comando < TempAtual){ //se o set-point é menor que a temp atual eu acelero o motor
                  ConstMotor = ConstMotor + 10;  
                  val = map(ConstMotor, 0, 1023, 0, 179); 
                  myservo.write(val); 
                  regBank.set(40003, (int) ConstMotor);
                }  
              }

         if (Comando > TempAtual){ //se o set-point é maior que a temp atual eu reduzo o motor
             if (ConstMotor > 10) {
               ConstMotor = ConstMotor - 10;  
               val = map(ConstMotor, 0, 1023, 0, 179); 
               myservo.write(val); 
               regBank.set(40003, (int) ConstMotor);
             }else {
               ConstMotor = 0;  //se já for menor que 10 eu paro o motor de vez
               val = map(ConstMotor, 0, 1023, 0, 179); 
               myservo.write(val); 
               regBank.set(40003, (int) ConstMotor);                
             }
         }
        }
         if (Comando == 0){
            ConstMotor = 0;  
            val = map(ConstMotor, 0, 1023, 0, 179); 
            myservo.write(val); 
            regBank.set(40003, (int) ConstMotor);
          }
        //}  
    }
    
    //escrevendo na eprom
     EEPROM.write(2, regBank.get(40004));
     EEPROM.write(3, regBank.get(40001));
     EEPROM.write(4, regBank.get(40002));     
     
     byte hiByteT = highByte(ConstMotor);
     byte loByteT = lowByte(ConstMotor);
     EEPROM.write(0, hiByteT);
     EEPROM.write(1, loByteT);

    
     slave.run(); 
  }
}

Nenhum comentário:

Postar um comentário