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.
8 years, 8 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
8 years, 8 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();
}
}