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, 6 months ago.
LPC7168 and CAN communication with Time-of-Flight Sensor
Hello,
I've recently been working on a project to create a suspension sensor using an optical distance sensor. This sensor uses I2C to communicate with our microcontroller and has been consistently printing to a computer with accurate values. However, the next stage is to communicate with the CAN bus. Here is my main code:
#include "mbed.h" #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); CAN can(p30, p29); //rd, td 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"); } int main() { CANMessage messageOut; //formatting CANMessage messageOut.format = CANStandard; messageOut.id = 0x720; //11100100000 ID in binary messageOut.len = 1; //8 bits, 1 byte //the dataToSend which i want is a the data produced by a function in my header 'sensor.getDistance()' uint8_t distance; //dataToSend messageOut.data[0] = (char)(distance & 0x00ff); //distance is the variable obtained in my header messageOut.data[1] = (char)(distance>>8); 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("%d\n", sensor.getDistance() ); this is what used to happen; it would print to a computer can.write(messageOut); //hopefully sending data along bus wait_ms(10); //100hz } }
So, I believe the message is properly formatted but I don't think I am actually sending the correct data. This is the getDistance() function in the header:
uint8_t VL6180x::getDistance() { uint8_t distance; VL6180x_setRegister(VL6180X_SYSRANGE_START, 0x01); //Start Single shot mode wait_ms(10); distance = VL6180x_getRegister(VL6180X_RESULT_RANGE_VAL); VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CLEAR, 0x07); return distance; }
Any insight would be great. If you need to see any other bits of the code just ask. Cheers
1 Answer
7 years, 6 months ago.
I suspect it is the evolution of your code for testing that has introduced some issues. These will make it more difficult to help.
messageOut.len = 1; //8 bits, 1 byte
the "payload" size of this message is 1-byte, but below it suggests you want to send 2 bytes
uint8_t distance; //dataToSend messageOut.data[0] = (char)(distance & 0x00ff); //distance is the variable obtained in my header messageOut.data[1] = (char)(distance>>8);
distance is an 8-bit value, and not initialized, and then split into 2 x 8-bit registers. So, this is quite inconsistent, and not initialized.
uint8_t VL6180x::getDistance() {
getDistance returns only an 8-bit value, so these fragments are not all that consistent with each other.
I'd suggest you revise your while(1) loop, building up the following a step at a time.
- get the value from the sensor and assign it to a variable.
- printf that value, and assess if it looks right
- put that value into the message, and send it.
- you might also send a fixed value message, something you could easily very as correct, just to prove your CAN communications.
Thanks for your reply. I have, as far as i am aware changed the values so they are all 8-bit (sorry if they aren't - I'm a bit new). Here is my modified code:
int main() { CANMessage messageOut; //formatting CANMessage messageOut.format = CANStandard; messageOut.id = 0x720; //11100100000 ID in binary messageOut.len = 1; //8 bits, 1 byte //the dataToSend which i want is a the data produced by a function in my header 'sensor.getDistance()' uint8_t distance; //dataToSend messageOut.data[0] = (char)(distance >> 8) & 0xff; 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) { distance = sensor.getDistance(); printf("%d\n", distance); can.write(messageOut); wait_ms(10); //100hz } }
I suspect I may not have initialised uint8_t but I am unsure how exactly you mean. Cheers
posted by 14 Mar 2017He means that you are trying to use the variable distance before you have set it's value.
int main() { CANMessage messageOut; //formatting CANMessage messageOut.format = CANStandard; messageOut.id = 0x720; //11100100000 ID in binary messageOut.len = 1; //8 bits, 1 byte //the dataToSend which i want is a the data produced by a function in my header 'sensor.getDistance()' uint8_t distance; //dataToSend // You can't set the message data before you read the sensor. // messageOut.data[0] = (char)(distance >> 8) & 0xff; 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) { distance = sensor.getDistance(); // changed to %u, distance is unsigned. printf("%u\n", distance); // now set the can message data. No need to do anything fancy since everything is 8 bit data. messageOut.data[0] = distance; can.write(messageOut); wait_ms(10); //100hz } }
I'll give this a bash. Thank you, guys.
EDIT: That's it working, guys, cheers!
EDIT2:This is my final code working as it should.
#include "mbed.h" #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); CAN can(p30, p29); //rd, td 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"); } int main() { CANMessage messageOut; //formatting CANMessage messageOut.format = CANStandard; messageOut.id = 0x720; messageOut.len = 1; uint8_t distance; //dataToSend can.frequency(100000); 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) { distance = sensor.getDistance(); printf("%u\n", distance); //u for unsigned int messageOut.data[0] = distance; can.write(messageOut); wait_ms(10); //100hz can.reset(); } }