Não consigo ler alguns Valores Arduino e ScadaBR

Pessoal, estou tentando criar um supervisório para um projeto. Estou utilizando ScadaBR como surpervisório e Arduino Duemilinove como microcontrolador. O problema é que apenas consegui pegar alguns dados via Supervisório... Acredito que tenha alguma coisa incorreta ou alguma forma que estou enviando para o ScadaBR.

Não estou conseguindo captar alguns valores da programação. Estou tentando captar o valor de temperatura utilizando um sensor DALLAS. mas o valor enviado para o ScadaBR não consigo ler.

Alguma sugestão?

Acredito que tenha a ver com a definição das variáveis, char, int , etc...

Exibições: 2001

Responder esta

Respostas a este tópico

Olá Lideman,

Poste o sketch e a configuração dos datapoints que voce está usando, para que a galera possa ter condições de te auxiliar.

Abraço.


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,
        MB_REG1,
        MB_REG2,
        MB_REG3,
        MB_REG4,
        MB_REGS         /* total number of registers on slave */
};

int regs[MB_REGS];    /* this is the slave's modbus data map */
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Ultrasonic.h"
Ultrasonic ultrasonic(12,13);
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int gasPin = A4;
int gVal = 0;
#include "DHT.h"
#define DHTPIN 3     // pin conectado sensor umidade
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);

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);
        dht.begin();

}


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

    /* your code goes here */
float h = dht.readHumidity();
float t = dht.readTemperature();
regs[3]=h;
regs[4]=t;
sensors.requestTemperatures();
regs[0]=sensors.getTempCByIndex(0);
delay(10);
regs[1]=ultrasonic.Ranging(CM);
delay(10);
gVal = analogRead(gasPin);
regs[2]=gVal;

}

Eu sofri muito com isso. No meu caso foi a configuração do datapoint. Poste o programa e a configuração do scadabr.

Rapidinho vc terá ajuda.

 

Está usando qual biblioteca?

Segue a parte que eu adiciono dentro da programação:


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,
        MB_REG1,
        MB_REG2,
        MB_REG3,
        MB_REG4,
        MB_REGS         /* total number of registers on slave */
};

int regs[MB_REGS];    /* this is the slave's modbus data map */
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Ultrasonic.h"
Ultrasonic ultrasonic(12,13);
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int gasPin = A4;
int gVal = 0;
#include "DHT.h"
#define DHTPIN 3     // pin conectado sensor umidade
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);

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);
        dht.begin();

}


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

    /* your code goes here */
float h = dht.readHumidity();
float t = dht.readTemperature();
regs[3]=h;
regs[4]=t;
sensors.requestTemperatures();
regs[0]=sensors.getTempCByIndex(0);
delay(10);
regs[1]=ultrasonic.Ranging(CM);
delay(10);
gVal = analogRead(gasPin);
regs[2]=gVal;

}

Lideman,

então está usando este programa no arduino, correto? Vc checou se as configurações do arduino e do scadabr são as mesmas?

qual a função desta linha?

sensors.requestTemperatures();
regs[0]=sensors.getTempCByIndex(0);

Estou com dúvidas, mas não vi nada errado.

E o datapoint? Vc colocou os offsets corretamente? Lembra que começa no zero.

esta usando o serial do arduino não é?

é sempre legal vc filmar, mesmo que no celular e postar no youtube.

Já ajudei pessoas assim, fica mais facil de entendermos o problema.

PEssoal, finalmente consegui realizar a comunicação com todas as variáveis. Mas me deparei com um novo erro que não estou conseguindo solucionar. Os valores foram atualizados apenas uma única vez.... depois disso eles ficaram congelados. Ja tentei reiniciar o servidor, aumentar o tempo de atualização, mas nada funcionou. Segue o novo codigo utilizado no arduino e algumas imagens das minhas configurações.

Espero que alguém possa dar uma luz de como resolver isso,

desde já grato a todos !!

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);


/* Modbus RTU common parameters, the Master MUST use the same parameters */
enum {
MB_SLAVE = 1, /* modbus slave id */
};
/* slave registers example */
enum {
MB_REG0,
MB_REG1,
MB_REG2,
MB_REG3,
MB_REG4,
MB_REG5,
MB_REG6,
MB_REGS /* total number of registers on slave */
};

int regs[MB_REGS]; /* this is the slave's modbus data map */
//Vibracao
int vib;

//Pressao
#include <Wire.h>

#define BMP085_ADDRESS 0x77 // I2C address of BMP085

const unsigned char OSS = 0; // Oversampling Setting

// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
long b5; // // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...) so ...Temperature(...) must be called before ...Pressure(...).
short temperature;
long pressure;

//Sonar
#include "Ultrasonic.h"
Ultrasonic ultrasonic(13,12);

//Sensor de Gas
const int analogInPin = A1;
int sensorValue = 0;

//Humidade
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

void setup()
{
/* Modbus setup example, the master must use the same COM parameters */
/* 115200 bps, 8N1, two-device network */
configure_mb_slave(9600, 'n', 0);
//Pressao
Wire.begin();
bmp085Calibration();
//Humidade
dht.begin();
}


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

/* your code goes here */
{
//Vibracao
vib=analogRead(3);
if(vib>0)
{
regs[1]=vib; // vibracao 2

}
else
{
regs[1]=0; // vibracao 0
}

//Pressao
temperature = bmp085GetTemperature(bmp085ReadUT());
pressure = bmp085GetPressure(bmp085ReadUP());
regs[3]=temperature*0.1, DEC; // temp interna 3
regs[2]=pressure, DEC; // pressao 2


//Sonar
regs[0]=ultrasonic.Ranging(CM); //sonar 0

//Gas
sensorValue = analogRead(analogInPin);
regs[6]=sensorValue; // gas 6

//Humidade
float h = dht.readHumidity();
float t = dht.readTemperature();
regs[5]=h; //humidade 5
regs[4]=t; //temp externa 4


//Timer
delay(200);
}

}
// Calibrando Pressao
void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}

// Calculate temperature given ut.
// Value returned will be in units of 0.1 deg C
short bmp085GetTemperature(unsigned int ut)
{
long x1, x2;

x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc 11)/(x1 + md);
b5 = x1 + x2;

return ((b5 + 8)>>4);
}

// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up)
{
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;

b6 = b5 - 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)OSS) + 2)>>2;

// Calculate B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

b7 = ((unsigned long)(up - b3) * (50000>>OSS));
if (b7 < 0x80000000)
p = (b71)/b4;
else
p = (b7/b4)1;

x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;

return p;
}

// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
{
unsigned char data;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.send(address);
Wire.endTransmission();

Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available())
;

return Wire.receive();
}

// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
{
unsigned char msb, lsb;

Wire.beginTransmission(BMP085_ADDRESS);
Wire.send(address);
Wire.endTransmission();

Wire.requestFrom(BMP085_ADDRESS, 2);
while(Wire.available()<2)
;
msb = Wire.receive();
lsb = Wire.receive();

return (int) msb8 | lsb;
}

// Read the uncompensated temperature value
unsigned int bmp085ReadUT()
{
unsigned int ut;

// Write 0x2E into Register 0xF4
// This requests a temperature reading
Wire.beginTransmission(BMP085_ADDRESS);
Wire.send(0xF4);
Wire.send(0x2E);
Wire.endTransmission();

// Wait at least 4.5ms
delay(5);

// Read two bytes from registers 0xF6 and 0xF7
ut = bmp085ReadInt(0xF6);
return ut;
}

// Read the uncompensated pressure value
unsigned long bmp085ReadUP()
{
unsigned char msb, lsb, xlsb;
unsigned long up = 0;

// Write 0x34+(OSS6) into register 0xF4
// Request a pressure reading w/ oversampling setting
Wire.beginTransmission(BMP085_ADDRESS);
Wire.send(0xF4);
Wire.send(0x34 + (OSS6));
Wire.endTransmission();

// Wait for conversion, delay time dependent on OSS
delay(2 + (3OSS));

// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADDRESS);
Wire.send(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 3);

// Wait for data to become available
while(Wire.available() < 3)
;
msb = Wire.receive();
lsb = Wire.receive();
xlsb = Wire.receive();

up = (((unsigned long) msb 16) | ((unsigned long) lsb 8) | (unsigned long) xlsb) >> (8-OSS);

return up;
}
/****************************************************************************
* BEGIN MODBUS RTU SLAVE FUNCTIONS
****************************************************************************/

/* global variables */
unsigned int Txenpin = 0; /* Enable transmission pin, used on RS485 networks */


/* enum of supported modbus function codes. If you implement a new one, put its function code here ! */
enum {
FC_READ_REGS = 0x03, //Read contiguous block of holding register
FC_WRITE_REG = 0x06, //Write single holding register
FC_WRITE_REGS = 0x10 //Write block of contiguous registers
};

/* supported functions. If you implement a new one, put its function code into this array! */
const unsigned char fsupported[] = { FC_READ_REGS, FC_WRITE_REG, FC_WRITE_REGS };

/* constants */
enum {
MAX_READ_REGS = 0x7D,
MAX_WRITE_REGS = 0x7B,
MAX_MESSAGE_LENGTH = 256
};


enum {
RESPONSE_SIZE = 6,
EXCEPTION_SIZE = 3,
CHECKSUM_SIZE = 2
};

/* exceptions code */
enum {
NO_REPLY = -1,
EXC_FUNC_CODE = 1,
EXC_ADDR_RANGE = 2,
EXC_REGS_QUANT = 3,
EXC_EXECUTE = 4
};

/* positions inside the query/response array */
enum {
SLAVE = 0,
FUNC,
START_H,
START_L,
REGS_H,
REGS_L,
BYTE_CNT
};


/*
CRC

INPUTS:
buf -> Array containing message to be sent to controller.
start -> Start of loop in crc counter, usually 0.
cnt -> Amount of bytes in message being sent to controller/
OUTPUTS:
temp -> Returns crc byte for message.
COMMENTS:
This routine calculates the crc high and low byte of a message.
Note that this crc is only used for Modbus, not Modbus+ etc.
****************************************************************************/

unsigned int crc(unsigned char *buf, unsigned char start,
unsigned char cnt)
{
unsigned char i, j;
unsigned temp, temp2, flag;

temp = 0xFFFF;

for (i = start; i < cnt; i++) {
temp = temp ^ buf[i];

for (j = 1; j <= 8; j++) {
flag = temp & 0x0001;
temp = temp >> 1;
if (flag)
temp = temp ^ 0xA001;
}
}

/* Reverse byte order. */
temp2 = temp >> 8;
temp = (temp 8) | temp2;
temp &= 0xFFFF;

return (temp);
}


/***********************************************************************
*
* The following functions construct the required query into
* a modbus query packet.
*
***********************************************************************/

/*
* Start of the packet of a read_holding_register response
*/
void build_read_packet(unsigned char slave, unsigned char function,
unsigned char count, unsigned char *packet)
{
packet[SLAVE] = slave;
packet[FUNC] = function;
packet[2] = count * 2;
}

/*
* Start of the packet of a preset_multiple_register response
*/
void build_write_packet(unsigned char slave, unsigned char function,
unsigned int start_addr,
unsigned char count,
unsigned char *packet)
{
packet[SLAVE] = slave;
packet[FUNC] = function;
packet[START_H] = start_addr >> 8;
packet[START_L] = start_addr & 0x00ff;
packet[REGS_H] = 0x00;
packet[REGS_L] = count;
}

/*
* Start of the packet of a write_single_register response
*/
void build_write_single_packet(unsigned char slave, unsigned char function,
unsigned int write_addr, unsigned int reg_val, unsigned char* packet)
{
packet[SLAVE] = slave;
packet[FUNC] = function;
packet[START_H] = write_addr >> 8;
packet[START_L] = write_addr & 0x00ff;
packet[REGS_H] = reg_val >> 8;
packet[REGS_L] = reg_val & 0x00ff;
}


/*
* Start of the packet of an exception response
*/
void build_error_packet(unsigned char slave, unsigned char function,
unsigned char exception, unsigned char *packet)
{
packet[SLAVE] = slave;
packet[FUNC] = function + 0x80;
packet[2] = exception;
}


/*************************************************************************
*
* modbus_query( packet, length)
*
* Function to add a checksum to the end of a packet.
* Please note that the packet array must be at least 2 fields longer than
* string_length.
**************************************************************************/

void modbus_reply(unsigned char *packet, unsigned char string_length)
{
int temp_crc;

temp_crc = crc(packet, 0, string_length);
packet[string_length] = temp_crc >> 8;
string_length++;
packet[string_length] = temp_crc & 0x00FF;
}

/***********************************************************************
*
* send_reply( query_string, query_length )
*
* Function to send a reply to a modbus master.
* Returns: total number of characters sent
************************************************************************/

int send_reply(unsigned char *query, unsigned char string_length)
{
unsigned char i;

if (Txenpin > 1) { // set MAX485 to speak mode
UCSR0A=UCSR0A |(1 TXC0);
digitalWrite( Txenpin, HIGH);
delay(1);
}

modbus_reply(query, string_length);
string_length += 2;

for (i = 0; i < string_length; i++) {
Serial.print(query[i], BYTE);
}

if (Txenpin > 1) {// set MAX485 to listen mode
while (!(UCSR0A & (1 TXC0)));
digitalWrite( Txenpin, LOW);
}

return i; /* it does not mean that the write was succesful, though */
}

/***********************************************************************
*
* receive_request( array_for_data )
*
* Function to monitor for a request from the modbus master.
*
* Returns: Total number of characters received if OK
* 0 if there is no request
* A negative error code on failure
***********************************************************************/

int receive_request(unsigned char *received_string)
{
int bytes_received = 0;

/* FIXME: does Serial.available wait 1.5T or 3.5T before exiting the loop? */
while (Serial.available()) {
received_string[bytes_received] = Serial.read();
bytes_received++;
if (bytes_received >= MAX_MESSAGE_LENGTH)
return NO_REPLY; /* port error */
}

return (bytes_received);
}


/*********************************************************************
*
* modbus_request(slave_id, request_data_array)
*
* Function to the correct request is returned and that the checksum
* is correct.
*
* Returns: string_length if OK
* 0 if failed
* Less than 0 for exception errors
*
* Note: All functions used for sending or receiving data via
* modbus return these return values.
*
**********************************************************************/

int modbus_request(unsigned char slave, unsigned char *data)
{
int response_length;
unsigned int crc_calc = 0;
unsigned int crc_received = 0;
unsigned char recv_crc_hi;
unsigned char recv_crc_lo;

response_length = receive_request(data);

if (response_length > 0) {
crc_calc = crc(data, 0, response_length - 2);
recv_crc_hi = (unsigned) data[response_length - 2];
recv_crc_lo = (unsigned) data[response_length - 1];
crc_received = data[response_length - 2];
crc_received = (unsigned) crc_received 8;
crc_received =
crc_received | (unsigned) data[response_length - 1];

/*********** check CRC of response ************/
if (crc_calc != crc_received) {
return NO_REPLY;
}

/* check for slave id */
if (slave != data[SLAVE]) {
return NO_REPLY;
}
}
return (response_length);
}

/*********************************************************************
*
* validate_request(request_data_array, request_length, available_regs)
*
* Function to check that the request can be processed by the slave.
*
* Returns: 0 if OK
* A negative exception code on error
*
**********************************************************************/

int validate_request(unsigned char *data, unsigned char length,
unsigned int regs_size)
{
int i, fcnt = 0;
unsigned int regs_num = 0;
unsigned int start_addr = 0;
unsigned char max_regs_num;

/* check function code */
for (i = 0; i < sizeof(fsupported); i++) {
if (fsupported[i] == data[FUNC]) {
fcnt = 1;
break;
}
}
if (0 == fcnt)
return EXC_FUNC_CODE;

if (FC_WRITE_REG == data[FUNC]) {
/* For function write single reg, this is the target reg.*/
regs_num = ((int) data[START_H] 8) + (int) data[START_L];
if (regs_num >= regs_size)
return EXC_ADDR_RANGE;
return 0;
}

/* For functions read/write regs, this is the range. */
regs_num = ((int) data[REGS_H] 8) + (int) data[REGS_L];

/* check quantity of registers */
if (FC_READ_REGS == data[FUNC])
max_regs_num = MAX_READ_REGS;
else if (FC_WRITE_REGS == data[FUNC])
max_regs_num = MAX_WRITE_REGS;

if ((regs_num < 1) || (regs_num > max_regs_num))
return EXC_REGS_QUANT;

/* check registers range, start address is 0 */
start_addr = ((int) data[START_H] 8) + (int) data[START_L];
if ((start_addr + regs_num) > regs_size)
return EXC_ADDR_RANGE;

return 0; /* OK, no exception */
}

/************************************************************************
*
* write_regs(first_register, data_array, registers_array)
*
* writes into the slave's holding registers the data in query,
* starting at start_addr.
*
* Returns: the number of registers written
************************************************************************/

int write_regs(unsigned int start_addr, unsigned char *query, int *regs)
{
int temp;
unsigned int i;

for (i = 0; i < query[REGS_L]; i++) {
/* shift reg hi_byte to temp */
temp = (int) query[(BYTE_CNT + 1) + i * 2] 8;
/* OR with lo_byte */
temp = temp | (int) query[(BYTE_CNT + 2) + i * 2];

regs[start_addr + i] = temp;
}
return i;
}

/************************************************************************
*
* preset_multiple_registers(slave_id, first_register, number_of_registers,
* data_array, registers_array)
*
* Write the data from an array into the holding registers of the slave.
*
*************************************************************************/

int preset_multiple_registers(unsigned char slave,
unsigned int start_addr,
unsigned char count,
unsigned char *query,
int *regs)
{
unsigned char function = FC_WRITE_REGS; /* Preset Multiple Registers */
int status = 0;
unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];

build_write_packet(slave, function, start_addr, count, packet);

if (write_regs(start_addr, query, regs)) {
status = send_reply(packet, RESPONSE_SIZE);
}

return (status);
}


/************************************************************************
*
* write_single_register(slave_id, write_addr, data_array, registers_array)
*
* Write a single int val into a single holding register of the slave.
*
*************************************************************************/

int write_single_register(unsigned char slave,
unsigned int write_addr, unsigned char *query, int *regs)
{
unsigned char function = FC_WRITE_REG; /* Function: Write Single Register */
int status = 0;
unsigned int reg_val;
unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];

reg_val = query[REGS_H] 8 | query[REGS_L];
build_write_single_packet(slave, function, write_addr, reg_val, packet);
regs[write_addr] = (int) reg_val;
/*
written.start_addr=write_addr;
written.num_regs=1;
*/
status = send_reply(packet, RESPONSE_SIZE);

return (status);
}


/************************************************************************
*
* read_holding_registers(slave_id, first_register, number_of_registers,
* registers_array)
*
* reads the slave's holdings registers and sends them to the Modbus master
*
*************************************************************************/

int read_holding_registers(unsigned char slave, unsigned int start_addr,

unsigned char reg_count, int *regs)
{
unsigned char function = 0x03; /* Function 03: Read Holding Registers */
int packet_size = 3;
int status;
unsigned int i;
unsigned char packet[MAX_MESSAGE_LENGTH];

build_read_packet(slave, function, reg_count, packet);

for (i = start_addr; i < (start_addr + (unsigned int) reg_count);
i++) {
packet[packet_size] = regs[i] >> 8;
packet_size++;
packet[packet_size] = regs[i] & 0x00FF;
packet_size++;
}

status = send_reply(packet, packet_size);

return (status);
}


void configure_mb_slave(long baud, char parity, char txenpin)
{
Serial.begin(baud);

switch (parity) {
case 'e': // 8E1
UCSR0C |= ((1UPM01) | (1UCSZ01) | (1UCSZ00));
// UCSR0C &= ~((1UPM00) | (1UCSZ02) | (1USBS0));
break;
case 'o': // 8O1
UCSR0C |= ((1UPM01) | (1UPM00) | (1UCSZ01) | (1UCSZ00));
// UCSR0C &= ~((1UCSZ02) | (1USBS0));
break;
case 'n': // 8N1
UCSR0C |= ((1UCSZ01) | (1UCSZ00));
// UCSR0C &= ~((1UPM01) | (1UPM00) | (1UCSZ02) | (1USBS0));
break;
default:
break;
}

if (txenpin > 1) { // pin 0 & pin 1 are reserved for RX/TX
Txenpin = txenpin; /* set global variable */
pinMode(Txenpin, OUTPUT);
digitalWrite(Txenpin, LOW);
}

return;
}

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

unsigned long Nowdt = 0;
unsigned int lastBytesReceived;
const unsigned long T35 = 5;

int update_mb_slave(unsigned char slave, int *regs,
unsigned int regs_size)
{
unsigned char query[MAX_MESSAGE_LENGTH];
unsigned char errpacket[EXCEPTION_SIZE + CHECKSUM_SIZE];
unsigned int start_addr;
int exception;
int length = Serial.available();
unsigned long now = millis();

if (length == 0) {
lastBytesReceived = 0;
return 0;
}

if (lastBytesReceived != length) {
lastBytesReceived = length;
Nowdt = now + T35;
return 0;
}
if (now < Nowdt)
return 0;

lastBytesReceived = 0;

length = modbus_request(slave, query);
if (length < 1)
return length;

exception = validate_request(query, length, regs_size);
if (exception) {
build_error_packet(slave, query[FUNC], exception,
errpacket);
send_reply(errpacket, EXCEPTION_SIZE);
return (exception);
}


start_addr = ((int) query[START_H] 8) +
(int) query[START_L];
switch (query[FUNC]) {
case FC_READ_REGS:
return read_holding_registers(slave,
start_addr,
query[REGS_L],
regs);
break;
case FC_WRITE_REGS:
return preset_multiple_registers(slave,
start_addr,
query[REGS_L],
query,
regs);
break;
case FC_WRITE_REG:
write_single_register(slave,
start_addr,
query,
regs);
break;
}
}

Anexos

lembrando que ja alterei o baud rate para 115200

Oi Lideman,

ainda está às voltas com o problema ou teve solução?

por favor tente identificar se foi o arduino que travou, ou se o software que pifou...

1) pra saber se foi o arduino que travou, faça alguma lógica p. ex um "blink" no seu loop, veja se continua funcionando legal, ou encontre outra forma de debugar passo-a-passo (comentando as linhas do arduino, rodando por etapas, etc.)

outra forma é desplugar/plugar de novo e ver se o scadabr consegue ler outro dado atualizado (neste caso, depois do reset ele responderia mais uma aquisição, pelo menos)

2) pra saber se é o scadabr que tá travando: sem resetar o arduino, pare o datasource, pare o servidor tomcat, depois reiniciar tudo novamente (o tomcat e o datasource), e veja se ele consegue fazer mais uma atualização... se funcionar realmente foi o driver do modbus que "pendurou", comente aqui com a gente

estou respondendo sem rodar o teu código, e é dificil bater o olho assim e encontrar o problema :-)

afinal o programa já está crescidinho...

no caso seria melhor fazer alguns testes mais específicos e isolar o problema, por exemplo com uma rotina de modbus bem mais simples (apenas ler um registrador constante, por exemplo...)

boa sorte e vai postando aqui

abç

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço