Activity › Forums › Questions & Troubleshooting › Controllino MAXI RS485 Modbus
-
Controllino MAXI RS485 Modbus
-
Hi,
the code seems to be correct and it should work.
Please, share the part of the sketch where you set the ModbusSlaveRegisters value.
Thanks,
Lukas
-
Hi,
i’m facing some simular problem. Can you share your code?
-
Hi Everyone
I managed to solve my own issue by just using normal serial communication, like the tutorial example of the DemoRS485, and not using the ModbusRtu.h related modbus code available in the tutorials.
Although I did manage to have the controllino MAXI act as a master and perform the required operations, I do still experience some sort of issue where it seems the device does not handle multiple slave addresses and quick concurrent communication to said devices very well.
I hooked up 3 slave devices to my MAXI master, with slave addresses 1, 3, 4.
A SH20 temperature and Humidity sensor, a Modbus RTU 4CH relay module and a N4DBA06 analogue and digital input /output device. In my loop code I would perform various register read and write operations like reading the humidity, then reading a 4-20mA input, and setting a voltage output, etc.., and like I stated, the device seems to struggle and sometimes not work as expected or not at all. I had to put in multiple delays between code lines and that would seem to sometimes either help or hinder.
<font face=”inherit”>Maybe someone has similar experiences and could share some </font>insight<font face=”inherit”>? Is this perhaps a possible hardware issue, or a software issue?</font>
Any info would be appreciated.
-
my and originally someone else’s code: (Thanks to whomever I don’t recall)
#include <SPI.h>
#include <Controllino.h>
float RH;
//———————————————————————————–
#define MAX_MILLIS_TO_WAIT 300
#define FRAMESIZE 9
//———————————————————————————–
#define ADDRESS 0x01 // BYTE 1
#define FUNCTION_CODE 0x04 // BYTE 2
#define BYTE_03 0x00 // BYTE 3
#define BYTE_04 0x01 // BYTE 4
#define BYTE_05 0x00 // BYTE 5
#define BYTE_06 0x01 // BYTE 6
//———————————————————————————–
void setup() {
Serial.begin(9600);
// initialize the modbus communication
Serial3.begin(9600);
Controllino_RS485Init();
Controllino_RS485RxEnable();
/* This will initialize Controllino RS485 pins */
}
void loop() {
if (runEvery(3000)) {
Serial.println(“===================================”);
uint16_t ws;
soil(&ws);
//for debugging purpose
RH = ws / 10; Serial.println(” Temp: \t” + String(RH));
}
}
/////////////////////////////function: access modbus data/////////////////////
float soil(uint16_t* ws) {
uint16_t temp;
unsigned long resptime;
uint8_t frame[FRAMESIZE] = {ADDRESS, FUNCTION_CODE, BYTE_03, BYTE_04, BYTE_05, BYTE_06, 0, 0, 0};
temp = calculateCRC(frame, FRAMESIZE – 3); // calculate out crc only from first 6 bytes
frame[6] = lowByte(temp);
frame[7] = highByte(temp);
Serial.println(“=========================================================”);
//=====================For debugging purposes======================//
String request = “Request: “;
for (int n = 0; n < FRAMESIZE – 1; n++) {
request += frame[n] < 0x10 ? ” 0″ : ” “;
request += String(frame[n], HEX);
request.toUpperCase();
}
Serial.println(request);
//=========================================================//
Controllino_RS485TxEnable();
Serial3.write(frame, FRAMESIZE – 1); // send 8 bytes
Serial3.flush(); // wait until the trasmission is complete
//delay(1000);
uint8_t DoPON[8] = {0x02, 0x06, 0x00, 0x83, 0x00, 0x01, 0xB9, 0x0D1};
Serial3.write(DoPON, 8);
Serial3.flush();
Controllino_RS485RxEnable();
resptime = millis();
while ((Serial3.available() < FRAMESIZE) && ((millis() – resptime) < MAX_MILLIS_TO_WAIT) ) {
delay(50);
}
String Response = “Response: “;
if (Serial3.available()) {
for (int n = 0; n < FRAMESIZE – 2; n++) {
frame[n] = Serial3.read();
//debugging//
Response += frame[n] < 0x10 ? ” 0″ : ” “;
Response += String(frame[n], HEX);
Response.toUpperCase();
}
Serial.println(Response);
*ws = ((uint16_t)frame[3] << 8) | frame[4];
}
}
/////////////////////////////function: access modbus data/////////////////////
uint16_t calculateCRC(uint8_t *array, uint8_t num) {
uint16_t temp, flag;
temp = 0xFFFF;
for (uint8_t i = 0; i < num; i++) {
temp = temp ^ array[i];
for (uint8_t j = 8; j; j–) {
flag = temp & 0x0001;
temp >>= 1;
if (flag)
temp ^= 0xA001;
}
}
return temp;
}
//————————————————-//
boolean runEvery(unsigned long interval)
{
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if ((currentMillis – previousMillis) >= interval)
{
previousMillis = currentMillis;
return true;
}
return false;
}
-
Hi Kwaaigone,
I think that your sketch may stuck when the reply from the Modbus slave is shorter than 7 bytes. It will stay in the blocking function Serial3.read.
And what can be the reason? Maybe you switch the RS485 direction too fast. The flush function may end when the last byte is loaded into the trasmit buffer, but not transmitted yet. As described here.
And your runEvery function may have a problem with millis overflow.
Good luck!
Lukas
-
Log in to reply.