7 years, 8 months ago.

Using LPC1768 and CAN Communication

Hello,

I'm new to using the LPC1768 and coding in general, however, as part of a university project, i need to interface with a ToF VL6180X sensor. I was able to copy sample code and get it printing to a PC terminal output using I2C (coolterm).

As part of the project, I then need to send this data to a CAN transceiver. I know the basics of CAN communication but I'm hoping to find some sample code of sending the I2C information to the CAN transceiver.

Any help would be great.

1 Answer

7 years, 8 months ago.

Take a look at this page first:

https://developer.mbed.org/handbook/CAN

Then make an attempt at it yourself and ask when you get stuck or don't understand something.

It's a lot easier to answer a specific questions rather than something as general as your question.

#include "mbed.h" //lpc1768
#include <VL6180x.h>

#define VL6180X_ADDRESS 0x29
 
VL6180xIdentification identification;

// mbed uses 8bit addresses shift address by 1 bit left
VL6180x sensor(p28, p27, VL6180X_ADDRESS<<1);
 
void printIdentification(struct VL6180xIdentification *temp){
  printf("Model ID = ");
  printf("%d\n",temp->idModel);
 
  printf("Model Rev = ");
  printf("%d",temp->idModelRevMajor);
  printf(".");
  printf("%d\n",temp->idModelRevMinor);
 
  printf("Module Rev = ");
  printf("%d",temp->idModuleRevMajor);
  printf(".");
  printf("%d\n",temp->idModuleRevMinor);  
 
  printf("Manufacture Date = ");
  printf("%d",((temp->idDate >> 3) & 0x001F));
  printf("/");
  printf("%d",((temp->idDate >> 8) & 0x000F));
  printf("/1");
  printf("%d\n",((temp->idDate >> 12) & 0x000F));
  printf(" Phase: ");
  printf("%d\n",(temp->idDate & 0x0007));
 
  printf("Manufacture Time (s)= ");
  printf("%d\n",(temp->idTime * 2));
  printf("\n\n");
}

CAN can(p30, p29);

int main() {
 
    CANmessageOut messageOut;
    
    messageOut.format = CANStrandard;
    messageOut.id = 0x720; //11100100000 ID in binary
    messageOut.len = 8; //VL6180x uses I2C so is this 16 bits?
    messageOut.data[0] = //I want the data received from my VL6180x here to write
    
    can.frequency(1000000); //arbitrary just now 
    can.reset();
    

 
    wait_ms(10); // delay .1s
 
    sensor.getIdentification(&identification); // Retrieve manufacture info from device memory
    printIdentification(&identification); // Helper function to print all the Module information
 
    if(sensor.VL6180xInit() != 0){
        printf("FAILED TO INITALIZE\n"); //Initialize device and check for errors
    };
 
    sensor.VL6180xDefautSettings(); //Load default settings to get started.
  
    wait_ms(20); // delay 
   
    while(1) {
      
    /*printf("Distance measured (mm) = ");
    printf("%d\n", sensor.getDistance() );  what used to happen was it would print to a computer */
      
    can.write(messageOut);
    
    wait_ms(20);  
    
    }
}

I keep getting an error saying the can message is undefined.

posted by Fraser Law 08 Mar 2017

Please report the actual error you get, not something a bit like it. You're probably getting "CANmessageOut is undefined" or similar. Line 43 should be CANmessage messageOut;

You also have a typo on line 45 and a clear syntax error on line 48. You probably shouldn't worry about setting the data values until after you have read the sensor and know what values you want to send.

messageOut.len = 8; is setting the CAN message length to 8 bytes (the maximum). If you only want to send 16 bits of data then set it to 2.

The code to then set the data values would be:

int16 dataToSend;
messageOut.data[0] = (char)(dataToSend & 0x00ff);
messageOut.data[1] = (char)(dataToSend>>8);

That will send the LSB in data 0 and the MSB in data 1, swap them over if you want the other order.

posted by Andy A 08 Mar 2017

Error: Identifier "CANStrandard" is undefined in "main.cpp", Line: 77, Col: 26 Error: Identifier "int16" is undefined in "main.cpp", Line: 81, Col: 6

These are the specific errors I'm getting. I still don't quite see how the data incoming from my sensor is being fitted into this string and being sent?

posted by Fraser Law 09 Mar 2017

For the first error try correcting the spelling from strandard to standard. That is the typo I was referring to, I made the assumption you would be able to spot it yourself once I'd told you the line to check.

int16 should be int16_t, I'd forgotten the naming convention used on mbed. Assuming your data source is a signed number rather than unsigned.

"I still don't quite see how the data incoming from my sensor is being fitted into this string and being sent?"

1) What string? There is no string, you are sending a sequence of 2 binary bytes (plus headers etc) over CAN not a string.

2) It's not being fitted into anything yet because your code doesn't make it obvious what it is you want to send. Set dataToSend to the value you want to send. Hence the name.

posted by Andy A 09 Mar 2017

My bad, that's all the errors sorted. Thanks for that.

What i meant by "I still don't quite see how the data incoming from my sensor is being fitted into this string and being sent?" is that I want to include the information that was being printed to the screen initially and then send it along the CAN bus instead. i.e.

    while(1) {
      
    /*printf("Distance measured (mm) = ");
    printf("%d\n", sensor.getDistance() );  what used to happen was it would print to a computer */
      
    can.write(messageOut);
    
    wait_ms(20);  

However, instead of printing sensor.getDistance() i want to send that information to the CAN.

posted by Fraser Law 10 Mar 2017

I think I've got it all working now and I think I understand what's happened in the code you provided in terms of formatting the CANMessage. I changed the 'dataToSend' to 'distance' which is originally in the getDistance() function within one of my header files:

uint8_t VL6180x::getDistance(){
   uint8_t distance;
   VL6180x_setRegister(VL6180X_SYSRANGE_START, 0x01);
   wait_ms(10);
   distance = VL6180x_getRegister(VL6180X_RESULT_RANGE_VAL);
   VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CLEAR, 0x07);

   return distance:
}

I think that will work and it makes sense (to me).

posted by Fraser Law 13 Mar 2017