cancel
Showing results for 
Search instead for 
Did you mean: 

RS485 Sensor

Mithunkumar
Associate II

Hi, I am trying to connect one energy meter sensor which has RS485 output , But i am unable to read RS485 sensor readings in Nucleo F401RE, If you have any examples please help out!!

4 REPLIES 4

Perhaps have the meter vendor explain how it works to you or suggest contractors you might work with.

RS485 is a signaling interface. It doesn't define how particular hardware is queried or used in the broader sense.

Does the meter have a manual or datasheet you can refer too?

Do you have the RS485 level/interface circuit wired to a UART? Does that work at some basic level?

Do you work with anyone who knows what they are doing or have experience with this equipment?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks for your valuable time Delorean!!

Actually I had used ESP32 for RS485 Sensors, now I try to connect same RS485 Sensors in STM32 but I am not able to connect, I have tried with the same interface circuit which I used in ESP32, but I am not able to read.

 

Ok, so present this in a form that shows the code that works and the code that doesn't and diagram what exactly you have wired up to the STM32

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

here is the code that I have used in ESP32, and it works fine, but i am not able to run in STM32

Main.ino 

#include "RS485.h"
#include <ModbusMaster.h>

int ESP_DE = 13;

RS485 mySensor(4, 15, 2);

void setup() {
Serial.begin(115200);
delay(1000);
while (!Serial) {}
mySensor.begin();
}

void loop() {
mySensor.Rs485readings();
}

RS485.cpp

#include "RS485.h"

Derived node;

DynamicJsonDocument doc(MAXFILESIZE * 1024);


RS485::RS485(int txPin, int rxPin, int devId) {
ESP_DI_TX = txPin;
ESP_RO_RX = rxPin;
DEVID = devId;
}
void RS485::pre(){}
void RS485::post(){}

void RS485::Jsonarray() {
const char* jsonarray = R"([
{
"DN": "EM",
"DA": 2,
"AR": [
{"rd": 2, "rt": 2, "dt": 2 },
{"rd": 4, "rt": 2, "dt": 2},
{"rd": 6, "rt": 2, "dt": 2}
]
}
])";
DeserializationError error = deserializeJson(doc, jsonarray);
serializeJsonPretty(doc, Serial);
}

void RS485::begin() {
pinMode(ESP_DI_TX, OUTPUT);
pinMode(ESP_RO_RX, OUTPUT);
pinMode(ESP_DE, OUTPUT);
Serial1.begin(9600, SERIAL_8N1, ESP_RO_RX, ESP_DI_TX);
digitalWrite(ESP_DE, 0);
node.begin(DEVID, Serial1);
node.preTransmission(pre);
node.postTransmission(post);


RS485::Jsonarray();
}

void RS485::Rs485readings() {

uint8_t noOfRegs = 0, temp;
uint8_t i, j, y = 0;
int v = 1;
uint8_t DATA[MAX][3];

JsonArray jsonarray = doc.as<JsonArray>();
//serializeJson(jsonarray, Serial);

//Converting JSON to 2D array
for (JsonObject data : jsonarray) {
int dev_id = data["DA"]; //Device Address
JsonArray addRegArray = data["AR"]; //AR = Add Register
for (const JsonVariant& addReg : addRegArray) {
int reg_id = addReg["rd"]; //rd = register ID
int reg_type = addReg["rt"]; //rt = register type
int data_type = addReg["dt"]; //dt = data type
if (DEVID == dev_id) {
DATA[noOfRegs][1] = reg_type;
DATA[noOfRegs][2] = data_type;
DATA[noOfRegs][0] = reg_id;
noOfRegs++;
}
}
}

//Bubble sort - To arrange the data in Ascending order as per reg_id
for (i = 0; i < noOfRegs; i++) {
for (j = i + 1; j < noOfRegs; j++) {
if ( DATA[i][0] > DATA[j][0]) {
for (int x = 0; x < 3; x++) {
temp = DATA[i][x];
DATA[i][x] = DATA[j][x];
DATA[j][x] = temp;
}
}
}
}
// for (i = 0; i < noOfRegs; i++) {
// for (j = 0; j < 3; j++) {
// Serial.printf("[%d][%d]:%d\n", i, j, DATA[i][j]);
// }
// }

Serial.printf("NoOfRegs: %d\n", noOfRegs);
//To identify range based on total number of input registers
uint8_t range = DATA[noOfRegs - 1][0];
if (DATA[noOfRegs - 1][2] == 2 || DATA[noOfRegs - 1][2] == 3)
range++;
Serial.printf("Range: %d\n", range);

//Readings
result = node.readInputRegisters(DATA[0][0], range, read_delay);
Serial.printf("Result : %d\n", result);

for (i = 0; i < noOfRegs; i++) {
if (DATA[i][2] == 1) {
if (result == node.ku8MBSuccess) {
reading = node.getResponseBuffer(y);
Serial.printf(": %d\r\n", reading);
} else {
Serial.println("RS485 Read Error");
}
}
else if (DATA[i][2] == 2 || DATA[i][2] == 3) {
if (result == node.ku8MBSuccess) {
uint16_t x[4];
union {
uint32_t i;
float f;
} data;
char hexString[9] = {0};

x[3] = node.getResponseBuffer(y) & 0xff;
x[2] = node.getResponseBuffer(y) >> 8;
x[1] = node.getResponseBuffer(y + 1) & 0xff;
x[0] = node.getResponseBuffer(y + 1) >> 8;

sprintf(hexString, "%02X%02X%02X%02X", x[0], x[1], x[2], x[3]);
data.i = strtoul(hexString, NULL, 16);
if (DATA[i][2] == 2) {
reading = data.f;
Serial.printf("V%d:%.2f\r\n", v, reading);
}
else if (DATA[i][2] == 3) {
reading = data.i;
Serial.printf("% li\r\n", reading); ;

}
else {
Serial.println("RS485 Read Error");
}
}
}
Serial.println("");
vTaskDelay(pdMS_TO_TICKS(1000));
if (result == node.ku8MBSuccess) {
v++;
if (DATA[i][2] == 1)
y++;
else
y = y + 2;
}
}
}
RS485.h

#ifndef RS485_H
#define RS485_H

#include <Arduino.h>
#include <Derived.h>
#include <SoftwareSerial.h>
#include <ArduinoJson.h>

#define MAXFILESIZE 8
#define MAX 20


class RS485 {
private:
uint8_t result;
uint8_t dev_id;
uint8_t reg_id;
uint8_t reg_type;
uint8_t data_type;
float reading;
int read_delay = 5000;
int ESP_DI_TX;
int ESP_RO_RX;
int DEVID;

public:
RS485(int, int, int);
static void pre();
static void post();
void begin();
void Jsonarray();
void Rs485readings();
};


#endif