Help with Grove Doppler Radar (BGT24LTR11) not interfacing

Hi Everyone,

I am a student working a on a project that utilizes a Grove Doppler Radar(BGT24LTR11). I am struggling to interface with it using a MEGA 2560 R3. Right now, I am trying to use the sample code to just understand and play around with the radar yet I can't seem to get it to work.

Link to Github:

Here is the sample code I have been using:
BGT24LTR11_DETECTION_TARGET.ino (1.3 KB)
BGT24LTR11.cpp (14.9 KB)
BGT24LTR11.h (1.6 KB)

In terms of hardware, I am powering the radar using the 5v and GND on the Arduino and I changed the software serial ports to 10, and 11 for the Mega.

When I run the code, nothing appears in my serial monitor at any baud rate. The code seems to get caught in the

 while (!BGT.setMode(0))
        ;

I am not really sure what is causing this? Is it hardware or software? How should I go about fixing this or how should I diagnose the problem - a am new to this?

If I just read the Serial monitor at 115200 baud I see data coming in on repeat. I looked at the communication documentation and I dont even see this as a possibility.

Grove_DopplerRadar(BGT24LTR11)Radar_module_communication_protocol_v1.1.pdf (200.8 KB)

Data I am picking up on repeat just reading the Serial port in HEX:
55, A2, C1, 0, 5, 0, 0, 0, 1, BD

I apologize if it something super simple. I have been stuck on this issue for quite a while now.

Thanks

Why not put serial.Print() messages before and after that bit of code and verify it is stopping there?

Thanks for the response and help. I tried it out and the code is indeed stuck in the loop. I just put it in the loop.

ShowSerial.println("TEST");

and it infinitely runs and prints.

Thanks

Ok, then have you looked at the documentation and determined why "
BGT.setMode(0)) might return a false? What are the possible return values?

You shouldn't use SoftwareSerial on a Mega.
Use one of the three hardware serial ports (Serial1 to Serial3).
Leo..

Thank you sooo much I just got it to work switching it to the hardware ports.

I appreciate so much. If anyone finds themselves in the same predicament. Here is my code:

#include "BGT24LTR11.h"

#ifdef __AVR__
    #include <SoftwareSerial.h>
    //SoftwareSerial SSerial(10, 11); // RX, TX  Made Changes Here
    #define COMSerial Serial1
    #define ShowSerial Serial

    BGT24LTR11<HardwareSerial> BGT;  //Made a change here!
#endif

#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
    #define COMSerial Serial1
    #define ShowSerial SerialUSB

    BGT24LTR11<Uart> BGT;
#endif

#ifdef ARDUINO_ARCH_STM32F4
    #define COMSerial Serial
    #define ShowSerial SerialUSB

    BGT24LTR11<HardwareSerial> BGT;
#endif

void setup() {
    // put your setup code here, to run once:
    ShowSerial.begin(9600);
    COMSerial.begin(115200);
    BGT.init(COMSerial);
    while (!ShowSerial)
        ;
    while (!COMSerial)
        ;
    /*
        MODE 0 -->detection target mode
        MODE 1 -->I/Q ADC mode

    */
    while (!BGT.setMode(0))
    ShowSerial.println("TEST");
        ;
}

void loop() {
    // put your main code here, to run repeatedly:
    uint16_t state = 0;
    ShowSerial.print("target speed:");
    ShowSerial.println(BGT.getSpeed());
    state = BGT.getTargetState();
    //2 --> target approach
    //1 --> target leave
    //0 --> Not Found target
    if (state == 2) {
        ShowSerial.println("target approach");
    } else if (state == 1) {
        ShowSerial.println("target leave");
    }
    delay(200);
}


//--------------------------- BGT24LTR11.cpp -----------------------------------------
#include "BGT24LTR11.h"

template <class T>
void BGT24LTR11<T>::init(T& serialPort) {
    _serial = &serialPort;
}

/****************************************************************
    Function Name: calculateChecksum
    Description: Calculate checksum from data bytes
    Parameters: data, pointer to uint16_t data array. data_length, length of array to calculate checksum over
    Return: uint16_t value of checksum
****************************************************************/
template <class T>
uint16_t BGT24LTR11<T>::calculateChecksum(uint16_t *data, uint16_t data_length) {
    uint16_t checksum = 0;
    for (uint16_t i = 0;  i < data_length; ++i) {
        checksum += data[i];
    }

    return checksum;
}

/****************************************************************
    Function Name: messageChecksum
    Description: Transform checksum from message to single value
    Parameters: high_order, low_order, last two checksum bytes from the message
    Return: uint16_t value of checksum
****************************************************************/
template <class T>
uint16_t BGT24LTR11<T>::messageChecksum(uint16_t high_order, uint16_t low_order) {
    return ((high_order << 8) + low_order);
}

/****************************************************************
    Function Name: getSpeed
    Description: Target acquisition speed
    Parameters: None
    Return: >0:success speed -1:fail
****************************************************************/
template <class T>
uint16_t BGT24LTR11<T>::getSpeed() {
    uint16_t data[7] = {0};
    _serial->write(commandC1, 7);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_GET_TARGET) {
                    for (int i = 0; i < 7; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_GET_TARGET + calculateChecksum(data, 5);
                    const uint16_t msg_checksum = messageChecksum(data[5], data[6]);

                    if (checksum != msg_checksum) {
                        return -1;
                    }

                    return (data[2] * 256 + data[3]);
                }
            }
        }
        /* code */
    }
    return -1;
}

/****************************************************************
    Function Name: getTargetState
    Description: Get target state
    Parameters: None
    Return: 2:target approach   1:target leave  0:Not Found target
****************************************************************/
template <class T>
uint16_t BGT24LTR11<T>::getTargetState() {
    uint16_t data[7] = {0};
    _serial->write(commandC1, 7);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_GET_TARGET) {
                    for (int i = 0; i < 7; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_GET_TARGET + calculateChecksum(data, 5);
                    const uint16_t msg_checksum = messageChecksum(data[5], data[6]);

                    if (checksum != msg_checksum) {
                        return 0;
                    }

                    //2 --> target approach
                    //1 --> target leave
                    //0 --> Not Found target
                    return data[4];
                }
            }
        }
        /* code */
    }
    return 0;
}

/****************************************************************
    Function Name: getIQADC
    Description: Gets the I/Q information ADC value.
    Parameters: I_d,Q_d,Store an array of I/Q information. len,The length of the array.
    Return: 1:success  0:fail
****************************************************************/
template <class T>
uint8_t BGT24LTR11<T>::getIQADC(uint16_t I_d[], uint16_t Q_d[], uint16_t* len) {
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_GET_IQADC) {
                    uint16_t length_h, length_l, length;
                    length_h = _serial->read();
                    length_l = _serial->read();
                    length = length_h * 256 + length_l;
                    for (int i = 0; i < ((length - 2) / 2); i++) {
                        I_d[i] = _serial->read();
                        Q_d[i] = _serial->read();
                    }
                    *len = (length - 2) / 2;
                    return 1;
                }
            }
        }
        /* code */
    }
    return 0;
}

/****************************************************************
    Function Name: setSpeedScope
    Description: Set the detection speed range.
    Parameters: maxspeed,minspeed 0-65535
    Return: 1:success  0:fail
****************************************************************/
template <class T>
uint8_t BGT24LTR11<T>::setSpeedScope(uint16_t maxspeed, uint16_t minspeed) {
    uint16_t data[8] = {0};
    uint16_t len = 0;
    unsigned char commandC3[11] = {0x55, 0x2A, 0xC3, 0x00, 0x06, 0x02, 0x09, 0x01, 0x03, 0x01, 0x57};
    if (maxspeed < minspeed) {
        return 0;
    }
    commandC3[5] = maxspeed / 256;
    commandC3[6] = maxspeed % 256;
    commandC3[7] = minspeed / 256;
    commandC3[8] = minspeed % 256;
    for (int i = 0; i < 9; i++) {
        len += commandC3[i];
    }
    commandC3[9] = len / 256;
    commandC3[10] = len % 256;
    _serial->write(commandC3, 11);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_SET_SPEED_SCOPE) {
                    for (int i = 0; i < 8; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_SET_SPEED_SCOPE + calculateChecksum(data, 6);
                    const uint16_t msg_checksum = messageChecksum(data[6], data[7]);

                    if (checksum != msg_checksum) {
                        return 0;
                    }

                    if (((data[2] * 256 + data[3]) == maxspeed) && ((data[4] * 256 + data[5]) == minspeed)) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            }
        }
        /* code */
    }
    return 0;
}

/****************************************************************
    Function Name: getSpeedScope
    Description: Get the detection speed range.
    Parameters: maxspeed,minspeed
    Return: 1:success  0:fail
****************************************************************/
template <class T>
uint8_t BGT24LTR11<T>::getSpeedScope(uint16_t* maxspeed, uint16_t* minspeed) {
    unsigned char commandC4[7] = {0x55, 0x2A, 0xC4, 0x00, 0x02, 0x01, 0x45};
    uint16_t data[8] = {0};
    _serial->write(commandC4, 7);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_GET_SPEED_SCOPE) {
                    for (int i = 0; i < 8; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_GET_SPEED_SCOPE + calculateChecksum(data, 6);
                    const uint16_t msg_checksum = messageChecksum(data[6], data[7]);

                    if (checksum != msg_checksum) {
                        return 0;
                    }

                    *maxspeed = data[2] * 256 + data[3];
                    *minspeed = data[4] * 256 + data[5];
                    return 1;
                }
            }
        }
        /* code */
    }
    return 0;
}

/****************************************************************
    Function Name: setMode
    Description: Set module mode.
    Parameters: 1:Gets the I/Q information ADC value mode. 0:To detect the target mode.
    Return: 1:success  0:fail
****************************************************************/
template <class T>
uint8_t BGT24LTR11<T>::setMode(uint16_t mode) {
    if (mode > 1) {
        return 0;
    }
    unsigned char commandC5[8] = {0x55, 0x2A, 0xC5, 0x00, 0x03, 0x00, 0x01, 0x47};

    if (mode == 1) {
        commandC5[5] = 0x01;
        commandC5[7] = 0x48;
    }
    uint16_t data[5] = {0};
    _serial->write(commandC5, 8);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_SET_MODE) {
                    for (int i = 0; i < 5; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_SET_MODE + calculateChecksum(data, 3);
                    const uint16_t msg_checksum = messageChecksum(data[3], data[4]);

                    if (checksum != msg_checksum) {
                        return 0;
                    }

                    if (data[2] == mode) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            }
        }
        /* code */
    }
    return 0;
}

/****************************************************************
    Function Name: getMode
    Description: Get module mode.
    Parameters: none.
    Return: 1:detect the target mode  2:Reported I/Q ADC  0:fail
****************************************************************/
template <class T>
uint8_t BGT24LTR11<T>::getMode() {
    unsigned char commandC6[7] = {0x55, 0x2A, 0xC6, 0x00, 0x02, 0x01, 0x47};
    uint16_t data[5] = {0};
    _serial->write(commandC6, 7);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_GET_MODE) {
                    for (int i = 0; i < 5; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_GET_MODE + calculateChecksum(data, 3);
                    const uint16_t msg_checksum = messageChecksum(data[3], data[4]);

                    if (checksum != msg_checksum) {
                        return 0;
                    }

                    //return 1 ---> detect the target mode
                    //return 2 ---> Reported I/Q ADC
                    //return 0 ---> fail
                    if (data[2] == 0) {
                        return 1;
                    } else if (data[2] == 1) {
                        return 2;
                    } else {
                        return 0;
                    }
                }
            }
        }
        /* code */
    }
    return 0;
}

/****************************************************************
    Function Name: setThreshold
    Description: Set threshold.
    Parameters: threshold.
    Return: 1:success  0:fail
****************************************************************/
template <class T>
uint8_t BGT24LTR11<T>::setThreshold(uint16_t threshold) {
    int len = 0;
    uint16_t data[8] = {0};
    unsigned char commandC7[11] = {0x55, 0x2A, 0xC7, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x01, 0x50};
    commandC7[5] = threshold / 256 / 256 / 256 % 256;
    commandC7[6] = threshold / 256 / 256 % 256;
    commandC7[7] = threshold / 256 % 256;
    commandC7[8] = threshold % 256;
    for (int i = 0; i < 9; i++) {
        len += commandC7[i];
    }
    commandC7[9] = len / 256 % 256;
    commandC7[10] = len % 256;
    _serial->write(commandC7, 11);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_SET_THRESHOLD) {
                    for (int i = 0; i < 8; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_SET_THRESHOLD + calculateChecksum(data, 6);
                    const uint16_t msg_checksum = messageChecksum(data[6], data[7]);

                    if (checksum != msg_checksum) {
                        return 0;
                    }

                    uint16_t thr = data[2] * 256 * 256 * 256 + data[3] * 256 * 256 + data[4] * 256 + data[5];
                    if (thr == threshold) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            }
        }
        /* code */
    }
    return 0;
}

/****************************************************************
    Function Name: getThreshold
    Description: Get threshold.
    Parameters: None.
    Return: 1:success  0:fail
****************************************************************/
template <class T>
uint16_t BGT24LTR11<T>::getThreshold() {
    unsigned char commandC8[7] = {0x55, 0x2A, 0xC8, 0x00, 0x02, 0x01, 0x49};
    uint16_t data[8] = {0};
    _serial->write(commandC8, 7);
    while (_serial->available() > 0) {
        if (_serial->read() == BGT24LTR11_MESSAGE_HEAD) {
            if (_serial->read() == BGT24LTR11_SEND_ADDRESS) {
                if (_serial->read() == BGT24LTR11_COMMAND_GET_THRESHOLD) {
                    for (int i = 0; i < 8; i++) {
                        data[i] = _serial->read();
                    }

                    const uint16_t checksum = BGT24LTR11_MESSAGE_HEAD + BGT24LTR11_SEND_ADDRESS + BGT24LTR11_COMMAND_GET_THRESHOLD + calculateChecksum(data, 6);
                    const uint16_t msg_checksum = messageChecksum(data[6], data[7]);

                    if (checksum != msg_checksum) {
                        return 0;
                    }

                    uint16_t whr = 0;
                    whr = data[2] * 256 * 256 * 256 + data[3] * 256 * 256 + data[4] * 256 + data[5];
                    return whr;
                }
            }
        }
        /* code */
    }
    return 0;
}

#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
    template class BGT24LTR11<Uart>;
#endif

template class BGT24LTR11<HardwareSerial>;

#if defined(__AVR__) || defined(ESP8266) || defined(ESP32)
    //#include <SoftwareSerial.h>
    template class BGT24LTR11<HardwareSerial>; //Made a change here!!!
#endif

//---------------------------BGT24LTR11.h-----------------------------
#ifndef __BGT24LTR11__
#define __BGT24LTR11__
#include "Arduino.h"

//address code
#define BGT24LTR11_MESSAGE_HEAD 0x55
#define BGT24LTR11_RECEIVE_ADDRESS 0x2A
#define BGT24LTR11_SEND_ADDRESS 0xA2

//command code
#define BGT24LTR11_COMMAND_GET_TARGET 0xC1
#define BGT24LTR11_COMMAND_GET_IQADC 0xC2
#define BGT24LTR11_COMMAND_SET_SPEED_SCOPE 0xC3
#define BGT24LTR11_COMMAND_GET_SPEED_SCOPE 0xC4
#define BGT24LTR11_COMMAND_SET_MODE 0xC5
#define BGT24LTR11_COMMAND_GET_MODE 0xC6
#define BGT24LTR11_COMMAND_SET_THRESHOLD 0xC7
#define BGT24LTR11_COMMAND_GET_THRESHOLD 0xC8

// target state
#define BGT24LTR11_TARGET_APPROACH 0x02
#define BGT24LTR11_TARGET_LEAVE 0x01
#define BGT24LTR11_TARGET_NONE 0x00

//mode
#define BGT24LTR11_MODE_TARGET 0x00
#define BGT24LTR11_MODE_IQADC 0x01

template <class T>
class BGT24LTR11 {
  private:
    T* _serial;
    unsigned char commandC1[7] = {BGT24LTR11_MESSAGE_HEAD, BGT24LTR11_RECEIVE_ADDRESS,
                                  BGT24LTR11_COMMAND_GET_TARGET,
                                  0x00, 0x02, 0x01, 0x42
                                 };
    /* data */
  public:
    void init(T& serialPort);
    uint16_t getSpeed();
    uint16_t getTargetState();
    uint8_t getIQADC(uint16_t I_d[], uint16_t Q_d[], uint16_t* len);
    uint8_t setSpeedScope(uint16_t maxspeed, uint16_t minspeed);
    uint8_t getSpeedScope(uint16_t* maxspeed, uint16_t* minspeed);
    uint8_t setMode(uint16_t mode);
    uint8_t getMode();
    uint8_t setThreshold(uint16_t whreshold);
    uint16_t getThreshold();
    uint16_t calculateChecksum(uint16_t *data, uint16_t data_length);
    uint16_t messageChecksum(uint16_t high_order, uint16_t low_order);

};

#endif




This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.