Forum Controllers/PLC

Welcome!

This community is for professionals and enthusiasts of our products and services. Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together.

0

Reading a Modbus PT100 temperature probe

Avatar
Hilton Izzett

Hi Guys

I'm quite afaid to enter this forum having no experience with programming at all so don't shoot yet 😎. All I want to do is read temperatures from a PT100 transmitter which say it used Modbus protocol (and it does, verified by someone else who has used it). The data sheet says:

Read Temp value, send command (example) 64 03 00 01 00 01 DC 3F (Device ID, function code, Register high bit, reg low bit, read number high bit, read number low bit, CRC_H, CRC_L).

Respnse will be: 64 03 02 01 0C 5F D9 (Device ID, function code, data byte numbers, Temp data high bit, Temp data low bit, CRC_H, CRC_L)

I wired the transmitter to A+ B-

After reading multitudes of examples from different libraries to try to understand a tiny bit, or byte, I used the code below.

There was no communication with the transmitter. It has a light that flashes and there was no light, and of course no data came through. I don't know what I don't know, so I'm looking for the error I have made if anyone can help I'd be most grateful.



#include ModbusRTUMaster



#if defined HAVE_RS485_HARD

#include

ModbusRTUMaster master(RS485); 

#elif defined HAVE_RS232_HARD

#include

ModbusRTUMaster master(RS232); 

#else

ModbusRTUMaster master(Serial1);

#endif


#define REGISTERS_TO_READ 2

const uint32_t baudrate = 9600;

uint32_t SlaveID = 0x64;

const uint16_t Address = 40002;

uint32_t lastSentTime = 0UL;


void setup() {


​Serial.begin(9600); // Start the serial port


​#if defined HAVE_RS485_HARD

​RS485.begin(baudrate, HALFDUPLEX, SERIAL_8N1);

​#elif defined HAVE_RS232_HARD

​RS232.begin(baudrate, SERIAL_8N1);

​#else

​Serial1.begin(baudrate, SERIAL_8N1);

​#endif 


​master.begin(baudrate);

​Serial.println();

​Serial.println("Checking start....");


}


void loop() {

​Serial.println();

​Serial.println("Checking Loop....");

​// Send a request every 1000ms

​if (millis() - lastSentTime > 925) {


​// Read REGISTERS_TO_READ holding registers, starting at address 0.

​// IMPORTANT: all read and write functions start a Modbus transmission, but they are not

​// blocking, so you can continue the program while the Modbus functions work. To check for

​// available responses, call master.available() function often.


​if (!master.readHoldingRegisters(SlaveID, 0, REGISTERS_TO_READ)) {

​// Failure treatment

}


​Serial.print("Last time sent = ");

​Serial.print(lastSentTime);

​Serial.println();


​lastSentTime = millis();


​// Check available responses often


​if (master.isWaitingResponse()) {

​ModbusResponse response = master.available();


​Serial.print("Holding Register values: ");

​for (int i = 0; i

​Serial.print(response.getRegister(i));

​Serial.print(';');



​if (response) {

​if (response.hasError()) {

​// Response failure treatment. You can use response.getErrorCode()

​// to get the error code.


​Serial.print("Error code is ");

​Serial.println(response.getErrorCode());

​} else {

​// Get the discrete inputs values from the response

​Serial.println();

}

}

}

}

delay(475);

}



1 Comment
Avatar
Discard
Avatar
Hilton Izzett
-
I'm sorry but I don't understand this email.

From: Ricard Franch Argullol <[email protected]>
Sent: Friday, July 21, 2023 7:46:57 PM
To: Hilton <[email protected]>
Subject: Reading a Modbus PT100 temperature probe
 
Una nueva pregunta Reading a Modbus PT100 temperature probe de Forum Controladores/PLC se ha publicado. Haga clic aquí para acceder a la pregunta: Ver pregunta ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​ ͏ ​

Una nueva pregunta Reading a Modbus PT100 temperature probe de Forum Controladores/PLC se ha publicado. Haga clic aquí para acceder a la pregunta:

Ver pregunta

Best Regards / Atentamente

Ricard Franch Technical Specialist

E: [email protected] T: (+34) 938 76 01 91  WhatsApp: (+34) 644 92 79 00 

Industrial Shields by Boot & Work Corp, S.L. |  Camí del Grau, 25 | Sant Fruitós de Bages 08272 Barcelona


Boot & Work Corp. S.L.

+34 938 76 01 91 | [email protected] | https://www.industrialshields.com

Con tecnología de Odoo

2 Answers
0
Avatar
Hilton Izzett
Best Answer

Thank you Ricard, you identified the critical flaw; it seems the real problem I had was not powering the M-Duino 21 + LoRa with 24VDC.  I was reading all sorts of blogs and watching videos and it seemed that the PLC could just be plugged into the USB, but thinking about it now, the PLC needs to send a message and needs + and GND to do it.

I learnt a couple more things: if I write readHoldingRegisters(100, 1, 1) it doesn't work.  If I write readHoldingRegisters(0x64, 0x01, 1) it works.  If i make uint16_t slaveID = 100 and uint16_t address = 1 and then write readHoldingRegisters(slaveID, address, 1) it works.

I assume that is all about how the number are stored and in what format. 

I used the code below but I will make a comment about it now: if I write for (uint16_t i = 0; i



```cpp

#include

#include


ModbusRTUMaster master(RS485);

const uint32_t baudrate = 9600;

const uint16_t numTransmitters = 3; // Number of transmitters to read from

uint16_t slaveIDs[numTransmitters] = {2, 3, 100}; // Array of slave addresses, has to be uint16_t

uint16_t offset = 0; /// This does not have to be uint16_t

uint16_t address = 1; /// This has to be uint16_t

uint16_t numReg = 1; /// This does not have to be uint16_t


void setup() {

Serial.begin(9600);

Serial.println("Getting started....");

RS485.begin(baudrate, HALFDUPLEX, SERIAL_8N1);

master.begin(baudrate);

}


void loop() {

for (uint16_t i = 0; i

//// if I use i

//// slaveID 100 reading is given to slaveID 2

uint16_t slaveID = slaveIDs[i];

master.readHoldingRegisters(slaveID, address, numReg);

/// if entering these numbers manually the first 2 must be entered as HEX eg. (0x64, 0x01, 1) else it does not work

ModbusResponse response = master.available();


if (response) {

if (response.hasError()) {

Serial.print("Error code = ");

Serial.println(response.getErrorCode());

} else {

Serial.print("Slave ID ");

Serial.print(slaveID);

Serial.print(" ");

uint16_t rawTemp = response.getRegister(offset);

float realTemp = rawTemp / 10.0;

Serial.print("Temp = ");

Serial.println(realTemp, 1);

}

}


delay(100);

}

}


```



Avatar
Discard
0
Best Answer

Hello Hilton,


First of all, don't worry about the validation email, it is just to inform you that your post has been published on the forum (since it has to be validated by a moderator).


Regarding the Modbus usage, please make sure the PLC is properly powered (using a 12-24V power supply, not the USB). If you are using RS485, check the switches: in case you are using an M-Duino PC, you'll need to select between FD and HD (full duplex and half duplex). If you only wired A- and B+, I am guessing you use half duplex.


As for the code you provided, it has some errors and does not compile. Check out this post about the Modbus RTU library and this other post about how to read a holding register. Double check configuration settings as the baudrate, save ID, etc.


P. S. It is always useful to provide more info, specially regarding your hardware: PLC Model, specific transmitter model (maybe a datasheet?), etc.

Avatar
Discard