RS-485 modbus library

Hey @peergum my apologies. I have been meaning to reply, yet my schedule has been absolutely hectic!

I’m just trying to get my private Git server setup. Once it’s setup, I can start porting some of the code over. It just kills me inside having to update code without proper rev control setup lol.

I’m super glad you figured out your project!

@peergum - would you be willing to share your modbus library? I can’t seem to get the default library to work right.

hello guys here is the library that work ok for me… but there are other modbus variants around there that works…

https://www.4shared.com/zip/VC3IaJYDca/modbus.html

I just posted the two files here: https://github.com/peergum/ModbusMaster-Electron

I unfortunately do not have a lot of time to document right now, since I’m travelling through Mexico and down to Argentina on a motorcycle and my time + internet connections are both limited :wink: but feel free to drop me a question or open a ticket on github and I’ll do my best to answer as soon as possible.

Cheers
Phil.

@peergum that is such great journey, enjoy your travel, have fun, disfruta el buen asado Argentino, la comida Peruana etc.

1 Like

Man, yeah, you are living the life I aspire to! Enjoy the journey.

1 Like

@peergum I am trying to start a rs485 project using the electron. When I copy in your libraries, i recieve errors from the online compiler surrounding classes in modbusmaster. I have copied all code from your github. Community assistance would be great.

Upon a retry, and a clean copy of the code over from peergum’s git, everything compiles just fine. More to come!

I was about to reply, I needed more code to help you. Glad it works. I’m available if you need help - not full time, though, travelling from Canada to Argentina on a motorbike doesn’t give too much free time (besides still working on the RS485 project for my remote employer :slight_smile: ) Btw, in Guatemala currently :slight_smile:

2 Likes

I have a project that needs to read from two sensors, but their slave IDs are not easily known beforehand. Thus I want to scan over some range of IDs (say 0-100) until I find one that responds. I am using the Modbus library available from the web IDE (which compiles fine). Is there a decent way to scan thru slave IDs? As i the library, the IDs are established when invoking the constructor. Or at least to set up an array of constructors so they can easily be scanned?. Thanks

@peergum Not sure which specific code you ported your ModbusMaster one from (you said 4-20’s on the Github), but can it also be used as a Slave? I browsed through the code and don’t see a way it can. Was just curious if the original code has a Slave version as well that can be easily ported.

Hope you’re enjoying your trip and made it to the next country…in El Salvador, Costa Rica, Nicaragua now?

EDIT: Got @peekay123 's version working. Had to add a second TXEN to this line at the start of the code:

Modbus slave(2,1,TXEN, TXEN); // Slave @2, Serial1 TX/RX pins, RE/DE connected together

In setup, also had to add this for some reason. It would not work without:

pinMode(TXEN, OUTPUT);

I just ported the code. I’m also working on scanning device, so I may provide an update to the library shortly. Very easy to fix temporarily, though. Just update _u8MBSlave with the new value.

Glad you found a way around, and no, the ModbusMaster lib wouldn’t work for a slave. The main method (ModbusMasterTransaction) works by sending, then receiving. For a slave, the logic would have to be inversed, and the caller would provide the values through a callback, for instance.

1 Like

Just updated the lib in my github repository to include setSlave(uint8_t slave). Call this method any time after begin to switch the ID used in messages sent onto the bus. For the note, I’ll make this an official community lib - despite the fact there’s another version with the same name, derived from the same original arduino lib.

Note this is a very “rough” work. I didn’t include any of the examples, docs, etc, for not having tested any with the lib, but I use the code on a project with 2 sensors of different brands (Nuflo, Troll) and it IS highly functional.

2 Likes

@peergum, do you have any example code for this library? I do not see in your library where you select your enable for the MAX485 driver chip?

Kind regards,

Geert

You need to define 3 functions and call methods preTransmission, postTransmission and idle with them as arguments (I called the function by the same name below)

  • preTransmission switches the MAX to TX mode
  • postTransmission switches to RX
  • idle is called while waiting for a response
// Switch to SEND mode
// WARNING: the order the TX/RX switching is IMPORTANT
// wrong order can shutdown the MAX IC.
void preTransmission(void)
{
  // FIRST enable TX
  // this should reenable the IC in SEND mode
  if (TX_ENABLE_PIN) {
      digitalWrite(TX_ENABLE_PIN, HIGH);
  }
  // THEN disable RX
  // with TX LOW, this would switch the IC to sleep mode
  if (RX_DISABLE_PIN) {
      digitalWrite(RX_DISABLE_PIN, HIGH);
  }
  delay(20);
}

// Switch to RECEIVE mode
// WARNING: the order the TX/RX switching is IMPORTANT
// wrong order can shutdown the MAX IC.
void postTransmission(void)
{
    // FIRST enable RX
    if (RX_DISABLE_PIN) {
        digitalWrite(RX_DISABLE_PIN, LOW);
    }
    // THEN disable TX
    if (TX_ENABLE_PIN) {
        digitalWrite(TX_ENABLE_PIN, LOW);
    }
    delay(20);
}

void idle(void) {
    delay(10);
}

Note that I use both TX and ^RX pins of the max. you can simplify by using one pin on the electron and connecting it to both pins on the max if you don’t plan to switch the max to sleep mode

1 Like

I am having some trouble controlling a slave device using my Photon. The specs of a slave device I am trying to communicate with says that it uses 4800 odd parity. I was wondering how I can achieve this using the existent modbus master libraries for Particle (theres 2 at the moment, one of which is @peergum and the other is @peekay123 I believe . Is there a setting somewhere I can set? I’ve used modbus simulators on my PC and the commands work fine as long as I set it at odd parity. Any help is much appreciated.

Unfortunately the Modbus library I adapted only uses RTU mode, which is binary/8 bits. I believe @peekay123’s version also only handles RTU. To communicate using parity, you’ll have to find/develop a lib that uses ASCII mode (7 bits + parity).

Alternatively you should check your device’s doc, they most probably handle RTU mode as well.

Cheers
Phil


Thanks peergum for the quick response. I’ve attached the specifications. It is in RTU mode I believe. I’ve tried to fiddle with a bunch of settings in my modbus simulator and the only thing that seems to work is 4800 baud rate with odd parity. Very weird.

Try to setup the parity on the Serial interface manually after calling begin on your ModbusMaster instance:

ModbusMaster sensor;

setup() {
  sensor.begin(1, Serial1); // using slave ID 1 on Serial
  Serial1.begin(4800, SERIAL_8O1);
  // ... test a comm here
}

Also what chip do you use to communicate with your device?

1 Like