RS485 Communication with Grundfos Genibus

Good day,

I am really struggling to understand how to interpret the spec sheets attached and send the correct byte values over rs485 from my arduino.

I have connected everything correctly etc. but I do not understand how to ie. set class 3 id 6.

I requirements are:
1.) to set class 3 to id 6 to open valve
2.) to set class 3 to id 5 to close valve

I presume i then need to do a crc check ?

any advice would be greatly appreciated.

thank you.

Looking at the first image you posted, then, yes, you need to calculate a CRC16 checksum for the message you want to send.

EDIT: there's a GENIBus-Arduino library on github that might do what you want.

1 Like

ok i am still pulling my hair out.
that Genibus library does not make sense to me. in the example code it also states that there is an arduino arror and that it is still to be completed.
i have tried modbusmaster library, simplemodbusmaster library, a simple sketch which creates a byte array with ie:

0x27, 0x0F, 0x20, 0x01, 0x02, 0x04,, 0x02, 0x10, 0x1A, 0x1B, 0x04, 0x02, 0x04, 0x05, 0x03, 0x81, 0x06, 0x80, 0x2A as per the specifications for a data request per the attachment that i uploaded and i get nothing...

the spec sheet says that i need to set class 3, id 6 for opening of the valve & set class 3, id 5 for closing the valve.

am i missing something major here or misinterpreting how to send those values from my arduino sketch to the max485 tranceiver.

the tranceiver is wired:

arduino tx -> max485 DI pin
arduino rx -> max485 RO pin
arduino pin 30 -> max485 DE/RE pin (tranmit enable)
arduino 5v -> max485 VCC
arduino gnd -> max485 GND

then the max A and B is connected to controller:
A -> A
B -> B

ive also tried sending from serial port monitor various hex arrays but dont get anything either, i presume this is perhaps because i would need to pull the transmit enable pin to high for transmit and then back to low for receive which i cannot do from serial port?

With RS485, you need to tell the MAX485 transceiver which way the data is flowing. Usually you put it into Tx mode, send the serial data, WAIT for the data to be transmitted (NOT the same as serial.print() returning) - use serial.flush() to wait, and then switch back to Rx mode.

One of the software serial libraries is generally used if you only have the 1 hardware serial port - like on an UNO, rather than the hardware serial port, as this is connected to the serial-USB converter chip.

The Modbus libraries generally do this for you. However, the Modbus libraries may no compute the correct checksum for your protocol. Get the checksum wrong and you will not get any response at all.

as far as I read your pictures, your module doesn't use modbus. Or do you find any description in your documents saying Modbus RTU?

I do not see Modbus anywhere no. :confused:

The attached shows basicly all i can find in the 100 odd pages that actually seem useful. :slight_smile:






I would forget Modbus. As @noiasca says, your message format isn't Modbus.

You could try sending one of the pre worked messages from the docs to see if you get a response using a software serial library and controlling the MAX485.

Here's an untested bit of code that might work for you:

// Uses PJRC AltSoftSerial library which is better than the standard SoftwareSerial library (IMHO)
// Get it here: https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
//
// All pin numbers are for an Arduino UNO.

#include <AltSoftSerial.h>

// MAX485 : RO to pin 8 & DI to pin 9 when using AltSoftSerial
#define RE 6
#define DE 7

const byte msg1[] = {0x27, 0x0F, 0x20, 0x01,
                     0x02, 0x04, 0x02, 0x10, 0x1A, 0x1B, 0x04, 0x02, 0x04, 0x05, 0x03, 0x81, 0x06,
                     0x80, 0x2A };

byte values[11];
AltSoftSerial swSerial;

void setup() {
  Serial.begin(115200);

  // set this to the required baud rate - max of 19200 baud
  swSerial.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  // put RS-485 into receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay( 1000 );
}

void loop() {
  uint32_t startTime;
  uint8_t  rxByte;
  
  Serial.println("Sending command");
  Serial.print("Response: ");
  
  // put the MAX485 into transmit mode
  digitalWrite(RE, HIGH);
  digitalWrite(DE, HIGH);  

  // send the message
  swSerial.write( msg1, sizeof(msg1) );
  // wait for all of the message to be sent
  swSerial.flushOutput();

  // put the MAX485 back into receive mode
  digitalWrite(RE, LOW);
  digitalWrite(DE, LOW);

  startTime = millis();
  // wait for up to 2 seconds for any reply and print out any received bytes
  while ( millis() - startTime < 2000UL ) {
    if ( swSerial.available() ) {
      rxByte = swSerial.read();
      Serial.print( rxByte, HEX );
      Serial.print( " " );
    }
  }
  Serial.println();
  Serial.println();

  // 5 second delay, then repeat the whole process again
  delay( 5000 );   
}

It uses a software serial port (AltSoftSerial library) to talk via the MAX485. It should send the canned message that's in your reply #4, and then wait for 2 seconds printing out any bytes that are received.

The software serial port can go up to 31250 baud according to the docs.

Maybe I missed it, but I couldn't see a baud rate in the images you posted.

There's a very good chance that you will get no response, as your valve probably has a different address to the one used in the canned message.

If you have to change any of the message, then the CRC will be wrong. Section 3.7 of your doc gives some clues that I used to create the same CRC using an online CRC generator.

Below is a screenshot of the web page with the settings I used to generate the checksum of 0x802A using the canned message. Note the Start Delimiter isn't included - as per the docs.

Hi there.

Thank you soo very much thus far in assisting me to get this working. It is really appreciated.

Soooo... firstly i replaced the arduino and the max485 and now i am actually getting voltages etc. on the A/B outputs. I noticed that the arduino was getting warm which i thought was odd.
The company who gave asked me to do this project for them preconfigured a veroboard with circuitry and i am presuming something went wrong with the soldering which fried something. :frowning:
I have since gone through the board and made sure that all is in tact as should be.
I thought something was wrong the other day but I carried on nonetheless thinking it was something in my code etc.

So I have now got a new arduino nano connected to the max485.

I have updated @markd833 code that you kindly sent me to incorporate the nano pinout (which i think is correct).

I am still getting CRC errors when it transmits the array's in the code despite checking them correctly against the site you shared with me. :confused:

In the spec sheets i see that for baud 9600 there is :
an inter-byte delay of <=1.2ms
inter telegram delay of >=3ms
inter telegram delay after data message >=50ms
Reply delay [3ms-50ms]

#include <Arduino.h>

// Uses PJRC AltSoftSerial library which is better than the standard SoftwareSerial library (IMHO)
// Get it here: https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
//
// All pin numbers are for an Arduino UNO.

#include <AltSoftSerial.h>

// MAX485 : RO to pin 8 & DI to pin 9 when using AltSoftSerial
#define RE 11
#define DE 12

// const byte msg1[] = {0x27, 0x0F, 0x20, 0x01,
//                      0x02, 0x04, 0x02, 0x10, 0x1A, 0x1B, 0x04, 0x02, 0x04, 0x05, 0x03, 0x81, 0x06,
//                      0x80, 0x2A, 0xAA };

// const byte msg1[] = {0x27, 0x0E, 0xFE, 0x01,
//                      0x00, 0x02, 0x02, 0x03, 0x04, 0x02, 0x2E, 0x2F, 0x02, 0x02, 0x94, 0x95,
//                      0x2A, 0xAA };

// const byte msg1[] = {0x27, 0x0E, 0xFE, 0x01,
//                      0x00, 0x02, 0x02, 0x03, 0x04, 0x02, 0x2E, 0x2F, 0x02, 0x02, 0x94, 0x95,
//                      0x2A};

// const byte msg1[] = {0x27, 0x0F,0x20,0x04,0x02,0x10,0x1A,0x1B,0x4,0x02,0x05,0x03,0x81,0x06,0x80,0x2A};

// const byte msg1[] = {0x27,0x0E, 0xFE, 
//                     0x01, 0x00, 0x02, 0x02, 0x03, 0x04, 0x02, 0x2E, 0x2F, 0x02 ,0x02, 0x94, 
//                     0x95, 0xA2, 0xAA};

const byte msg1[] = {0x27,0x0E, 0xFE, 
                    0x02, 0x95,
                    0x8A, 0x57};

// const byte msg1[] = {0x27, 0x0F, 0x20, 0x01,
//                      0x02, 0x04, 0x02, 0x10, 0x1A, 0x1B, 0x04, 0x02, 0x04, 0x05, 0x03, 0x81, 0x06,
//                      0x80, 0x2A };


byte values[11];
AltSoftSerial swSerial;

void setup() {
  Serial.begin(9600);

  // set this to the required baud rate - max of 19200 baud
  swSerial.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  // put RS-485 into receive mode
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);

  delay( 1000 );
}

void loop() {
  uint32_t startTime;
  uint8_t  rxByte;
  
  Serial.println("Sending command");
  Serial.print("Response: ");
  
  // put the MAX485 into transmit mode
  digitalWrite(RE, HIGH);
  digitalWrite(DE, HIGH);  

  // send the message
  swSerial.write( msg1, sizeof(msg1) );
  // wait for all of the message to be sent
  swSerial.flushOutput();

  // put the MAX485 back into receive mode
  digitalWrite(RE, LOW);
  digitalWrite(DE, LOW);

  startTime = millis();
  // wait for up to 2 seconds for any reply and print out any received bytes
  while ( millis() - startTime < 2000UL ) {
    if ( swSerial.available() ) {
      rxByte = swSerial.read();
      Serial.print( rxByte, HEX );
      Serial.print( " " );
    }
  }
  Serial.println();
  Serial.println();

  // 5 second delay, then repeat the whole process again
  // delay( 5000 );   
}

Looking at the first photo in your post #1 (and photo 4 in post #10), the 0x0E value in the above message is the length field. If you send the message in the current code, then the length field value is not correct.

The delays in the spec shouldn't be a problem. I would have thought that the inter-byte delay would be less than 1.2ms, even with a software serial port implementation. There's a 2 second wait for a response which is much longer than the inter telegram delay.

Probably of little use to you but I think that there is an error in the example message in the photo in post #1. The connection request message says that the destination address ix 0xFE, but the connection reply message says it's coming from address 0x20. I would say that photo 1 in reply #4 is correct as far as addresses go.

As there is just you and this 1 device on your RS485 bus, then I guess that the source address (i.e. the Nano) can be any address other than the address of the other device. Do you know what the address is of the other device?

What is telling you that there are CRC erros?

apologies.
i copied the code to the forum before editing :man_facepalming:

the current code i tried with just that class reference was

const byte msg1[] = {0x27,0x03, 0xFE, 
                    0x02, 0x95,
                    0xAD, 0xCE};

Ok, so what is telling you that there are CRC errors?

ok soooooo.

i managed to get the grundfos pc link rs485 adapter and after a tedious process managed to get the grundfos software (which does absolutely nothing except monitor voltage and flow etc. and upgrade firmware) - sadly.

but what i have managed to do is log the serial with serial monitor.
i have been trying to send the hex values that i have captured and i get a result.... although.... it is all garbled stuff which i cannot understand.
i have changed baud rate and it makes no difference.

does the attached perhaps have any info which makes sense to you? :man_facepalming:
Thank you again for all the assistance thus far!!! :smiley:

https://easyupload.io/m/lbcuvx

Hi, @qballza
Rather than post info off forum, can you please attach it to the post, preferably NOT a zip, but in a format that we all can read.
Not sure what .spm is.

Thanks... Tom... :smiley: :+1: :coffee: :australia:

ok sure im going to do my best now.
it is serial port monitor session.
there are various windows in the software but i will take screenshots etc.
thank you

0x24 is reply from the controller.
0x27 is connection request / data request

hex order:

start delimeter , length, destination address, source address

[03/12/2021 10:42:50] Read data (COM6) 
    24 41 00 e7 0b 26 00 00 04 74 00 00 00 00 00 00   $A.ç.&...t...... 
    00 00 00 00 00 00 00 3d 00 00 00 00 00 00 00 00   .......=........ 
    00 00 33 02 00 00 01 64 00 00 00 00 02 15 ff ff   ..3....d......ÿÿ 
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
    20 ff ff c4 9d                                     ÿÿĝ            
[03/12/2021 10:42:51] Written data (COM6) 
    27 2e e7 00 0b 13 10 02 0f 0d 0c 0e 14 12 01 13   '.ç............. 
    16 09 07 0a 6c 08 00 15 05 02 15 b4 a5 b3 a7 aa   ....l......´¥³§ª 
    a6 ac a9 b1 a4 ad b0 a3 b2 af ab a8 b6 51 ae b5   ¦¬©±¤­°£²¯«¨¶Q®µ 
    fd c9                                             ýÉ               
[03/12/2021 10:42:51] Read data (COM6) 
    24 41 00 e7 0b 26 00 00 04 74 00 00 00 00 00 00   $A.ç.&...t...... 
    00 00 00 00 00 00 00 3d 00 00 00 00 00 00 00 00   .......=........ 
    00 00 32 f0 00 00 01 64 00 00 00 00 02 15 ff ff   ..2ð...d......ÿÿ 
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
    20 ff ff c3 3a                                     ÿÿÃ:            
[03/12/2021 10:42:51] Written data (COM6) 
    27 2e e7 00 0b 13 10 02 0f 0d 0c 0e 14 12 01 13   '.ç............. 
    16 09 07 0a 6c 08 00 15 05 02 15 b4 a5 b3 a7 aa   ....l......´¥³§ª 
    a6 ac a9 b1 a4 ad b0 a3 b2 af ab a8 b6 51 ae b5   ¦¬©±¤­°£²¯«¨¶Q®µ 
    fd c9                                             ýÉ               
[03/12/2021 10:42:51] Read data (COM6) 
    24 41 00 e7 0b 26 00 00 04 74 00 00 00 00 00 00   $A.ç.&...t...... 
    00 00 00 00 00 00 00 3d 00 00 00 00 00 00 00 00   .......=........ 
    00 00 33 02 00 00 01 34 00 00 00 00 02 15 ff ff   ..3....4......ÿÿ 
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
    20 ff ff 19 b6                                     ÿÿ.¶            
[03/12/2021 10:42:51] Written data (COM6) 
    27 09 e7 00 0e 02 1f 03 10 01 01 ee 30            '.ç........î0    
[03/12/2021 10:42:51] Read data (COM6) 
    24 12 00 e7 0e 08 00 00 01 7a 00 00 01 7b 10 04   $..ç.....z...{.. 
    00 00 01 7a ad 2e                                 ...z­.           
[03/12/2021 10:42:51] Written data (COM6) 
    27 2e e7 00 0b 13 10 02 0f 0d 0c 0e 14 12 01 13   '.ç............. 
    16 09 07 0a 6c 08 00 15 05 02 15 b4 a5 b3 a7 aa   ....l......´¥³§ª 
    a6 ac a9 b1 a4 ad b0 a3 b2 af ab a8 b6 51 ae b5   ¦¬©±¤­°£²¯«¨¶Q®µ 
    fd c9                                             ýÉ               

OK so these two pages might be of more assistance.
i put the lines through the hex (send) as i was trying to ascertain the bytes/packets etc.