#include <Arduino.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "sdkconfig.h"
#define TAG "RS485_ECHO_APP"
#define ECHO_TEST_TXD 17
#define ECHO_TEST_RXD 16
#define ECHO_TEST_RE 2
#define ECHO_TEST_DE 4
#define BUF_SIZE 127
#define PACKET_READ_TICS (100 / portTICK_PERIOD_MS)
#define ECHO_READ_TOUT 3
static void echo_send(const int port, const char* str, uint8_t length) {
if (uart_write_bytes(port, str, length) != length) {
ESP_LOGE(TAG, "Send data critical failure.");
abort();
}
}
void setup() {
Serial.begin(9600);
const int uart_num = 1; // UART port number
uart_config_t uart_config = {
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 122,
.source_clk = UART_SCLK_REF_TICK,
};
esp_log_level_set(TAG, ESP_LOG_INFO);
ESP_LOGI(TAG, "Start RS485 application test and configure UART.");
ESP_ERROR_CHECK(uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0));
ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
ESP_LOGI(TAG, "UART set pins, mode, and install driver.");
ESP_ERROR_CHECK(uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RE, ECHO_TEST_DE));
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX));
// Set timeout in terms of milliseconds
ESP_ERROR_CHECK(uart_set_rx_timeout(uart_num, ECHO_READ_TOUT * portTICK_PERIOD_MS));
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
ESP_LOGI(TAG, "UART start receive loop.\r");
echo_send(uart_num, "Start RS485 UART test.\r\n", 24);
}
void loop() {
const int uart_num = 1; // UART port number
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
while (1) {
int len = uart_read_bytes(uart_num, data, BUF_SIZE, PACKET_READ_TICS);
if (len > 0) {
echo_send(uart_num, "\r\n", 2);
char prefix[] = "RS485 Received: [";
echo_send(uart_num, prefix, (sizeof(prefix) - 1));
ESP_LOGI(TAG, "Received %u bytes:", len);
printf("[ ");
for (int i = 0; i < len; i++) {
printf("0x%.2X ", (uint8_t)data[i]);
echo_send(uart_num, (const char*)&data[i], 1);
if (data[i] == '\r') {
echo_send(uart_num, "\n", 1);
}
}
printf("] \n");
echo_send(uart_num, "]\r\n", 3);
} else {
echo_send(uart_num, ".", 1);
ESP_ERROR_CHECK(uart_wait_tx_done(uart_num, 10));
}
}
}
I have Interface RS485 with Esp32 wroom32 and tried to write a code by using Echo but there is no proper communication as shown below serial monitor execution can any one help?
You are using a lot of low-level function-calls.
What is your intention?
Sending a some bytes over serial and that's it?
or
Are the special reasons why you wrote such a complicated code?
Can you please explain in more detail what you are trying do do.
best regards Stefan
Yes I want to send NPK sensor data by Esp32 interfacing with RS485 but before that I want to check with Echo.
So why don't you just configure Serial1 or Serial2 for that?
UART1 is by default connected to pins that can not be used, (GPIO 9 & 10) you will have to assign it custom pins before (or during) it's initialization
this should crash the ESP32
I tried but I'm not getting the values from sensor
Regardless, you do not need code that complicated. UART2 is the easiest to work with since the default pins are useable and or not connected to anything else (UART0 is connected to the USB to TTL converter)
RS485- Esp32 Wroom32
DE- GPIO2
RE- GPIO4
DI- TX2 (GPIO16)
RI- RX2 (GPIO17)
Like this I connected GPIO1 for more readability I assigned in the code.
That is the TX pin for UART0, any debug messages from you code may also be sent using that same pin.
try something like this maybe..
untested sorry..
#include <Arduino.h>
#define TAG "RS485_ECHO_APP"
#define ECHO_TEST_TXD 17
#define ECHO_TEST_RXD 16
#define ECHO_TEST_RE 2
#define ECHO_TEST_DE 4
#define BUF_SIZE 127
#define PACKET_READ_TICS 100// (100 / portTICK_PERIOD_MS)
#define ECHO_READ_TOUT 3
byte data[BUF_SIZE];
int recvdCount = 0;
static void echo_send( const char* str, uint8_t length) {
digitalWrite(ECHO_TEST_DE, HIGH);
digitalWrite(ECHO_TEST_RE, HIGH);
if (Serial2.write(str, length) != length) {
ESP_LOGE(TAG, "Send data critical failure.");
abort();
} else Serial2.flush();
digitalWrite(ECHO_TEST_DE, LOW);
digitalWrite(ECHO_TEST_RE, LOW);
}
void setup() {
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, ECHO_TEST_RXD, ECHO_TEST_TXD);
pinMode(ECHO_TEST_RE, OUTPUT);
pinMode(ECHO_TEST_DE, OUTPUT);
echo_send("Start RS485 UART test.\r\n", 24);
Serial.println("Ready..");
}
void loop() {
unsigned long now = millis();
if (Serial2.available()) {
//read bytes till timeout..
recvdCount = 0;
memset(data, 0, sizeof(data));
while (millis() - now < PACKET_READ_TICS) {
if (Serial2.available()) {
byte b = Serial2.read();
data[recvdCount] = b;
recvdCount++;
if (recvdCount >= sizeof(data)) {
//error, potential overflow
recvdCount = 0;
}
}
}
if (recvdCount > 0) {
echo_send( "\r\n", 2);
char prefix[] = "RS485 Received: [";
echo_send( prefix, (sizeof(prefix) - 1));
ESP_LOGI(TAG, "Received %u bytes:", recvdCount);
Serial.print("[ ");
for (int i = 0; i < recvdCount; i++) {
Serial.printf("0x%.2X ", (uint8_t)data[i]);
echo_send( (const char*)&data[i], 1);
if (data[i] == '\r') {
echo_send( "\n", 1);
}
}
Serial.print("] \n");
echo_send( "]\r\n", 3);
} else {
echo_send( ".", 1);
Serial.println(".");
}
}
}
good luck.. ~q
let me guess, not getting any replay at all..
i've worked a few that came with id not at 1..
try sending a broadcast packet to it, it should respond..
const byte moist_b[] = {0xFF, 0x03, 0x00, 0x00, 0x00, 0x01, 0x91, 0xD4};
the first FF is address 255 broadcast, any sensor connected should respond and will replace the FF with its id, make sure only one hooked up at a time..
good luck.. ~q
Sorry for the delay
Yes as you said that FF is address and 255 is broadcast but Nitrogen, Phosphorus and Potassium values are getting 0 in serial monitor
This one I will try and give an update
I tried this and I am getting like this in serial monitor.
Aha. Two screenshots.
What are the screenshots showing? Sender and receiver of the same data?
Adding explanations what is shown will make it easier to understand.
And you should post serial printing as code-sections.
If anybody would like to take a closer look or search for a certain character.sequence.
If you posted the printing as code-section this will be easy to do
best regards Stefan
Thank you qubits-us this code is working to read data now I am trying to read NPK data over RS485 through Esp32 like below code but unable to read can you help me for this