Open ajpaezm opened 4 years ago
See here : #127
Thanks.
I made the changes suggested in lines 708 and 752. Apologies for this, but can you tell me where should I paste the snippet about the calculations for T3_5 and T1_5?
if (baud > 19200)
{
_T1_5 = 750; // 750 us
_frameDelay = 1750; // 1750 us
}
else
{
// _frameDalay = T3.5
_T1_5 = 16500000 / baud; // 1 packet = always 11 bits
_frameDelay = 38500000 / baud; // 1 packet = always 11 bits
}
Also, if this goes in ModbusMaster.cpp, shouldn't I name _T1_5 as T1_5 and _frameDelay as T3_5?
In case I'm sure I'm going to be working with a BaudRate below 19200, can I just hardcode T1_5 and T3_5 like this?
From ModbusMaster.cpp:
uint8_t ModbusMaster::ModbusMasterTransaction(uint8_t u8MBFunction)
{
uint8_t u8ModbusADU[256];
uint8_t u8ModbusADUSize = 0;
uint8_t i, u8Qty;
uint16_t u16CRC;
uint32_t u32StartTime;
uint8_t u8BytesLeft = 8;
uint8_t u8MBStatus = ku8MBSuccess;
unsigned long T1_5 = 16500000L/9600; //fixed baud rate of 9600
unsigned long T3_5 = 38500000L/9600; // fixed baud rate of 9600
...
This is the first change (for T3_5):
This is the second change (for T1_5):
I performed such changes and the response continued to be the same (0xE2). Did I execute these proposed modifications correctly? I'd be glad to know (and if you have any additional tips as well, of course).
Thanks a lot for your valuable time.
delays seem to be at the right place.
enable transmission in _preTransmission() callcack : turn HIGH the RE/DE pins, and then disable transmission in _postTransmission() callback : done !
On my side, I added Serial information in the begin() function, with T1.5 and T3.5 calculations. (to be honest, I forked the project (198th fork on Git !), renamed all functions and variables for readability, and also removed the Doxygen comments : reading the sources, you will instantly understand what I did)
You could also make T1_5 and T3_5 public, and set them anywhere in your code, before you initiate communications.
Also, don't forget :
if you use a bare MAX485 IC
On my side I had problems with a VFD : in the documentation, A and B are reverted !
Here's the schematics I made and use (on a STM32, with a DIP-8 MAX485, works fine with 3.3V logic, no need for a MAX3485) :
R15 = R16 = 22K R17 = 100R to 120R
enable transmission in _preTransmission() callcack : turn HIGH the RE/DE pins, and then disable transmission in _postTransmission() callback : done !
Ok, about this, I added these (unless you meant it in the main.cpp file and not on the ModbusMaster.cpp):
I will attempt your circuit diagram and see whats up. Also will use other modules to try to connect to as well.
I didn't try to fork it as you mentioned it.
I'll let you know if any of these work out!
I ran into the same problem. I can't read any data from HoldingRegisters using Arduino Mega2560 + MAX485 shield, though I can write into it successfully to control HVAC unit and I can read data from HoldingRegisters using Modbus-to-USB converter. DE and RE are both connected to pin 39.
@yet-another-average-joe, I tried replacing ModbusMaster lib with your lib - YAAJ_ModbusMaster, but still getting the same result: E2 error. Any thoughts what I'm doing wrong?
class OutputVentilation : public IO
{
private:
Stream *outputSerial;
ObjectAbstract *input;
YAAJ_ModbusMaster modbus;
public:
OutputVentilation(const char *name PROGMEM, PinOutput* outputPin, ObjectAbstract *input, Stream *outputSerial) : IO(name, outputPin, false, 0)
{
this->outputSerial = outputSerial;
this->input = input;
stateChanged = true;
valueChanged = true;
Serial.println("init modbus");
modbus.begin(Serial2, 19200, SERIAL_8E1, 1, 39, 2500);
Serial.println("init modbus complete");
setValue(this->read(VregAddrSpeed));
setState(value);
// modbus.preTransmission(this->preTransmission);
// modbus.postTransmission(this->postTransmission);
}
void write(unsigned int reg, unsigned int value)
{
((HardwareSerial*)outputSerial)->begin(19200, SERIAL_8E1);
Serial.println("write modbus");
modbus.F6_WriteSingleRegister(reg, value);
read(reg);
}
unsigned int read(unsigned int reg)
{
((HardwareSerial*)outputSerial)->begin(19200, SERIAL_8E1);
Serial.println("read modbus");
Serial.println(modbus.F3_ReadMultipleHoldingRegisters(reg, 1));
Serial.println(modbus.getRxBuf(0));
return modbus.getRxBuf(0);
}
}
Always getting error on read:
Started
init modbus
init modbus complete
read modbus
227
39470
write modbus
read modbus
226
39470
This thread is definetly not the right place to ask about a forked library ! This will just add confusion ! I heavily changed the library name in order to avoid this.
At first glance, I see a problem :
this->outputSerial = outputSerial;
Not sure the compiler will make any difference between "this->outputSerial" and "outputSerial" (alone) in the context. At first, I'd replace "outputParameter" with "_outputParameter" (or I don't know about this trick...)
Why do you have to cast the stream ? My fork is intended for HardwareSerial only. Not for generic Stream. It will not work with software serial. And it's been tested on STM32 only. Not with AVRs. Maybe I forgot to say.
OxE2 is TIMEOUT. The most irritating and frustating error ;)
Please, open an issue on YAAJ_ModbusMaster, not there ! This is not 4-20mA related, and I'd be 4-20mA, I'd close this thread right now !!! See you later on https://github.com/yet-another-average-joe/YAAJ_ModbusMaster/issues (the 190th fork or so). But as is, many information are missing.
Well, the issue is that base ModbusMaster library doesn't work for reading holding registers in my configuration (Arduino Mega 2560 + Max485). I already spent few days trying to figure out why. And one of my guesses was timings and delays which are absent in this library. Though I saw delays included with some other Modbus implementations. But @yet-another-average-joe 's fix doesn't work in my case too :( And yes, these errors are quite frustrating.
So this code doesn't work for reading:
class OutputVentilation : public IO
{
private:
Stream *outputSerial;
ObjectAbstract *input;
ModbusMaster modbus;
static void preTransmission()
{
digitalWrite(RS485_MB_PIN, HIGH);
delay(100);
}
static void postTransmission()
{
delay(100);
digitalWrite(RS485_MB_PIN, LOW);
}
public:
OutputVentilation(const char *name PROGMEM, PinOutput* outputPin, ObjectAbstract *input, Stream *outputSerial) : IO(name, outputPin, false, 0)
{
this->outputSerial = outputSerial;
this->input = input;
stateChanged = true;
valueChanged = true;
modbus.begin(1, *outputSerial);
modbus.preTransmission(this->preTransmission);
modbus.postTransmission(this->postTransmission);
setValue(this->read(VregAddrSpeed));
setState(value);
}
void write(unsigned int reg, unsigned int value)
{
((HardwareSerial*)outputSerial)->begin(RS485_MB_PIN_BAUD_RATE, SERIAL_8E1);
modbus.writeSingleRegister(reg, value);
read(reg);
}
unsigned int read(unsigned int reg)
{
((HardwareSerial*)outputSerial)->begin(RS485_MB_PIN_BAUD_RATE, SERIAL_8E1);
Serial.println(modbus.readHoldingRegisters(reg, 1));
Serial.println(modbus.getResponseBuffer(0));
return modbus.getResponseBuffer(0);
}
}
It also returns E2(226)/E3(227) errors:
Started
227
5120
226
5120
PS: good point about casting Stream, in will replace it HardwareSerial, because I actually use Serial2.
I am having the same problem if you managed to fix it please kindly assist
my code read holding registers in Arduino Uno but dont works in Arduino Mega, i dont know why
I have an issue trying to use Arduino UNO for Modbus communication with a certain device I'm trying to get readings from.
Devices: 1) ARDUINO UNO Board. 2) MAXmax485 (DE-RE connected together). 3) CEM M-RS485 (this is the link: http://docs.circutor.com/docs/M014B01-03.pdf), properly connected to A+ and B-.
The code is as follows:
According to the guide section 4.4.4.1.- Configuration variables for the CEM M-RS485 everything is set up. The registry I'm trying to read is 2710, which should return the following (see image attached to the message please).![image](https://user-images.githubusercontent.com/47114614/66969056-ff711c00-f055-11e9-9a41-6d7644e6521c.png)
In the table of section 4.4.4.5. there are also commands that should be readable, but no luck whatsoever.![image](https://user-images.githubusercontent.com/47114614/66969106-2deef700-f056-11e9-9ce4-0c5b166f7ed4.png)
Some strange values are included in the response (like "SOH", "EOT" and another one but I think is garbage, I'm not sure). There's one value that is relevant though, 0xE2, which corresponds to ku8MBResponseTimedOut (he entire response was not received within the timeout period, ModbusMaster::ku8MBResponseTimeout).
Can someone help find out what the issue might be? Perhaps there's something I'm not properly setting inside my code, as the physical setup seems to be correct.
Thanks in advance!