IMU vs GPS which is better for this application?

nsaspook

Joined Aug 27, 2009
16,344
I would start with the simple processor, the PIC32MX simply to reduce variables. The one thing I did read about the UART-RVC mode is to be sure your UART buffer is always ready to handle input and to be careful with deep UART buffering if you need up to date data at every application read of that buffer. I've seen drivers that dump the buffer after every read to be sure the next read is fresh data.
 

nsaspook

Joined Aug 27, 2009
16,344
My IMU devices have arrived.
1682434749383.png
Looks like I won't be able to add it to a existing small CAN-FD board unless I overlay it in a existing IMU pad. That's something I don't like doing.
1682434897726.png
BNO086 pads up on top of the Murata accelerometer on the board. The small chip on the bottom board is the BMA accelerometer alternative device.

So it's being designed in on a larger display board with lots of space on the bottom to handle all three devices as possible sensor choices.
1682435154319.png
This board file was sent to JLCPCB, should be here by the end of the week, I hope.
 

MisterBill2

Joined Jan 23, 2018
27,673
In was going to suggest using accelerometers rather than GPS, and for that matter, DC coupled accelerometers will be easy to calibrate at zero and full scale. and no software to write if the right devices or scaling can be used.
 

Thread Starter

dcbingaman

Joined Jun 30, 2021
1,065
In was going to suggest using accelerometers rather than GPS, and for that matter, DC coupled accelerometers will be easy to calibrate at zero and full scale. and no software to write if the right devices or scaling can be used.
Thanks MisterBill2 for the suggestion. I think that is a good idea. I am already going down the path though of using the BNO086 IMU and have the board in work with KiCad. :)
 

Thread Starter

dcbingaman

Joined Jun 30, 2021
1,065
My IMU devices have arrived.
View attachment 292771
Looks like I won't be able to add it to a existing small CAN-FD board unless I overlay it in a existing IMU pad. That's something I don't like doing.
View attachment 292772
BNO086 pads up on top of the Murata accelerometer on the board. The small chip on the bottom board is the BMA accelerometer alternative device.

So it's being designed in on a larger display board with lots of space on the bottom to handle all three devices as possible sensor choices.
View attachment 292773
This board file was sent to JLCPCB, should be here by the end of the week, I hope.
Nice! Let me know how your testing goes. I am currently designing a board as well, but not as far along as at the moment as you are.
:)
 

nsaspook

Joined Aug 27, 2009
16,344
In was going to suggest using accelerometers rather than GPS, and for that matter, DC coupled accelerometers will be easy to calibrate at zero and full scale. and no software to write if the right devices or scaling can be used.
The digital interface code is just I/O programming code, that's usually easy if you have complete device information compared to the math needed to use the data effectively. DC/AC coupling applies to old school accelerometers. Analog Sensors Vs. Digital Sensors is the usual terminology for modern sensors, based on the output signal.
 

MisterBill2

Joined Jan 23, 2018
27,673
At the very least, a digital signal requires logic to change it into what can appear on a digital display. Not only does that logic require code to tell the logic how to scale that, it also takes time. An analog signal may require a meter that may be fast or an analog display that may be real time fast.And no code and no code changes for calibration. Calibration is why a DC accelerometer is easy to set, because there is a constant "1 G" available.
And what is the response time for that digital output accelerometer ???
 

nsaspook

Joined Aug 27, 2009
16,344
At the very least, a digital signal requires logic to change it into what can appear on a digital display. Not only does that logic require code to tell the logic how to scale that, it also takes time. An analog signal may require a meter that may be fast or an analog display that may be real time fast.And no code and no code changes for calibration. Calibration is why a DC accelerometer is easy to set, because there is a constant "1 G" available.
And what is the response time for that digital output accelerometer ???
Unless you're all analog from signal to End Effector or display, the signal in a modern device will be digitized and processed. I've used DC output devices decades ago on mil-spec gear. The limiter of actual data rate updates is the sensor response, drift and noise in DC, AC, analog or digital. This is not the 80's. Using a 8MHz clock for transfers and modern hardware $20 9-DOF IMU's (with 14-16 bit resolution) gives you sub-ms response times, kHz sample rates and 32-bit controller processing times in microseconds for double FP operations on 3D vectors. It's easily adequate for real-time quad drone flight control with auto calibration of the acceleration sensor and others.
https://forum.allaboutcircuits.com/threads/pic32mk-mc-qei-example.150351/post-1560143
1682473577988.png
It takes 104us total with 14us processing time (32-bit hardware floating point is great) for a complete position update but the magnetometer 80 Hz refresh rate is the limiting factor.

For a little more money ($50) you can get these digital spec's.
https://www.murata.com/-/media/webr...3300-d01.ashx?la=en&cvid=20210316063715000000
https://www.murata.com/-/media/webr..._article.ashx?la=en&cvid=20190530013729941000

SCL3300 Inclinometer in Short
 3-axis accelerometer
 Direct angle output
 Angle resolution of direct angle output 0.0055°/LSB
 Typical noise density for small angles 0.0013°/√Hz
 Excellent bias stability over component lifetime typically less than 10 mg
 Typical output temperature dependency only 15 mg
 Wide operating temperature range -40...+125 °C
 Low current consumption at the 1 mA level
 Digital 16-bit output
 Small size: 7.6 x 8.6 x 3.3 mm

 
Last edited:

Thread Starter

dcbingaman

Joined Jun 30, 2021
1,065
Unless you're all analog from signal to End Effector or display, the signal in a modern device will be digitized and processed. I've used DC output devices decades ago on mil-spec gear. The limiter of actual data rate updates is the sensor response, drift and noise in DC, AC, analog or digital. This is not the 80's. Using a 8MHz clock for transfers and modern hardware $20 9-DOF IMU's (with 14-16 bit resolution) gives you sub-ms response times, kHz sample rates and 32-bit controller processing times in microseconds for double FP operations on 3D vectors. It's easily adequate for real-time quad drone flight control with auto calibration of the acceleration sensor and others.
https://forum.allaboutcircuits.com/threads/pic32mk-mc-qei-example.150351/post-1560143
View attachment 292808
It takes 104us total with 14us processing time (32-bit hardware floating point is great) for a complete position update but the magnetometer 80 Hz refresh rate is the limiting factor.

For a little more money ($50) you can get these digital spec's.
https://www.murata.com/-/media/webr...3300-d01.ashx?la=en&cvid=20210316063715000000
https://www.murata.com/-/media/webr..._article.ashx?la=en&cvid=20190530013729941000

SCL3300 Inclinometer in Short
 3-axis accelerometer
 Direct angle output
 Angle resolution of direct angle output 0.0055°/LSB
 Typical noise density for small angles 0.0013°/√Hz
 Excellent bias stability over component lifetime typically less than 10 mg
 Typical output temperature dependency only 15 mg
 Wide operating temperature range -40...+125 °C
 Low current consumption at the 1 mA level
 Digital 16-bit output
 Small size: 7.6 x 8.6 x 3.3 mm
Talking about the benefits of the digital realm going far beyond just IMU's. The other modern devices I just love to use are FPGAs, CPLD's and modern SOC's with a hard core Processor combined with FPGA fabric. With programmable logic I can change the entire board behavior with zero changes to the hardware. I can write high level stuff with either a softcore processor or the SOC and at the same time create my own custom digital circuitry to process things even faster using hardware along with true parallel processing. I get all of that and I can even change the hardware with zero changes to my board. I prefer to convert any analog data to digital form first, process it all a want and then if needed convert back to the analog world. With digital filters, I can change the filter characteristics again with zero changes to the board. I think the list of benefits goes on and on.
I am not saying that analog design is not required, RF, audio, power supplies etc. It is obviously still needed but it usually augments digital systems.
 

nsaspook

Joined Aug 27, 2009
16,344
Talking about the benefits of the digital realm going far beyond just IMU's. The other modern devices I just love to use are FPGAs, CPLD's and modern SOC's with a hard core Processor combined with FPGA fabric. With programmable logic I can change the entire board behavior with zero changes to the hardware. I can write high level stuff with either a softcore processor or the SOC and at the same time create my own custom digital circuitry to process things even faster using hardware along with true parallel processing. I get all of that and I can even change the hardware with zero changes to my board. I prefer to convert any analog data to digital form first, process it all a want and then if needed convert back to the analog world. With digital filters, I can change the filter characteristics again with zero changes to the board. I think the list of benefits goes on and on.
I am not saying that analog design is not required, RF, audio, power supplies etc. It is obviously still needed but it usually augments digital systems.
+1 You need a good understanding of both for applied physics applications.
I deal with analog dinosaurs daily. :eek:
1682477092470.png
A modern computer sends/receives digital data to an analog I/O interface board to this magnetic quadrupole magnet power supply.
1682477563329.png
 
Last edited:

MisterBill2

Joined Jan 23, 2018
27,673
Please Keep in mind that the real world is all composed of fairly linear stuff, and that the very vast majority of the digital portion is unseen and even difficult to touch or taste. At least that is the case for most of humanity, at least, so far.
And much of that "wonderful digital world" requires access to resources unavailable to the casual experimenter, as well as a great deal of additional insight and knowledge.
 

nsaspook

Joined Aug 27, 2009
16,344
Please Keep in mind that the real world is all composed of fairly linear stuff, and that the very vast majority of the digital portion is unseen and even difficult to touch or taste. At least that is the case for most of humanity, at least, so far.
And much of that "wonderful digital world" requires access to resources unavailable to the casual experimenter, as well as a great deal of additional insight and knowledge.
Today digital is far more accessible to the casual experimenter IMO. Analog has become the esoteric domain of magic as digital evolved into component modules able to replace even high power analog output circuits that has given us things like marvelous bldc motor drivers that are 99% digital in design that move cars and flying machines.
https://forum.allaboutcircuits.com/threads/pic32mk-mc-qei-example.150351/post-1527541
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,344
Testing the new PCB. Looks like the IMU hardware is working correctly.
1682918985489.png
I just love hand soldering those LGA package devices.
1682919020452.png
Blob solder bumps for the pads, gel flux and a SMD head-gun.
1682920051347.png
1682919077783.png
IMU debug signal header.
1682919131927.png
1Mhz SPI clock for testing
1682919165988.png
1682919198126.png
I have the proper SPI SH2 Sensorhub messages so the basic connections, chip and chip time std 32kHz OSC are all working correctly.
1682919842469.png
Need to tweak the mishmash of driver code into something coherent.
 
Last edited:

Thread Starter

dcbingaman

Joined Jun 30, 2021
1,065
Nice. How many layer board are you using?
I usually use solder-paste along with a stencil.

Hot plate for one side of the board and if I am unfortunate enough to haver parts on both sides of the board a hot air gun for the other side.

This will be the first time I had to solder an LGA part. What I did find out was for best results the stencil opening should be smaller than the pads for a 70-90% covering of the pad. It looks like the other LGA part you have there is a 32Khz Crystal if I am looking at your board correctly?

Are you willing to share your schematic?
 

nsaspook

Joined Aug 27, 2009
16,344
Nice. How many layer board are you using?
I usually use solder-paste along with a stencil.

Hot plate for one side of the board and if I am unfortunate enough to haver parts on both sides of the board a hot air gun for the other side.

This will be the first time I had to solder an LGA part. What I did find out was for best results the stencil opening should be smaller than the pads for a 70-90% covering of the pad. It looks like the other LGA part you have there is a 32Khz Crystal if I am looking at your board correctly?

Are you willing to share your schematic?
It a four layer board from JLC. The board CAD design is using a paid version of EagleCad.
The design is for the SPI interface and is a work in progress. YMMV.
1683080087723.png

It's all hand soldered with a iron or hot air-gun with fine solder and good magnification. I have an oven but rarely use it for most things designed to be hand built. It's tricky to bump the tiny LGA pads for hot-air soldering but I've been doing it for a while.
32Khz Clock Oscillator
https://www.mouser.com/datasheet/2/96/TC25-1001783.pdf

A early (very beta) version of the driver is running in Sensor HUB interrupt mode.
1683080318376.png
1683080570493.png
The IMU INT signal is active low and it re-triggered by a Sensor HUB data Report Feature request.
C:
            if (imu0.update) {
                imu0.update = false;
                enableReport(TOTAL_ACCELERATION, 10);
                imu0.op.imu_getdata(&imu0); // read data from the chip
            }
1683080372752.png
Total Acceleration sensor packet. The interrupt rises then the data is read.
C:
/*
* setup external interrupt #2 for IMU BNO08X data update interrupt trigger output
*/
void init_imu_int_bno(const imu_cmd_t * imu)
{
    if (imu) {
        INTCONCLR = _INTCON_INT2EP_MASK; //External interrupt on falling edge
        IFS0CLR = _IFS0_INT2IF_MASK; // Clear the external interrupt flag
        EVIC_ExternalInterruptCallbackRegister(EXTERNAL_INT_2, update_imu_int_bno, (uintptr_t) imu);
        EVIC_ExternalInterruptEnable(EXTERNAL_INT_2);
    }
}

/*
* user callback function per BNO08X data interrupt
* update pacing flag from IMU ISR
* passes an pointer to the IMU data object
*/
void update_imu_int_bno(uint32_t a, uintptr_t context)
{
    imu_cmd_t * imu = (imu_cmd_t *) context;

    if (imu) {
        imu->update = true;
        bno08x_int_count++;
    }
}
The callback sets a flag for the main loop and keeps count of total IMU interrupts generated from the device and executed on the controller.

1683081382100.png
4 byte header first on both send and receiver. Send a Set Feature Accelerometer command 0xFD 0x01 and report get data back.
 

nsaspook

Joined Aug 27, 2009
16,344
Have most of the show-stopper bugs out of the BNO086 Sensor HUB interface driver.

I can select and get several types of IMU reports for the test display app to use.

Serial port debugging info for two reportid's (accelerometer and quaternion Angular position fusion) that both trigger interrupts to the PIC32 for processing via IMU SHTP SPI transfers.
1683519609374.png
1683519694323.png1683519717721.png
 

nsaspook

Joined Aug 27, 2009
16,344
The SPI on that IMU is a strange duck as the receive data packets are full-duplex with any transmission so you need to send lots of null transmit packets to get the required complete receive data packet. There is also several critical timing requirements to get the correct data from the IMU when requested. One of the most critical to have at least 100us between host transmissions. I had several debug printf line between send packets to check the software logic that when removed the transfer interrupts worked but only zero data packets were received.
C:
// check for new data and read contents into imu.rbuf
bool bno086_receive_packet(void * imup)
{
    imu_cmd_t * imu = imup;

    bno086_get_header(imu); // first 4 bytes
    delay_us(100);
    if (bno086_get_cpacket(SHTP_HEADER_SIZE, imu)) {
        dprintf("bno086_receive_packet\r\n"); // <-----
        delay_us(100); // added for the needed per transmission delay.
        processPacket();
        return true;
    }
    return false;
My debug printf dprintf used above.
C:
//#define PDEBUG
    int printf_stub(const char*, ...);

#ifdef PDEBUG
#define    dprintf    printf
#else
#define dprintf    printf_stub
#endif
////
/*
* dummy printf replacement for debug line printf elimination
*/
int printf_stub(const char* s, ...)
{
    return 1; // dummy printed value
}
With a define of PDBUG in the header file I can select the real printf or the printf_sub. Printf_stub is a function that only returns 1 (not used or checked for) as the number of characters printed but does nothing with the supplied function arguments.
So printf_stub is optimized out of the code by the compiler. The lack of delay caused the data transfers to fail so I added a fixed delay in the code to compensate.
1683581151733.png
Header and data block timing.
1683581207883.png
Header that returns the length 0x0013 and type 0x03 of data packet.
1683581335366.png
The data section of the packet. Length 0x0013 (the MSB 0x80 means a packet continuation from the first block of received data) code is 0xFB for the accelerometer SHTP header.

1683582729862.png
That data XYZ is decoded from 16-bit fixed point Q format to a C double and that data is scaled to the correct range.
Some code fragments to show how it's done
C:
// start IMU sensor reports with rates

enableReport(ROTATION, UPDATE_MS);
enableReport(TOTAL_ACCELERATION, UPDATE_MS);

//Given a register value and a Q point, convert to float
//See https://en.wikipedia.org/wiki/Q_(number_format)

double qToFloat(int16_t fixedPointValue, uint8_t qPoint)
{
    double qFloat = fixedPointValue;
    qFloat *= pow(2.0f, -qPoint);
    return(qFloat);
}
//// packet data (offset from the start of the received data buffer) frame offsets skip the timestamp data.
uint8_t * rxShtpData = imu0.rbuf + SHTP_HEADER_SIZE; // SPI receive data buffer
#define SIZEOF_BASE_TIMESTAMP 5

currReportOffset += SIZEOF_BASE_TIMESTAMP;

uint16_t data1 = (uint16_t) rxShtpData[currReportOffset + 5] << 8 | rxShtpData[currReportOffset + 4];
#define ACCELEROMETER_Q_POINT 8 // for accelerometer based data

totalAcceleration.v[0] = qToFloat(data1, ACCELEROMETER_Q_POINT);
///
accel->x = totalAcceleration.v[0] * accelRange; // scale to the correct units
I still have a few IMU boot/restart timing bugs to fix. I'm thinking to increase the IMU reset capacitor so the CPU is up and running, waiting for the IMU reset on power up restart
 
Last edited:

Thread Starter

dcbingaman

Joined Jun 30, 2021
1,065
The SPI on that IMU is a strange duck as the receive data packets are full-duplex with any transmission so you need to send lots of null transmit packets to get the required complete receive data packet. There is also several critical timing requirements to get the correct data from the IMU when requested. One of the most critical to have at least 100us between host transmissions. I had several debug printf line between send packets to check the software logic that when removed the transfer interrupts worked but only zero data packets were received.
C:
// check for new data and read contents into imu.rbuf
bool bno086_receive_packet(void * imup)
{
    imu_cmd_t * imu = imup;

    bno086_get_header(imu); // first 4 bytes
    delay_us(100);
    if (bno086_get_cpacket(SHTP_HEADER_SIZE, imu)) {
        dprintf("bno086_receive_packet\r\n"); // <-----
        delay_us(100); // added for the needed per transmission delay.
        processPacket();
        return true;
    }
    return false;
My debug printf dprintf used above.
C:
//#define PDEBUG
    int printf_stub(const char*, ...);

#ifdef PDEBUG
#define    dprintf    printf
#else
#define dprintf    printf_stub
#endif
////
/*
* dummy printf replacement for debug line printf elimination
*/
int printf_stub(const char* s, ...)
{
    return 1; // dummy printed value
}
With a define of PDBUG in the header file I can select the real printf or the printf_sub. Printf_stub is a function that only returns 1 (not used or checked for) as the number of characters printed but does nothing with the supplied function arguments.
So printf_stub is optimized out of the code by the compiler. The lack of delay caused the data transfers to fail so I added a fixed delay in the code to compensate.
View attachment 293773
Header and data block timing.
View attachment 293774
Header that returns the length 0x0013 and type 0x03 og data packet.
View attachment 293775
The data section of the packet. Length 0x0013 (the MSB 0x80 means a packet continuation from the first block of received data) code is 0xFB for the accelerometer SHTP header.

View attachment 293776
That data XYZ is decoded from 16-bit fixed point Q format to a C double and that data is scaled to the correct range.
Some code fragments to show how it's done
C:
//Given a register value and a Q point, convert to float
//See https://en.wikipedia.org/wiki/Q_(number_format)

double qToFloat(int16_t fixedPointValue, uint8_t qPoint)
{
    double qFloat = fixedPointValue;
    qFloat *= pow(2.0f, -qPoint);
    return(qFloat);
}
//// packet data (offset from the start of the received data buffer) frame offsets skip the timestamp data.
uint8_t * rxShtpData = imu0.rbuf + SHTP_HEADER_SIZE; // SPI receive data buffer
#define SIZEOF_BASE_TIMESTAMP 5

currReportOffset += SIZEOF_BASE_TIMESTAMP;

uint16_t data1 = (uint16_t) rxShtpData[currReportOffset + 5] << 8 | rxShtpData[currReportOffset + 4];

totalAcceleration.v[0] = qToFloat(data1, ACCELEROMETER_Q_POINT);
///
accel->x = totalAcceleration.v[0] * accelRange; // scale to the correct units
I still have a few IMU boot/restart timing bugs to fix. I'm thinking to increase the IMU reset capacitor so the CPU is up and running, waiting for the IMU reset on power up restart
Thanks for the information. I am stilling working on my primary display board for the Automotive Acceleration Display. The other board will have the processor and the IMU to send the data to. Attached is the schematic thus far for the display board if you are interested. I wanted a '1980's 1990's' look to the display by using 10 segment bar graphs to show acceleration in Y+, Y-, X+ and X-. Along with a 4 digit seven segment display for the actual RSS value. The display is blue (my favorite LED color). I have a 32 count optical encoder knob that will allow the user to change the screen brightness over an 8 bit range using a PWM. I am using a chip someone else on the forum recommended, that is the TI part: TLC6C5712-Q1. A nice 12 channel LED driver with PWM control.

I started working on a preliminary layout for this board. As shown here.

1683599840171.png
The board is about 5.5 inches long by 2.5 inches high. The bar graphs are arranged as shown in a cross format and the 4 digit display is to the right of that (surface mount) 4 parts. It will be mounted into an enclosure that I am designing using FreeCad along with a 3D printer for that part.

It is good to know about the 100 microsecond limit on the chip. I would have never guessed that. Concerning the nulls for full duplex that is one thing I noticed while reading the datasheet that made the communication a little 'odd'. But I guess you take the good with the bad.

I plan on requesting data from the IMU about 100 times per second and filtering it in the processor to eliminate 'bumps in the road'.

I am not nearly as far along as you, but you are blazing the trail finding the quirks with using this chip. Thanks!
 

Attachments

nsaspook

Joined Aug 27, 2009
16,344
Thanks for the information. I am stilling working on my primary display board for the Automotive Acceleration Display. The other board will have the processor and the IMU to send the data to. Attached is the schematic thus far for the display board if you are interested. I wanted a '1980's 1990's' look to the display by using 10 segment bar graphs to show acceleration in Y+, Y-, X+ and X-. Along with a 4 digit seven segment display for the actual RSS value. The display is blue (my favorite LED color). I have a 32 count optical encoder knob that will allow the user to change the screen brightness over an 8 bit range using a PWM. I am using a chip someone else on the forum recommended, that is the TI part: TLC6C5712-Q1. A nice 12 channel LED driver with PWM control.

I started working on a preliminary layout for this board. As shown here.

View attachment 293787
The board is about 5.5 inches long by 2.5 inches high. The bar graphs are arranged as shown in a cross format and the 4 digit display is to the right of that (surface mount) 4 parts. It will be mounted into an enclosure that I am designing using FreeCad along with a 3D printer for that part.

It is good to know about the 100 microsecond limit on the chip. I would have never guessed that. Concerning the nulls for full duplex that is one thing I noticed while reading the datasheet that made the communication a little 'odd'. But I guess you take the good with the bad.

I plan on requesting data from the IMU about 100 times per second and filtering it in the processor to eliminate 'bumps in the road'.

I am not nearly as far along as you, but you are blazing the trail finding the quirks with using this chip. Thanks!



Nice.

If you're using the UART robot data stream then you won't hopefully have the timing and other issues I'm having talking to the sensor hub for pre-processed sensor data in a simpler manner that most of the complex full featured published drivers. It's worth the one-time hassle, as I can get from the IMU several types of data outputs that would have taken lots of external processing (number crunching vectors and matrices) on the raw sensor data that I've needed to use on other less capable sensors.

Here I have
Line 1: Raw (Total) Acceleration that includes the earth's gravity acceleration.
Line 2: Angular rotation quaternion.
Line 3: Linear Acceleration without gravity.
1683602602514.png
C:
                enableReport(ROTATION, UPDATE_MS);
                enableReport(TOTAL_ACCELERATION, UPDATE_MS);
                enableReport(LINEAR_ACCELERATION, UPDATE_MS);
How the different representations are displayed as the IMU is moved.
0.25 speed is better.
 
Last edited:
Top