Mikroe RS485 Click with Azure Sphere - 使用 RS485 发送和接收字节数组
Mikroe RS485 Click with Azure Sphere - Issue sending and receiving byte arrays using RS485
我正在使用连接了 RS485 click 板的 Avnet Azure sphere 板。在 RS485 Click 中,GPIO PWM 设为高电平以从 Click 板发送 RS485 信号,GPIO PWM 设为低电平以接收 RS485 信号。
这里的问题是发送请求至少需要 2 秒,但在我们将 GPIO PWM 切换回低电平以进行接收之前,连接的传感器 return 会在几毫秒内做出响应。因此我的 UART return 事件没有触发。任何帮助将不胜感激。
我的发送串口消息功能
static void SendUartMessage(int uartFd, const char* dataToSend, size_t totalBytesToSend, bool ignoreRx)
{
size_t totalBytesSent = 0;
//size_t totalBytesToSend = strlen(dataToSend);
int sendIterations = 0;
close(r1PinFd);
r1PinFd = GPIO_OpenAsOutput(MIKROE_PWM, GPIO_OutputMode_PushPull, GPIO_Value_High);
while (totalBytesSent < totalBytesToSend) {
sendIterations++;
// Send as much of the remaining data as possible
size_t bytesLeftToSend = totalBytesToSend - totalBytesSent;
const char* remainingMessageToSend = dataToSend + totalBytesSent;
ssize_t bytesSent = write(uartFd, remainingMessageToSend, bytesLeftToSend);
if (bytesSent == -1) {
Log_Debug("ERROR: Could not write to UART: %s (%d).\n", strerror(errno), errno);
exitCode = ExitCode_SendMessage_Write;
return;
}
totalBytesSent += (size_t)bytesSent;
}
int c, d;
delay_milliseconds(2000);
close(r1PinFd);
r1PinFd = GPIO_OpenAsOutput(MIKROE_PWM, GPIO_OutputMode_PushPull, GPIO_Value_Low);
Log_Debug("Sent %zu bytes over UART in %d calls.\n", totalBytesSent, sendIterations);
}
我的 RS485 UART return 事件
static void UartEventHandler(EventLoop* el, int fd, EventLoop_IoEvents events, void* context)
{
const size_t receiveBufferSize = 256;
uint8_t receiveBuffer[receiveBufferSize + 1]; // allow extra byte for string termination
ssize_t bytesRead;
// Read incoming UART data. It is expected behavior that messages may be received in multiple
// partial chunks.
bytesRead = read(uartFd, receiveBuffer, receiveBufferSize);
if (bytesRead == -1) {
Log_Debug("ERROR: Could not read UART: %s (%d).\n", strerror(errno), errno);
exitCode = ExitCode_UartEvent_Read;
return;
}
if (bytesRead > 0) {
receiveBuffer[bytesRead] = 0;
Log_Debug("UART received %d bytes: '%s'.\n", bytesRead);
char data_hex_str[sizeof(receiveBuffer) / sizeof(receiveBuffer[0])];
get_hex(receiveBuffer, sizeof(receiveBuffer) / sizeof(receiveBuffer[0]), data_hex_str, sizeof(receiveBuffer) / sizeof(receiveBuffer[0]), 16);
strcat(returnDataUart, data_hex_str);
Log_Debug("\s", returnDataUart);
}
char* pjsonBuffer = (char*)malloc(JSON_BUFFER_SIZE);
if (pjsonBuffer == NULL) {
Log_Debug("ERROR: not enough memory to send telemetry");
}
snprintf(pjsonBuffer, JSON_BUFFER_SIZE,
"{\"gX\":%.2lf, \"gY\":%.2lf, \"gZ\":%.2lf, \"aX\": %.2f, \"aY\": "
"%.2f, \"aZ\": %.2f, \"pressure\": %.2f, \"light_intensity\": %.2f, "
"\"altitude\": %.2f, \"temp\": %.2f, \"rssi\": %d, \"RS485\": %s}",
acceleration_g.x, acceleration_g.y, acceleration_g.z, angular_rate_dps.x,
angular_rate_dps.y, angular_rate_dps.z, pressure_kPa, light_sensor, altitude,
lsm6dso_temperature, network_data.rssi, returnDataUart);
Log_Debug("\n[Info] Sending telemetry: %s\n", pjsonBuffer);
SendTelemetry(pjsonBuffer, true);
free(pjsonBuffer);
}
RS485 是半双工的,所以一次只能有一个设备传输。因此,您必须在发送完数据后立即关闭发射器。理想情况下,您应该在硬件中执行此操作。在你的情况下,看起来你在关闭发射器之前有一个 delay_milliseconds(2000);
。这会导致冲突,所有传输的数据都将丢失。
我正在使用连接了 RS485 click 板的 Avnet Azure sphere 板。在 RS485 Click 中,GPIO PWM 设为高电平以从 Click 板发送 RS485 信号,GPIO PWM 设为低电平以接收 RS485 信号。 这里的问题是发送请求至少需要 2 秒,但在我们将 GPIO PWM 切换回低电平以进行接收之前,连接的传感器 return 会在几毫秒内做出响应。因此我的 UART return 事件没有触发。任何帮助将不胜感激。
我的发送串口消息功能
static void SendUartMessage(int uartFd, const char* dataToSend, size_t totalBytesToSend, bool ignoreRx)
{
size_t totalBytesSent = 0;
//size_t totalBytesToSend = strlen(dataToSend);
int sendIterations = 0;
close(r1PinFd);
r1PinFd = GPIO_OpenAsOutput(MIKROE_PWM, GPIO_OutputMode_PushPull, GPIO_Value_High);
while (totalBytesSent < totalBytesToSend) {
sendIterations++;
// Send as much of the remaining data as possible
size_t bytesLeftToSend = totalBytesToSend - totalBytesSent;
const char* remainingMessageToSend = dataToSend + totalBytesSent;
ssize_t bytesSent = write(uartFd, remainingMessageToSend, bytesLeftToSend);
if (bytesSent == -1) {
Log_Debug("ERROR: Could not write to UART: %s (%d).\n", strerror(errno), errno);
exitCode = ExitCode_SendMessage_Write;
return;
}
totalBytesSent += (size_t)bytesSent;
}
int c, d;
delay_milliseconds(2000);
close(r1PinFd);
r1PinFd = GPIO_OpenAsOutput(MIKROE_PWM, GPIO_OutputMode_PushPull, GPIO_Value_Low);
Log_Debug("Sent %zu bytes over UART in %d calls.\n", totalBytesSent, sendIterations);
}
我的 RS485 UART return 事件
static void UartEventHandler(EventLoop* el, int fd, EventLoop_IoEvents events, void* context)
{
const size_t receiveBufferSize = 256;
uint8_t receiveBuffer[receiveBufferSize + 1]; // allow extra byte for string termination
ssize_t bytesRead;
// Read incoming UART data. It is expected behavior that messages may be received in multiple
// partial chunks.
bytesRead = read(uartFd, receiveBuffer, receiveBufferSize);
if (bytesRead == -1) {
Log_Debug("ERROR: Could not read UART: %s (%d).\n", strerror(errno), errno);
exitCode = ExitCode_UartEvent_Read;
return;
}
if (bytesRead > 0) {
receiveBuffer[bytesRead] = 0;
Log_Debug("UART received %d bytes: '%s'.\n", bytesRead);
char data_hex_str[sizeof(receiveBuffer) / sizeof(receiveBuffer[0])];
get_hex(receiveBuffer, sizeof(receiveBuffer) / sizeof(receiveBuffer[0]), data_hex_str, sizeof(receiveBuffer) / sizeof(receiveBuffer[0]), 16);
strcat(returnDataUart, data_hex_str);
Log_Debug("\s", returnDataUart);
}
char* pjsonBuffer = (char*)malloc(JSON_BUFFER_SIZE);
if (pjsonBuffer == NULL) {
Log_Debug("ERROR: not enough memory to send telemetry");
}
snprintf(pjsonBuffer, JSON_BUFFER_SIZE,
"{\"gX\":%.2lf, \"gY\":%.2lf, \"gZ\":%.2lf, \"aX\": %.2f, \"aY\": "
"%.2f, \"aZ\": %.2f, \"pressure\": %.2f, \"light_intensity\": %.2f, "
"\"altitude\": %.2f, \"temp\": %.2f, \"rssi\": %d, \"RS485\": %s}",
acceleration_g.x, acceleration_g.y, acceleration_g.z, angular_rate_dps.x,
angular_rate_dps.y, angular_rate_dps.z, pressure_kPa, light_sensor, altitude,
lsm6dso_temperature, network_data.rssi, returnDataUart);
Log_Debug("\n[Info] Sending telemetry: %s\n", pjsonBuffer);
SendTelemetry(pjsonBuffer, true);
free(pjsonBuffer);
}
RS485 是半双工的,所以一次只能有一个设备传输。因此,您必须在发送完数据后立即关闭发射器。理想情况下,您应该在硬件中执行此操作。在你的情况下,看起来你在关闭发射器之前有一个 delay_milliseconds(2000);
。这会导致冲突,所有传输的数据都将丢失。