RS485 communication with Siemens PAC3100

Hello everyone, first time using these forums. :smiley:

Context

I'm currently working on my last year's high school project which basically consists of communicating a Siemens PAC3100 Power Meter to an Arduino Board and then use it to transmit the (measured) information via WIFI or some sort of local IP (..to an html based site) where one could see said information (in real time or with some minor delay, 1 second for example) by launching the browser and typing the IP either in a computer or cellphone (this "second part" i haven't really reseached yet, but i'll cross that bridge when i get to it, i first need to stablish communication :stuck_out_tongue: ).

For the "first part" of the project im using an Arduino UNO board connected to a MAX485 RS485 to ttl converter (which then conects to the RS485 Power Meter's connector). In the software side of things i'm using the ModbusMaster library v2.0.1 by Doxygen.

I'm pretty new to using this (RS 485) communications protocol so i've been searching though a couple of videos and came across a guy using this library and get it working successfully. I tried following his example along with some reading of the library's reference guide, namely the RS485_Half Duplex example (Page 47 of the guide)

Part 1 of the video

Part 2 of the video

I know that the guy is using an Arduino Nano, but since it's more or less similar to the UNO i thought that (software side) it wouldn't matter much.

Hardware connections
Board is powered by USB connection from PC, at the end i'm gonna use a 5v normal connection

  • -/A from PM connected to A from MAX converter
  • +/B from PM connected to B from MAX converter
  • Vcc from MAX converter connected to 5V from board
  • Gnd from MAX converter connected to Gnd from board and to common groud from PM
  • RO from MAX converter connected to pin 1 (TX) from board
  • RE from MAX converter connected to pin 2 from board
  • DE from MAX converter connected to pin 3 from board
  • RO from MAX converter connected to pin 0 (RX) from board, there is also a 10kohm pull up resistor connected to 5V from board

Starting Code

#include <ModbusMaster.h>

ModbusMaster PAC1;

//Enable pins of the Adapter
#define MAX485_DE 3
#define MAX485_RE 2

void preTransmission()
{
  digitalWrite(MAX485_DE, 1);
  digitalWrite(MAX485_RE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_DE, 0);
  digitalWrite(MAX485_RE, 0);
}

void setup()
{
  pinMode(MAX485_RE, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);

  //Initiate Reception
  digitalWrite(MAX485_DE, 0);
  digitalWrite(MAX485_RE, 0);
  
  Serial.begin(9600);

  //PAC slave ID is 126
  PAC1.begin(126, Serial);

  PAC1.preTransmission(preTransmission);
  PAC1.postTransmission(postTransmission);
}
void loop()
{
 uint8_t Data;

 Data = PAC1.readInputRegisters(0x03,3);//Fuction Utilization? and number of registers to be read
 if (Data == PAC1.ku8MBSuccess)
 {
  Serial.println("===============");
  Serial.print("Voltage a-n:");
  Serial.println(PAC1.getResponseBuffer(0x02));//Specified register to print/use?
 }
 delay (1000);
}

Right now i'm just trying to get communication with the PM (read in the serial monitor the ~127V from Va-N that i'm measuring) so i can then work from there with the other voltages and currents. For the final product i would like to be able to read Va- n, Vb-n , Vc-n, Current a, b, and c.

Problem
The problem i'm experiencing right now is that i just can't seem to be able to communicate with the PM. From the PAC3100 Manual (Page 127) i understand that i need to use the 03 function and (from page 129 and 130) that i need to use the offsets 1, 3, 5, 13, 15 and 17 and their respective 2 floating registers.

I'm pretty sure that the problem is with the void loop part:

void loop()
{
 uint8_t Data;

 Data = PAC1.readInputRegisters(0x03,3);//Fuction Utilization? and number of registers to be read
 if (Data == PAC1.ku8MBSuccess)
 {
  Serial.println("===============");
  Serial.print("Voltage a-n:");
  Serial.println(PAC1.getResponseBuffer(0x02));//Specified register to print/use?
 }
 delay (1000);
}

I'm not very clear in which "format" i need to input the function and the offsets with their registers because in the library example and in the video an address is being included (0x3100) in the part where i thought that the function would go and in the PM's manual nothing is being mentioned, i'm pretty sure i just need to "put together" this address but i can't seem to be able to do it in the correct way beacuse i just keep getting gibberish in the Serial Console:

‚łģ‚łģ~// and stuff similar when i try to put a different order, accomodate it differently, add zeroes, etc...

Another thing, because (i infer) the information is divided into 2 registers i need to combine the High word with the low word in order to get readable information, i tried to understand the explanation of combining these with the explanation of the library and the use in the example, i have an idea of doing it, but i can't doint because i can't communicate with the PM in the first place

Summary
I would like if someone could please explain me or point me in the right direction of how to put together the exact format of the function and registers in the library so i can communicate properly with the PM and get the readings in the Serial Monitor.

Also a little bit of the clarification of the low word and high word stuff would be very appreciated

Clarifications/ Further questions

  • I found another library which is SimpleModbus Master but for that i need to use 2 serial ports (which the UNO doesn't have, i tried investigating using altsoft serial and software serial, but upon searching i've come up with the conclusion that they're not suitable for this tipe of thing). I mean to buy a MEGA board if it comes up to it, but i want to see if it's possible with the UNO and the Modbus Master library. That's why for the moment i'm using the Half duplex connection so i can also use the Serial Monitor. Also, i'm sure that the problem with the communication would be the same as in here. Or would i be recommended to switch to this other set of library/board?
  • It's crossed my mind that it could be a problem in hardware but i'm not sure it is. Page 50 of the manual states that i need to use some certain resistors as terminators and pull up-pull down for the RS485 connection but the PM is like 15-20 cm from the adapter. Do i still need to include them?
  • In one of the forum posts about a problem involving RS485 and the MAX485 adapter i read that i need to use the 10k ohm pull up resistor to Vcc from the DI pin. Is this correct?
  • i can't find specified on the library's guide as to which word format i should use. The PAC supports 8N2, 8E1, 8O1 and 8N1, which one i should use? In the Simple Modbus library i can, but in the ModbusMaster i can't seem to find a way..
  • About the low word/high word thing.. I suppose that i need to convert the measured information in "normal" varibles (int, byte, char, etc..) becasue i would then use these to transmit it via WIFI. Is this correct? The PAC's Manual states that these variables are (in the low word/high word thing) in float format. Would this affect my plans?
  • The one second delay is to not ask for the measurements "too" fast, it's not necesary for it to be real time, though if it is necesary, i can add more delay or remove it.
  • I apologize in advance if these are too many questions.. I''m also more or less new with the whole Arduino enviroment (just started with it on this semester). :sweat_smile:

Links
(Videos already linked)

Modbus Master Library

Siemens PAC3100 Manual

(Modbus library reference guide in attachments)

(Attached are some photos of the "setup" i have) Beware, they're in early stages of cabling :stuck_out_tongue:

ModbusMaster reference-2.0.1.pdf (202 KB)

Doxygen is a automated documentation generation tool and not the author of the library. That's another reason why we like to see links to the libraries used.

I'm pretty new to using this (RS 485) communications protocol

RS-485 is the physical interface definition, not the protocol. In your case Modbus seems to be the protocol spoken on the line.

RO from MAX converter connected to pin 1 (TX) from board

I hope that should read DI and not RO.

  //PAC slave ID is 126
  PAC1.begin(126, Serial);

...

  Serial.println("===============");
  Serial.print("Voltage a-n:");
  Serial.println(PAC1.getResponseBuffer(0x02));//Specified register to print/use?
 }

You're using the serial interface twice so the two usages must interfere. If you communicate with the power meter by the hardware serial interface you must not use it for debugging. Even though the RS-485 driver is disabled you don't have a distinction between the two traffic sources.

 Data = PAC1.readInputRegisters(0x03,3);//Fuction Utilization? and number of registers to be read

May I ask for an explanation why you set the register address to 0x03 if you try to access register 0x3100?

I'm not very clear in which "format" i need to input the function and the offsets with their registers because in the library example and in the video an address is being included (0x3100) in the part where i thought that the function would go and in the PM's manual nothing is being mentioned,

The function is chosen by the method name (readInputRegisters is function 4).

I found another library which is SimpleModbus Master but for that i need to use 2 serial ports (which the UNO doesn't have, i tried investigating using altsoft serial and software serial, but upon searching i've come up with the conclusion that they're not suitable for this tipe of thing). I mean to buy a MEGA board if it comes up to it, but i want to see if it's possible with the UNO and the Modbus Master library. That's why for the moment i'm using the Half duplex connection so i can also use the Serial Monitor. Also, i'm sure that the problem with the communication would be the same as in here. Or would i be recommended to switch to this other set of library/board?

I'd suggest to buy a board with a separate hardware serial. A Mega2560 has 4 of them but a Leonardo would fit too as it doesn't use the hardware serial interface for the USB communication.

It's crossed my mind that it could be a problem in hardware but i'm not sure it is. Page 50 of the manual states that i need to use some certain resistors as terminators and pull up-pull down for the RS485 connection but the PM is like 15-20 cm from the adapter. Do i still need to include them?

Yes. The bus must be terminated at both ends to mostly eliminate reflections and the biasing resistors are needed to have a defined state on the bus if no driver is active. Depending on the RS-485 module you're using (I miss the link to it!) this is already the case. The module on the pictures seem to have them on-board.

In one of the forum posts about a problem involving RS485 and the MAX485 adapter i read that i need to use the 10k ohm pull up resistor to Vcc from the DI pin. Is this correct?

No, you need one for the RO pin. This is to avoid a floating pin during transfers.

i can't find specified on the library's guide as to which word format i should use. The PAC supports 8N2, 8E1, 8O1 and 8N1, which one i should use?

I prefer the 8E1 as you get additional reliability by the parity bit.

In the Simple Modbus library i can, but in the ModbusMaster i can't seem to find a way..

In ModbusMaster the main sketch is responsible to initialize the serial (Stream) object provided, so specify the correct option in the Serial.begin() method.

pylon:
I hope that should read DI and not RO.

pylon:
No, you need one for the RO pin. This is to avoid a floating pin during transfers.

From what you say i might've screwed up the cabling, just swapped them.

pylon:
Yes. The bus must be terminated at both ends to mostly eliminate reflections and the biasing resistors are needed to have a defined state on the bus if no driver is active. Depending on the RS-485 module you're using (I miss the link to it!) this is already the case. The module on the pictures seem to have them on-board.

From some searching i couldn't find a datasheet for the module (i did for the IC though) but on this site and in another one aswell i found the schematic of the converter (attached below). It appears that it already has the 10k resistors on it, from the RE, RO, DI, and DE outputs, a 120 ohm termination resistor on the RS485 side of things aswell as 20kohm polarization resistors. So i suppose i don't have to add anything or should i add atleast the 10kohm from RO to Vcc anyways?

pylon:
I'd suggest to buy a board with a separate hardware serial. A Mega2560 has 4 of them but a Leonardo would fit too as it doesn't use the hardware serial interface for the USB communication.

Already did, it should arrive either tomorrow or the day after. Once it does i'll try to work with the ModbusMaster library and the SimpleModbus aswell, see how i fare :sweat_smile: . Meanwhile i'll keep trying with the UNO because how could the guy in the videos stablish connection if it was a nano?

pylon:
May I ask for an explanation why you set the register address to 0x03 if you try to access register 0x3100?

The 0x3100 i mentioned (sorry, i didn't explain myself enough) was the addres used by the guy in the video and in the library's example aswell. That's where i'm getting stumped: The PAC's manual doesn't say anything about 0x3100 so that can't be my adress to call, i must be needing something else. I first though that it was where i should put the function to call...

pylon:
The function is chosen by the method name (readInputRegisters is function 4).

... And you tell me the fuction i actually need is 4 (0x04 from what i can see in the PM's Manual [pag. 129]) So i suppose i should put that 0x04 in that part? Or should i add something else to that funtion call?

Data = PAC1.readInputRegisters(0x04,2);//Like this? Reading as well the first two registers so i can get the Va-n data in low and high word.

.

One last thing (it involves my main problem). Upon some research of the Siemens forums i found a couple of small threads where the adress to be called is 40001, could it be the one i need? I'll try with it and keep searching in those forums while the MEGA arrives.

Siemens forum thread 1

Siemens forum thread 2

Siemens forum thread 3

Siemens forum thread 4

485.pdf (84 KB)

MAX1487-MAX491.pdf (1.3 MB)

1 Like

So i suppose i don't have to add anything or should i add atleast the 10kohm from RO to Vcc anyways?

No, if you use that pretty standard cheap Chinese module you have everything you need for a point-to-point connection (it's a bad module for a bus system).

The 0x3100 i mentioned (sorry, i didn't explain myself enough) was the addres used by the guy in the video and in the library's example aswell. That's where i'm getting stumped: The PAC's manual doesn't say anything about 0x3100 so that can't be my adress to call, i must be needing something else. I first though that it was where i should put the function to call...

The relevant addresses are in appendix A.2 of the manual. Siemens seems to call the register addresses "Offset".

So i suppose i should put that 0x04 in that part? Or should i add something else to that funtion call?

No, as I wrote, you don't have to specify the function code but use the corresponding method. So for the registers in appendix A.2.5 you can use readInputRegisters() method.

Data = PAC1.readInputRegisters(0x04,2);//Like this? Reading as well the first two registers so i can get the Va-n data in low and high word.

This will read a part of register "Voltage b-n" and a part of register "Voltage c-n", so that doesn't make sense.

One last thing (it involves my main problem). Upon some research of the Siemens forums i found a couple of small threads where the adress to be called is 40001, could it be the one i need? I'll try with it and keep searching in those forums while the MEGA arrives.

It might be that Siemens uses the standard address ranges (although I couldn't find a reference in the manual) so that "Offset 1" of function 0x04 mean register address 40001. It would match my experience of Siemens devices to have lengthy manuals which are missing the relevant information though (one reason I try to avoid to buy anything from Siemens).