Electronics

2016-05-23 05:20 I uploaded the project to a GitHub repository

LIDAR Lite2 - How to use I2C without Arduino
Part 2 - Cypress CY8C4247LQI-BL483

2016-05-22 06:24

After some reverse engineering in Part 1 of the LIDAR I2C protocol used in Pulsed Light's demo for the Arduino UNO, lets now see if the new gained knowledge is any good for a different platform.

I'm using the Cypress CY8CKIT-042-BLE Poineer Kit, with the CY8C4247LQI-BL483 daughter board mounted.

Since the Pioneer Kit has Arduino UNO compatible headers, re-wirering is just a matter of switching the cables from the Arduino to the Cypress board 1:1.

Protocol testing

To test the protocol independent of any implementation details, I used the Bridge Control Panel Application. This programm is part of the Windows-based PSoC Creater IDE, that Cypress provides free of charge.

The tool allows us to script sequences of I2C commands.
(You can find the CommandScript.iic in the BridgeControlPanel sub-dir of this project's GitHub repository.)

In the top part of the Editor panel you write the commands.
The bottom part shows the responses.

Readers of Part 1 might recognize some of them.

Putting the cursor in one line of the top part of the Editor panel and clicking the Send button, sends the sequence over the I2C bus.

Selecting multiple lines in the top part of the Editor panel and clicking the Send button, sends all the selected sequences over the I2C bus.

  1. sequence writes (w) to the LIDAR I2C address (0x62, first hex value), Command Control Register (0x00, second hex value), the value 0x00 (last hex value), sending the LIDAR the Reset
    command.
    The LIDAR responses to each hex value written with the ACK signal (+) and to the completion of the sequence with the Stop signal (p).
  2. sequence writes (w) to the LIDAR I2C address (0x62, first hex value), Mode Control Register (0x04, second hex value), the value 0x8C (last hex value).
    Bit 7 = 1 Enable velocity measurement
    Bit 3 = 1 Disable short signal acquisition
    Bit 2 = 1 Disable short reference
    The LIDAR responses to each hex value written with the ACK signal (+) and to the completion of the sequence with the Stop signal (p).
  3. sequence writes (w) to the LIDAR I2C address (0x62, first hex value), Outer Loop Count Register (0x11, second hex value), the value 0xFF (last hex value), configuring the LIDAR for continous measurement mode.
    The LIDAR responses to each hex value written with the ACK signal (+) and to the completion of the sequence with the Stop signal (p).
  4. sequence writes (w) to the LIDAR I2C address (0x62, first hex value), Command Control Register (0x00, second hex value), the value 0x04 (last hex value), starting LIDAR's continous acquisition & correlation processing with DC correction.
    The LIDAR responses to each hex value written with the ACK signal (+) and to the completion of the sequence with the Stop signal (p).
  5. The registers 0x0F and 0x10 have to be read to get the two byte distance measurement from the LIDAR.
    Using LIDAR's auto increment capability this can be done in one call.

    Auto Increment is activated by setting the Most Significant Bit (MSB) in the register address.
    So, to read the register 0x0F and 0x10 in one call we address the register 0x8F (0x0F with MSB set to 1 = 0x8F => LIDAR register auto increment) .

    As it is standard for operating the I2C bus:

    • The register address to read is written to the LIDAR I2C address (0x62, first hex value)
      The LIDAR responses with ACK (+) to both bytes sent (0x62 0x8F).
    • The Read command (r) is send to LIDAR's I2C address (0x62, third hex value), fetching the two bytes from 0x0f (0x00) and 0x10 (0xDC).
      (The necessary Restart sequence between write and read is handled by the software in the background, as is the expected NACK signal at the end of the data transfer.)
      The LIDAR response with a Stop (p) to the NACK sent by the Bridge Control Panel.

Using variables in the Bridge Control Panel

For values to read, you usually put a x in the command sequence at the position of the byte to read.

To be able to use advanced features of the program, you can define vatiables using Chart|Variable Settings.

These variables can than be used in the positions where usually the x would be expected.

The VariablesSettings.ini can be found in the BridgeControlPanel sub-dir of this project's GitHub repository.

Using Bridge Control Panel's chart for the LIDAR data

After defining variables we can now use the chart functionality of the Bridge Control Panel application to visualize changes, measured by the LIDAR.

Select the two last lines in the Editor panel:

Switch to the Chart panel and click the Repeat button:

Well, looks like we got the protocol right!

Firmware development

Having the basics in place, we can finally start developing the firmware.

To keep things simple:

The PSoC configuration in the Creator Software is pretty basic:

We use an I2C Master for the MCU-LIDAR communication

and a standard UART for the MCU-COM communication

The pin-mapping is dictated by:

  1. the Kit's USB-COM bridge (UART over USB on P1[4], P1[5])
  2. Arduino UNO compatible I2C connection (I2C on P3[4], P3[5])

The Firmware source code starts with some definitions to make the code more readable:

In the next lines we declare the LIDAR I2C messages we are going to send:

The main() function (at the end of the file) controls the whole operation:

This is pretty much standard code for initializing a PSoC.

At line 260 the custom code starts:

At this point the initialization is done.

Calling our custom function LIDAR_startMeasuringContinously() put the LIDAR in measuring mode.

We declare a variable for each of the expected measuremnt results and enter an infinite loop.

In that loop we:

Lets now dive a little deeper into some of the custom functions.

LIDAR_Init()

LIDAR_StartMeasuringContinously()

LIDAR_Measure()

Reads the current measurement values form the LIDAR.

It also implements a simple algorithm for averaging over a given number of measured values.

LIDAR_Distance()

Reads the current distance measurement values form the LIDAR.

Following I2C protocol

LIDAR_Velocity()

Reads the current velocity value form the LIDAR.

Following I2C protocol

LIDAR_I2C_SendMsg()

is a helper function, that actually sends a message to the LIDAR via I2C using the build in I2C_I2CMasterWriteBuf() function.

The function also implements some error recover and reporting functionality.

LIDAR_I2C_ReadBuf()

reads a number of bytes (cnt) from the I2C bus into a buffer (*buf).

The implementation is equivalent to LIDAR_I2C_SendMsg(), we just use the build in library function I2C_I2CMasterReadBuf() to read bytes from the I2C bus.

UART_send_I2CMasterApiStatus()

is a helper function, that forwards I2C Master Api Errors as text strings over the UART.

Test run

Now we can

If everything works as it should, you should see a result similar to this

Moving the sensor (or something in front of it) should change the values displayed accordingly.