Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
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 08 Mar 2017Please 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 08 Mar 2017Error: 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 09 Mar 2017For 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 09 Mar 2017My 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 10 Mar 2017I 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 13 Mar 2017