Tengo algunos problemas al intentar consultar un esclavo modbus con un Arduino a través de RS485.
Ya he logrado consultar un esclavo Modbus de software que se ejecuta en mi PC a través del puerto USB / COM usando el Libray de ModbusMaster , por lo tanto, no debería ser un problema de software.
Leí sobre TTL y las conversiones de nivel y coloco un circuito como este en una placa de pruebas:
Usandoelmismofirmware/esquemaquefuncionóparaelsoftwareesclavo,conectéelpinyelRXdearduinoalmax485yAyBalesclavomodbusyemitívariassolicitudes.
PuedoverlasseñalesconvertidasporelMAX485(CPA1114)atravésdelosciloscopioyparecesercorrecto.Elleddelesclavomodbusseenciendecuandoveunatransacciónmodbus.Sinembargo,loqueleícomoresultadodelasolicitudessiempre0xE0
(iddeesclavonoválido)o0xE2
(tiempodeespera).
Consultéalesclavoconlamismasolicitudutilizandootraherramienta(unconvertidorRS485/USByunescánerModbusCAS),ydalosresultadosesperados,esdecir,datos0x01
.
EsteeselcódigoqueestoyejecutandoenunArduinoEthernet(conunapantallaparafinesdedepuración):
#include<ModbusMaster.h>#include<LiquidCrystal.h>LiquidCrystallcd(12,11,4,5,6,7);ModbusMasternode(1);voidsetup(){pinMode(3,OUTPUT);node.begin(19200);lcd.begin(16,2);}voidloop(){uint16_tm_startAddress=1;uint8_tm_length=1;uint8_tresult;digitalWrite(3,HIGH);//TXresult=node.readHoldingRegisters(m_startAddress,m_length);lcd.clear();if(result==node.ku8MBSuccess){lcd.print("DATA:");
digitalWrite(3, LOW); // RX
for (uint8_t j = 0; j < m_length; j++) lcd.print( node.getResponseBuffer(j), HEX );
} else {
lcd.print("ERR ");
lcd.print(result, HEX);
}
delay(500);
}
Estas son las señales de solicitud emitidas por el Arduino, que siempre fallan en obtener una respuesta de datos, y la otra herramienta, que siempre tiene éxito:
señaldesolicitudArduino
señal del convertidor USB / RS485
Superposicióndelasdosseñales
¿Hayalgúnproblemaconlaseñaldesolicitud?¿Estoycometiendoalgúnerrorenelcircuitooenelcódigo?
Cualquierpunteroseríamuyapreciado.
EDIT:
SegúnlosugeridoporKvegaoro,lohicefuncionareditandolabibliotecaModbusMasterparacambiarelpinD3alestadocorrectoenelmomentoadecuado.Parahacerlo,utilicéuncódigoqueencontréen
Esta es la edición que he hecho en ModbusMaster.cpp
, función ModbusMasterTransaction
, comenzando en la línea 746:
// code edited to work with MAX485:
// transmit request
UCSR0A=UCSR0A |(1 << TXC0);
Serial.flush();
digitalWrite(3, HIGH);
for (i = 0; i < u8ModbusADUSize; i++)
{
#if defined(ARDUINO) && ARDUINO >= 100
MBSerial.write(u8ModbusADU[i]);
#else
MBSerial.print(u8ModbusADU[i], BYTE);
#endif
}
while (!(UCSR0A & (1 << TXC0)));
digitalWrite(3, LOW);
// --
u8ModbusADUSize = 0;
Tenga en cuenta que el pin D3 está codificado en la biblioteca, por lo que no es un buen diseño. Si alguien lo necesita, lo ajustará mejor. ¡Aunque funciona!