0

CAN Bus example for MRMS LIDAR 4m VL53L1X, CAN Bus (mrm-lid-can-b2)

Prerequisites

If not already done so already, install Arduino software and make basic connections, as described in page for MRMS ESP32: Arduino, IMU, eFuse, BT, WiFi, CAN Bus (mrm-esp32). This setup is convenient, but it is not mandatory. Read on and we will describe how to connect some other microcontroller and power supply.

This setup is necessary for the rest of ML-R system. If You want to try just this example, don't copy all the libraries but only directories "mrm-common" and "mrm-can-bus". They provide CAN Bus support, but again just for ESP32 microcontroller, ML-R or any other. If You want to use some other MCU, You will have to start its CAN Bus driver. If You do so, this example will work for that board, too.

Task

We will order the lidar to start measuring distance and sending the result every few milliseconds.

Connections

Starting from a basic connection, let's add a MRMS LIDAR 4m VL53L1X, CAN Bus (mrm-lid-can-b2). Connecting a ML-R CAN Bus device is easy. Only a cable, like MRMS CAN Bus cable 10 cm (mrm-jst-can10), is necessary. The cable will connect 2 CAN Bus lines (low and high) and will also supply 0 V and 5 V through 3. and 4. wire.

However, this bus is not only intended for ML-R devices, but for any other CAN Bus compatible. You can read here how to connect Your boards to ML-R CAN Bus.

Program

The program is short, but it hides some of the details in Mrm_can_bus class:

#include <mrm-can-bus.h>

#define COMMAND_SENSORS_MEASURE_CONTINUOUS 0x10
#define COMMAND_SENSORS_MEASURE_SENDING 0x13

Mrm_can_bus can;

uint8_t data[8];        // Message content: 8 bytes

void setup() {
  Serial.begin(115200);

  data[0] = COMMAND_SENSORS_MEASURE_CONTINUOUS;  // First byte of the content
  for (uint8_t i = 0; i < 8; i++)
    can.messageSend(0x150 + 2 * i, 1, data);
  for (uint8_t i = 0; i < 8; i++)
    can.messageSend(0x270 + 2 * i, 1, data);
}

void loop() {
  // Receive a message
  CANBusMessage* msg = can.messageReceive();
  if (msg != NULL && msg->data[0] == COMMAND_SENSORS_MEASURE_SENDING){
    uint16_t mm = (msg->data[2] << 8) | msg->data[1];
    Serial.print(mm);
    Serial.println(" mm");
  }
}
The program uses Mrm_can_bus class to access ESP32s CAN Bus hardware. setup() starts serial communication with PC so that Serial.print() can display the results. Array data is payload CAN Bus messages use. First we will use it for an outgoing message and so we set its first byte to COMMAND_SENSORS_MEASURE_CONTINUOUS. That's the command we'd like to execute. It will instruct the sensor to start sending measurement data continually. As You can have many lidars of this kind in Your CAN Bus, each is supposed to listen to just one message id. The whole range is covered by the 2 loops that follow: 0x150, 0x152,..., 0x15E, and the next one 0x270,..., 0x27E. You can change address the sensor listens to but You may not know how the one You have is set up. So, we start them all.

loop() receives messages. You should be familiar with CAN Bus message structure to understand data sent and received. When a message is received, the program will check first byte of the payload to see if it is a measurement result. If it is, it will convert bytes 2 and 3 into millimeters and will print the result.

You can use an oscilloscope or a logic analyzer to check the signals.

The program uses mrm-can-bus library which can be found in C:\Users\<Your login name>\Documents\Arduino\libraries\mrm-can-bus\src. Open mrm-can-bus.cpp in an editor. Notepad++ is a good choice. If You want to change bus speed from the default 250 kbps, find line with "CAN_TIMING_CONFIG_250KBITS" and change the constant. If You like to have messages' content displayed, change "#define VERBOSE 0" into "#define VERBOSE 1". This library is based on Espressif's native driver so Espressif original documentation will give You all the information.

If You use ML-R CAN Bus devices, by far the easiest option for CAN Bus usage will be to stick to the ML-R framework which takes care about messaging so CAN Bus layer is not exposed at all. When You demand MRMS LIDAR 4m VL53L1X, CAN Bus (mrm-lid-can-b2) to return a measured distance, You just call a function. The framework takes care that the reasonably fresh result is supplied. The details of this work are not so easy to replicate.

Here is the complete CAN Bus interface:
CommandMCU -> sensorSensor -> MCUComment
Calibration0x05If a temperature varies greatly, a calibration will improve measuring. Calibration data are saved in sensor's flash. Initial calibration is mandatory for this sensor. Otherwise measured distance will vary greatly. Initial calibration was conducted during production. To calibrate the sensor, place a 17% gray target at 140 mm from the sensor and send the sensor this command.
Firmware0x190x1A LowByte HighByteFirmware version = (HighByte << 8) & LowByte.
FPS0x300x31 LowByte HighByteFrames Per Second (sensor's local loop frequency) = (HighByte << 8) & LowByte.
Id change0x40 newIdChanges message's id the sensor listens to. It is close to its address. Valid "newId" values are 0 - 14. Each value chooses addresses in one of 2 ranges: 0x150, 0x152,..., 0x15E and 0x270,..., 0x27E. 0 chooses 0x150, 1 0x152, etc.
Alive0xFF id0xFFIf the sensor with address "id" is present, it will return the message.
Reset0x1B
Measure once0x110x13 LowByte HighByteMeasures just once and returns the result. Result in mm = (HighByte << 8) & LowByte
Measure continuous0x100x13 LowByte HighByteInitiates measuring and returning of the measured temperature each few ms, if the distance changes. Result in mm = (HighByte << 8) & LowByte.
Stop measuring0x12
Distance mode0x50 type"type" is 0 for long range, 1 for short range. Short mode has better ambient light immunity but the maximum distance is limited to 1.3 m. Long distance ranges up to 4 m but is less performant under ambient light. Data are retained in flesh memory during power loss.
Inter-measurement time0x52 LowByte HighByteTime in ms = (HighByte << 8) & LowByte. Time must be bigger than timing budget. Choose the same time as TB to get the biggest frequency. Data are retained in flesh memory during power loss.
Timing budget0x51 LowByte HighByteBudget in ms = (HighByte << 8) & LowByte. Possible ms values are 20, 50, 100, 200, and 500. TB improves the measurement reliability but increases power consumption. Data are retained in flesh memory during power loss.
Region of interest.0x53 ByteX ByteYByteX and ByteY can be between 4 and 16. Data are retained in flesh memory during power loss.
Info.0x24Returns sensor's settings.

CAN Bus limitations

For 1 node You will have no problems. If You plan to have many of them, check this page.