Skip to content
Snippets Groups Projects
test_recept_loramac_ard.ino 5.41 KiB
#include <ArduinoJson.h>

static char recv_buf[512];
static int led = 2;

/**
 * @brief Sends an AT command and checks for a specific response within a timeout period.
 *
 * This function sends an AT command to a device connected via Serial2 and waits for a specific
 * acknowledgment response within the specified timeout period. The function also prints the
 * command and received characters to the Serial monitor for debugging purposes.
 *
 * @param p_ack The expected acknowledgment response string. If NULL, the function returns immediately.
 * @param timeout_ms The timeout period in milliseconds to wait for the acknowledgment response.
 * @param p_cmd The AT command to send. This is a format string, followed by additional arguments
 *              as needed (similar to printf).
 * @param ... Additional arguments for the AT command format string.
 * @return int Returns 1 if the acknowledgment response is received within the timeout period,
 *             otherwise returns 0.
 */
static int at_send_check_response(char *p_ack, int timeout_ms, char *p_cmd, ...)
{
    int ch;
    int num = 0;
    int index = 0;
    int startMillis = 0;
    va_list args;
    memset(recv_buf, 0, sizeof(recv_buf));
    va_start(args, p_cmd);
    Serial2.print(p_cmd);
    Serial.print(p_cmd);
    va_end(args);
    delay(200);
    startMillis = millis();

    if (p_ack == NULL)
        return 0;

    do
    {
        while (Serial2.available() > 0)
        {
            ch = Serial2.read();
            recv_buf[index++] = ch;
            Serial.print((char)ch);
            delay(2);
        }

        if (strstr(recv_buf, p_ack) != NULL)
            return 1;

    } while (millis() - startMillis < timeout_ms);
    Serial.println();
    return 0;
}

/**
 * @brief Parses and processes a received message.
 *
 * This function takes a received message string, extracts the data portion,
 * converts it from a hexadecimal string to a byte array, and prints the byte
 * array in hexadecimal format.
 *
 * @param p_msg Pointer to the received message string. If the message is NULL,
 *              the function will print "Received null" and return immediately.
 *
 * The function performs the following steps:
 * 1. Checks if the received message is NULL.
 * 2. Searches for the "RX" substring in the message.
 * 3. Extracts the data portion following the "RX" substring.
 * 4. Converts the extracted data from a hexadecimal string to a byte array.
 * 5. Prints the byte array in hexadecimal format.
 */
static void recv_prase(char *p_msg)
{
    if (p_msg == NULL)
    {
        Serial.println("Received null");
        return;
    }
    char *p_start = NULL;
    char data[128]; // To hold the received bytes as characters

    int bytes_len = 0;
    p_start = strstr(p_msg, "RX");
    if (p_start && (1 == sscanf(p_start, "RX \"%s\"", &data)))
    {
        for (int i = 0; i < sizeof(data); i++)
        {
            if (int(data[i + 1]) == 0)
            {
                bytes_len = i;
                break;
            }
        }

        // Convert the characters to a byteArray
        int message_len = bytes_len / 2 + 1;
        byte out[message_len];
        auto getNum = [](char c)
        { return c > '9' ? c - 'A' + 10 : c - '0'; };
        for (int x = 0, y = 0; x < bytes_len; ++x, ++y)
            out[y] = (getNum(data[x++]) << 4) + getNum(data[x]);
        out[message_len] = '\0';

        // Print the received bytes
        for (int i = 0; i < sizeof(out) - 1; i++)
        {
            Serial.print(out[i], HEX);
            Serial.print("-");
        }
        Serial.println();
    }
}

/**
 * @brief Setup function for initializing serial communication and configuring the device.
 * 
 * This function performs the following tasks:
 * - Initializes the Serial communication at a baud rate of 9600.
 * - Sets the pin mode for the LED pin to OUTPUT.
 * - Sets the initial state of the LED to LOW (off).
 * - Initializes the Serial2 communication at a baud rate of 9600.
 * - Prints a test message to Serial.
 * - Sends AT commands to configure the device for LoRa communication:
 *   - Checks for an OK response with the "AT" command.
 *   - Sets the device mode to TEST with the "AT+MODE=TEST" command.
 *   - Sets the device to receive LoRa packets with the "AT+TEST=RXLRPKT" command.
 * - Delays for 200 milliseconds.
 * - Sets the LED state to HIGH (on).
 */
void setup(void)
{
    Serial.begin(9600);
    pinMode(led, OUTPUT);
    digitalWrite(led, LOW);
    Serial2.begin(9600);
    Serial.print("Serial2 LOCAL TEST\r\n");
    at_send_check_response("+AT: OK", 100, "AT\r\n");
    at_send_check_response("+MODE: TEST", 1000, "AT+MODE=TEST\r\n");
    at_send_check_response("+TEST: RXLRPKT", 5000, "AT+TEST=RXLRPKT\r\n");
    delay(200);
    digitalWrite(led, HIGH);
}

/**
 * @brief Main loop function that continuously attempts to receive data via LoRaMAC.
 * 
 * This function runs indefinitely, attempting to receive data every 5 seconds.
 * It constructs a command to transmit a HEX value, sends the command, and checks for a response.
 * If a response is received, it processes the received data; otherwise, it prints an error message.
 * 
 * @note The function uses a delay of 5000 milliseconds (5 seconds) between each attempt.
 */
void loop(void)
{
    char cmd[128];
    // Transmit HEX Value
    sprintf(cmd, "");
    int ret = at_send_check_response("+TEST: RX", 1000, "");
    if (ret)
        recv_prase(recv_buf);
    else
        Serial.println("Receive failed!\r\n\r\n");
    delay(5000);
}