2024-05-07 12:12 AM
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!!
2024-05-07 01:00 AM
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?
2024-05-07 01:13 AM
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.
2024-05-07 01:27 AM
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
2024-05-07 02:07 AM
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