【问题标题】:Mikroe RS485 Click with Azure Sphere - Issue sending and receiving byte arrays using RS485Mikroe RS485 Click with Azure Sphere - 使用 RS485 发送和接收字节数组
【发布时间】:2021-05-24 21:51:52
【问题描述】:

我正在使用 Avnet Azure 球体板,并连接了 RS485 点击板。在 RS485 Click 中,GPIO PWM 拉高以从 Click 板发送 RS485 信号,GPIO PWM 拉低以接收 RS485 信号。 这里的问题是发送请求至少需要 2 秒,但连接的传感器会在几毫秒内返回响应,然后我们将 GPIO PWM 切换回低电平以进行接收。因此我的 UART 返回事件没有触发。任何帮助将不胜感激。

我的发送UART消息功能

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 返回事件

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);
}

【问题讨论】:

  • 你使用的是什么操作系统?

标签: c iot uart rs485 azure-sphere


【解决方案1】:

RS485 是半双工的,因此一次只能传输一个设备。因此,您必须在完成发送数据后立即关闭发射器。理想情况下,您应该在硬件中执行此操作。在您的情况下,在您关闭发射器之前,您似乎有一个delay_milliseconds(2000);。这会导致冲突,传输的任何数据都将丢失。

【讨论】:

  • 如果我没有给延迟,发送数据是不成功的。无论如何我们可以延迟传感器的响应吗?
  • 发送后必须立即关闭发射器。如果您的写入是通过 DMA 工作的,您需要将关闭发送器与 DMA 传输完成时调用的中断联系起来。一种常见的模式是使用 UART RTS 线来切换发送器。
  • DMA 完成中断不是切换收发器的正确​​事件; UART 硬件仍然需要更多时间来移出最后一个字符帧。软件中可靠/准确的控制只能通过UART设备驱动程序来实现。顺便说一句,这个“答案”似乎更像是一个评论而不是一个具体的解决方案。
  • 问题出在我为毫秒等待创建的延迟方法上。当我给出低于 1000 的值时,它四舍五入到零。一切正常。
猜你喜欢
  • 1970-01-01
  • 2015-03-07
  • 2019-05-09
  • 2020-08-05
  • 2010-11-13
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多