Prop Shield Beta Test

Status
Not open for further replies.
I'd like to make the case for this faster 1/sqrtf() implementation again.
It's twice as fast. Worst case error I found so far was better than 0.00005 absolute.

-Ben

Code:
#define TESTCOUNT 		10
#define TESTLENGTH		5000

elapsedMicros time;
unsigned int sqrtfTime;
unsigned int qsqrtfTime;
void setup() {
Serial.begin(9600);
delay(500);

for (int test=0 ; test<TESTCOUNT ; test++) {
	Serial.print("Test #"); Serial.println(test+1);
	// ***** generating random values to test on
	randomSeed(analogRead(0));
	float randomNumber[TESTLENGTH];
	for (int i=0 ; i<TESTLENGTH ; i++){
		randomNumber[i] = float(random(1E9)) / 1E6;
	}
	
	// ***** calculate normal sqrtf() *****
	float normalroot[TESTLENGTH];
	time = 0;
	for (int i=0 ; i < TESTLENGTH ; i++) {
		normalroot[i] = 1.f / sqrtf(randomNumber[i]);
	}
	sqrtfTime = time;
	Serial.print("Computing "); Serial.print(TESTLENGTH);
	Serial.print(" inverse square roots using the normal sqrtf() function took ");
	Serial.print(sqrtfTime); Serial.println(" microseconds.");
	
	// ***** fast qsqrtf() *****
	float fastroot[TESTLENGTH];
	time = 0;
	for (int i=0 ; i < TESTLENGTH ; i++) {
		fastroot[i] = qsqrtf(randomNumber[i]);
	}
	qsqrtfTime = time;
	Serial.print("Computing "); Serial.print(TESTLENGTH);
	Serial.print(" inverse square roots using the  fast qsqrtf() function took ");
	Serial.print(qsqrtfTime); Serial.println(" microseconds.");
	
	// ***** finding maximum error made by faster function
	float maxErrorFast = 0.f;
	int maxErrorIndex = 0;
	for (int i=0 ; i < TESTLENGTH ; i++) {
		if ( (fastroot[i] - normalroot[i]) > maxErrorFast ) {
			maxErrorFast = fastroot[i] - normalroot[i];
			maxErrorIndex = i;
		}
	}
	Serial.print("maximum absolute error with fast sqrt was: ");
	Serial.println(maxErrorFast, 15);
	Serial.print("and occurred when computing qsqrtf(");
	Serial.print(randomNumber[maxErrorIndex], 15); Serial.println(").");
	
	Serial.print("normal sqrt was "); Serial.print(float(sqrtfTime) / float(qsqrtfTime), 4);
	Serial.println(" times slower");
	
	Serial.print("End of test #"); Serial.println(test+1);
	Serial.println("");
}
  

}

void loop() {
	delay(1);
}


float qsqrtf(float x) {
	long i;
	float y;
	
	float x2 = x * 0.5f;
	y = x;
	i = * (long * ) &y;
	i  = 0x5f3759df - ( i >> 1 );
	y  = * ( float * ) &i;
	//Newton-Raphson:
	y  = y * ( 1.5f - ( x2 * y * y ) );
	return y;
}

And the serial output:
Code:
Test #1
Computing 5000 inverse square roots using the normal sqrtf() function took 36711 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18242 microseconds.
maximum absolute error with fast sqrt was: 0.000000000000000
and occurred when computing qsqrtf(4.941257953643799).
normal sqrt was 2.0124 times slower
End of test #1

Test #2
Computing 5000 inverse square roots using the normal sqrtf() function took 36710 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18234 microseconds.
maximum absolute error with fast sqrt was: 0.000000014901161
and occurred when computing qsqrtf(54.022491455078125).
normal sqrt was 2.0133 times slower
End of test #2

Test #3
Computing 5000 inverse square roots using the normal sqrtf() function took 36715 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18239 microseconds.
maximum absolute error with fast sqrt was: 0.000000003725290
and occurred when computing qsqrtf(864.105102539062500).
normal sqrt was 2.0130 times slower
End of test #3

Test #4
Computing 5000 inverse square roots using the normal sqrtf() function took 36711 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18248 microseconds.
maximum absolute error with fast sqrt was: 0.000000000000000
and occurred when computing qsqrtf(0.789928972721100).
normal sqrt was 2.0118 times slower
End of test #4

Test #5
Computing 5000 inverse square roots using the normal sqrtf() function took 36714 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18237 microseconds.
maximum absolute error with fast sqrt was: 0.000000000000000
and occurred when computing qsqrtf(1.512629985809326).
normal sqrt was 2.0132 times slower
End of test #5

Test #6
Computing 5000 inverse square roots using the normal sqrtf() function took 36714 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18237 microseconds.
maximum absolute error with fast sqrt was: 0.000000003725290
and occurred when computing qsqrtf(300.916290283203125).
normal sqrt was 2.0132 times slower
End of test #6

Test #7
Computing 5000 inverse square roots using the normal sqrtf() function took 36705 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18233 microseconds.
maximum absolute error with fast sqrt was: 0.000000007450581
and occurred when computing qsqrtf(75.223937988281250).
normal sqrt was 2.0131 times slower
End of test #7

Test #8
Computing 5000 inverse square roots using the normal sqrtf() function took 36708 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18241 microseconds.
maximum absolute error with fast sqrt was: 0.000000014901161
and occurred when computing qsqrtf(18.799392700195312).
normal sqrt was 2.0124 times slower
End of test #8

Test #9
Computing 5000 inverse square roots using the normal sqrtf() function took 36717 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18229 microseconds.
maximum absolute error with fast sqrt was: 0.000000029802322
and occurred when computing qsqrtf(4.698485851287842).
normal sqrt was 2.0142 times slower
End of test #9

Test #10
Computing 5000 inverse square roots using the normal sqrtf() function took 36713 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 18242 microseconds.
maximum absolute error with fast sqrt was: 0.000000003725290
and occurred when computing qsqrtf(300.983123779296875).
normal sqrt was 2.0126 times slower
End of test #10
 
I just revised the sketch to improve the fusion rate. I moved the accel and gyro temp fetch into the 2 Hz loop. Now the fusion runs at 780 Hz (with the Teensy at 72 MHz) when the accel is in the active state and 840 Hz when the accel enters low-power mode after 36 seconds of no activity (user configurable). I also corrected the Madgwick fusion call for the actual alignment of the prop shield sensors and changed the Euler angles for the heading reads from 0 to 360 like a compass. I also changed the order of the bias calibrations so the accel, then gyro and lastly mag are calibrated since the two former require no motion and the latter requires figure-eight motion. Everything should be working properly now.
 
I'd like to make the case for this faster 1/sqrtf() implementation again.

I tried this (and updated the gihub repository with it), but it didn't change the fusion rate so even if it is much faster, it is not the rate limiting step...
 
Last edited:
Hi,

I've tried the Audio Amp with the code Below, and can't get any sound out of the amplifier. I've got a signal from the DAC if I connect directly just no sound from the prop board.

Could someone else try the code please see if you get some sound from the board?

Code:
#include <Audio.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=180,469
AudioOutputAnalog        dac1;           //xy=380,468
AudioConnection          patchCord1(sine1, dac1);
// GUItool: end automatically generated code

int freq = 1100;

void setup() {
	Serial.begin(115200);
	while (!Serial);
	Serial.println("Setting up");
	pinMode(5, OUTPUT);
	digitalWrite(5, 1);//Enable Amplified.
	AudioMemory(12);
	sine1.amplitude(1.0);
	sine1.frequency(1000);
	Serial.println("Send Serial Char to increase freq");
}

void loop()
{
	if (Serial.available()) {
		Serial.read();
		sine1.frequency(freq);
		Serial.println(freq);
		freq += 100;
	}
}
 
Hi,

I've tried the Audio Amp with the code Below, and can't get any sound out of the amplifier. I've got a signal from the DAC if I connect directly just no sound from the prop board.

Could someone else try the code please see if you get some sound from the board?

Yes, I can and did try it, CODE worked as copied from post 129. 8ohm 0.5W speaker makes tone on both: GND to DAC and USB end across AMP:: - and +.

<edit> Also tried Talkie lib and it worked.
 
Last edited:
I tried this (and updated the gihub repository with it), but it didn't change the fusion rate so even if it is much faster, it is not the rate limiting step...
Ok, thanks for testing this. If there is no improvement I suggest reverting to normal sqrtf() to get the full float accuracy.
-Ben
 
I'd like to make the case for this faster 1/sqrtf() implementation again.
It's twice as fast. Worst case error I found so far was better than 0.00005 absolute.

-Ben

I thought I would compare your qsqrtf() with cortex M4F hardware SQRT (think teensy 3++) on MK64F @120MHz (albeit MBED with different compiler), here are the numbers for 5000 reps

Code:
      sqrtf took 1647 us
      qsqrtf took 917 us
      qsqrtf error 1.86265e-09
      sqrtf 1.796074 slower

and on a 180Mhz Cortex M4F (not freescale )
        sqrtf took 1090 us
        qsqrtf took 634 us
        qsqrtf error 1.86265e-09
        sqrtf 1.719243 slower
The hardware manual says SQRT and divide each take 14 cycles, so your qsqrtf() is faster than the hardware SQRT.

EDIT: By comparison, sqrtf() on teesy 3.1 @120MHz took 32358us, so this shows the speedup from the MK64F's hardware floating point

NOTE: mbed MK64F has on-board FXOS8700Q
 
Last edited:
I thought I would compare your qsqrtf() with cortex MF4 hardware SQRT (think teensy 3++) on MK64F @120MHz (albeit MBED with different compiler), here are the numbers for 5000 reps

Code:
      sqrtf took 1647 us
      qsqrtf took 917 us
      qsqrtf error 1.86265e-09
      sqrtf 1.796074 slower

and on a 180Mhz Cortex M4F (not freescale )
        sqrtf took 1090 us
        qsqrtf took 634 us
        qsqrtf error 1.86265e-09
        sqrtf 1.719243 slower
The hardware manual says SQRT and divide each take 14 cycles, so your qsqrtf() is faster than the hardware SQRT.

But the strange thing is that the teensy 120mhz times are so much slower than mbed ??? 5000*28/120mhz should be about 1166us, about what the mbed results show. But teensy sketch shows

Code:
Computing 5000 inverse square roots using the normal sqrtf() function took 32351 microseconds.
Computing 5000 inverse square roots using the  fast qsqrtf() function took 17610 microseconds.

I'm still trying to figure that out ....?

Compiler switches/config enabling hardware FP? Perhaps Arduino or Teensy defaults don't tell compiler to use hardware FP?
Or you have to declare floats as type single rather than double since the ARM FP is single precision.
 
Compiler switches/config enabling hardware FP? Perhaps Arduino or Teensy defaults don't tell compiler to use hardware FP?
Or you have to declare floats as type single rather than double since the ARM FP is single precision.

Right now, since the current Teensy's do not have hardware floating point. If you use the Teensy setup, floating point is always done via emulation. In the future, when the next generation of Teensy comes out, it will have single precision floating point in the hardware, but any use of double precision is done by emulation. So to pave the way for this, it is a good habit to use float instead of double, use single precision math functions (i.e. sqrtf instead of sqrt), and add a 'f' suffix to all floating point constants. I know Paul adds the switch to make constants single precision by default (which has its own set of issues if you really need the higher precision), but it is a good habit to get into to be type correct, in case your code is moved to a different system.
 
Compiler switches/config enabling hardware FP? Perhaps Arduino or Teensy defaults don't tell compiler to use hardware FP?
Or you have to declare floats as type single rather than double since the ARM FP is single precision.

Ooops, I was operating in a fog as usual. The fast MK64F times show the speedup from the Cortex M4F hardware floating point. (I edited my previous post.)
 
As another "teensy 3++" comparison here are times for single call to MadgwickQuaternionUpdate() from
https://github.com/kriswiner/Teensy_Prop_Shield using invSqrt()

teensy 3.2@120MHz 216us
MBED MK64F @120MHz 8us (Cortex M4F hardware floating point)
MBED F446RE @180MHz 5us (Cortex M4F hardware floating point, not freescale)

Mahony: teensy 133us, MK64F 5us

Paul's NXPMotionSense
kalman fusion: teensy 3648us, MK64F 468us
 
Last edited:
Prop shield use cases and examples

As I think about the prop shield, what is needed to help make it a success is examples to help people put the pieces together. So off of the top of my head, some examples might be:

Doing something with persistence of vision (poi) using a simple string of APA102 lights, such as http://orchardelica.com/wp/?page_id=597 redone with the shield (and hopefully at some point FASTled using the SPI hardware).

Something with the compass, such as this 3d compass: https://github.com/jrleeman/3DCompass/blob/master/README.md.

Play sounds stored in flash memory. However to do this, you need to be able to download sounds to the flash memory (such as the zmodem thread that went by a few days ago). For zmodem, you probably want to refashion it as a library, to include in other things, but given it uses a lot program memory, we may be stuck having to flash the zmodem downloader, do the downloads, and then reflash the main program. It might be better if somebody used to hacking USB and filesystems, adds a rudimentary USB external disk support. However nice that is, I suspect it is a lot of work.

Similarly using the prop shield for a simple data logger, that can upload its data when connected to a computer (perhaps acting as a USB keyboard, and spitting out logs as text files).
 
As I think about the prop shield, what is needed to help make it a success is examples to help people put the pieces together.

I agree. The additional hardware required to experience these examples should be kept to a minimum and should in general only consist of stuff you'd connect to the Prop Shield anyway, like APA102s and a small speaker (or headphones). A simplified version of Mortonkopf's Pixel Poi is a good idea, the 3D-Compass IMHO not so much as it requires NeoPixel Rings which use WS2811 instead of APA102 LEDs and requires you to arrange the LEDs in this specific pattern, which means basically you must have two of the NeoPixel Rings or you must brew your own PCB.

Examples can be educational without being complex by just showing certain features of the prop shield and the associated libraries. A talking compass (with talkie lib) might be worth considering. Or a audio playback example that maps a 3-channel equalizer (lows, mids, highs) to the 3 axis of orientation of the prop shield. These are not much more than simple update loops in the arduino sketch, yet IMHO entertaining and educational.
-Ben
 
A 3D compass example without any addional hardware could work as follows:

  • Direction printed to the console whenever the bearing changes by greater than 1 steradian or so
  • LED 13 blinks faster the closer the bearing is to magnetic north
 
I am looking forward to playing. I should just start doing so, but currently in the process of debugging my own new board, also was waiting for my order from Adafruit with some APA102s (1 meter of 60per...) was tempted to get the 8x8 grid (https://www.adafruit.com/products/2734), as this might be fun with this board.

Will also be interesting to see how well these IMU components work as compared with the board I am playing with, which is setup to install a BNO055 IMU.

Now back to play!
 
As I think about the prop shield, what is needed to help make it a success is examples to help people put the pieces together. So off of the top of my head, some examples might be:
...
Similarly using the prop shield for a simple data logger, that can upload its data when connected to a computer (perhaps acting as a USB keyboard, and spitting out logs as text files).

More samples would be cool - if only there were a Wiki. It would be Nice if there were a link for common expendables: Suitable speaker - a headphone jack that could go on - is the $20 DotStar really the cheapest strip to get a few LED's?

As noted above I tried Talkie - watching the speaker while sounds played got really boring, even that cool two minute Diner song . . . I posted here Talkie-speech-library about making a non-blocking version of Talkie.

Frank may like this - I just took my Interrupt driven non-blocking TALKIE library and made a sample playing the 2 minute song: PropTomsDinerInt

It is set to work with the Prop Shield - with the linked Altered Library from GitHub.

Having good data logging Examples to access the Flash would be cool. Would be a challenge to feed Talkie from data stored there - have to buffer through local RAM - to not let it boundary cross or run out any single sound set would have to be cached locally.
 
Last edited:
another Prop Shield arrived

Just wanted to report the Prop Shield Beta arrived here! Only had a few minutes so far, but Paul's "RawData" code at https://github.com/PaulStoffregen/NXPMotionSense shows signs of life; it looks like it sends about 100 readings per second. Looks to me like ax,ay,az are always multiples of 4, in other words the two LSBs are always 0 ?
Swinging around on USB cord:
Code:
ax, ay, az, gx, gy, gz, mx, my, mz
-27624,1748,14344,-11619,13526,8754,515,328,742
-26820,680,14308,-12082,11813,11169,499,257,825
-26180,-572,13940,-12681,9350,13410,467,167,886
-25692,-1672,13084,-13400,6141,15159,426,67,908
-25132,-2472,11896,-13993,2449,16067,377,-54,923
-24756,-3016,10472,-14259,-1500,15982,330,-148,875
-24820,-3564,8964,-14035,-5385,14831,274,-219,810
-25856,-3772,7564,-13383,-8799,12645,201,-250,719
-28128,-3384,6376,-12523,-11457,9674,143,-277,646
-31280,-2436,5804,-11626,-13244,6438,84,-267,562
-32768,-1376,5596,-11040,-14320,3400,52,-254,524
-32768,-184,5372,-10843,-14882,633,5,-224,465
-32768,988,5060,-10634,-14981,-1950,-29,-190,434
-32768,1928,4676,-10003,-14705,-4345,-57,-160,401
-32768,2544,4292,-8958,-14209,-6453,-82,-139,387
-32768,2932,3956,-7883,-13523,-8209,-109,-119,375
-32768,3368,3592,-7210,-12698,-9628,-122,-103,371
-32768,3960,3104,-7031,-11690,-10733,-126,-71,360
-32768,4464,2384,-7084,-10467,-11538,-142,-72,367
-32768,5056,1676,-7032,-9071,-12227,-137,-59,351
-32768,5368,728,-6768,-7645,-12764,-125,-45,346
-30200,5840,-136,-6392,-6173,-13243,-130,-54,341
-26848,6016,-908,-6153,-4579,-13537,-125,-35,340
-24880,6768,-1368,-6328,-2799,-13679,-121,-33,312
-24264,7696,-364,-6853,-549,-13555,-95,-20,310
-24520,7992,844,-7581,1703,-13000,-89,-4,285
-24592,8496,1996,-8327,3868,-12399,-55,29,264
-24752,9016,3312,-8741,6116,-11830,-26,58,249
-25784,9040,5416,-8922,8436,-10995,17,90,222
-27132,8876,7736,-9407,10627,-9747,84,136,221
-28048,8648,9708,-10205,12504,-8021,143,199,204
-28344,8120,11112,-10943,13990,-5817,203,280,230
-28020,7548,11888,-11366,15070,-3289,286,349,273
-27532,6216,13044,-11400,15847,-462,353,408,353
-25592,5176,13884,-11427,15978,2439,402,448,437
-23416,4192,13820,-11525,15174,5330,452,443,554
Sitting still on desk:
Code:
ax, ay, az, gx, gy, gz, mx, my, mz
544,348,8424,-2,-3,4,168,216,286
532,344,8408,-1,0,7,158,220,284
536,348,8384,4,5,3,157,213,273
544,352,8400,-5,-1,2,156,196,272
544,348,8404,-3,1,3,168,210,285
536,336,8412,-1,1,2,182,201,289
552,348,8428,-1,-2,3,164,215,260
552,344,8404,-1,5,-1,161,217,291
544,352,8384,-10,4,-2,161,202,282
548,352,8424,-10,0,1,146,218,274
532,348,8408,-1,-3,3,162,214,285
540,340,8384,-8,1,2,160,206,290
536,364,8404,-2,0,1,156,198,301
532,360,8408,0,0,5,142,219,279
552,356,8408,-3,1,4,163,218,280
532,364,8416,0,1,-2,152,202,289
540,336,8400,-3,-1,2,151,208,301
532,360,8388,-5,-5,2,154,196,294
540,344,8400,-2,1,1,169,210,278
544,344,8380,-2,3,4,166,203,289
544,344,8400,-1,4,0,159,215,282
524,352,8404,-5,5,-4,166,211,275

trying to get ax,ay near zero (level):
Code:
4,40,8412,-4,7,0,196,277,313
4,48,8400,-12,9,4,202,286,328
-16,24,8436,-8,7,0,199,294,335
-4,24,8424,9,3,0,206,285,324
-16,20,8432,2,-1,-2,201,288,327
0,16,8420,-4,-2,-7,193,290,328
4,32,8428,3,-1,-11,195,293,333
4,44,8396,8,-4,-13,201,287,322
4,80,8436,-18,-2,-15,192,288,329
4,40,8444,-25,4,-6,200,286,319
-16,48,8388,-12,-3,0,197,293,312
4,48,8396,-3,-2,-6,191,286,326
28,4,8420,4,0,-2,188,285,324
-4,52,8432,11,5,0,211,290,317
 
Last edited:
@Ben
I'd like to make the case for this faster 1/sqrtf() implementation again.

I made a mistake in testing this by changing the Mahony algorithm but not the Madgwick, which I am calling in the sketch. So, here is the comparison:

Method sensor fusion rate
sqrt 730 Hz
sqrtf 780 Hz
InvSqrt 815 Hz

the InvSqrt is indeed faster using the Madgwick algorithm (and i suspect the Mahony too) and is worth the effort. This was with the Teensy running at 72 Mhz.
 
just starting on the shield. ran erase everything, all good:
Flash Memory has 8388608 bytes.
Erasing ALL Flash Memory:
estimated wait: 20 seconds.
Yes, full chip erase is SLOW!
....................
Erase completed
actual wait: 24 seconds.

and then raw hardware test:
Raw SerialFlash Hardware Test

Read Chip Identification:
JEDEC ID: EF 40 17
Part Nummber: W25Q64FV
Memory Size: 8388608 bytes
Block Size: 65536 bytes

Reading Chip...

Writing 4096 signatures

Double Checking All Signatures:
all 4096 signatures read ok

Checking Signature Pairs
all 2047 signature pairs read ok

Checking Read-While-Write (Program Suspend)
write 256 bytes at 256
write time was 450 microseconds.
read-while-writing: 00 00 00 00 15 F5 95 4B
test passed, good read while writing

Checking Read-While-Erase (Erase Suspend)
erase time was 187406 microseconds.
erase correctly erased 65536 bytes
read-while-erasing: 00 00 00 00 15 F5 95 4B
test passed, good read while erasing

All Tests Passed :)

Test data was written to your chip. You must run
EraseEverything before using this chip for files.
Will try and get on to using flash with POV APA102 this week.
 
Last edited:
Testing the NXPmotionsense with ws2811 led string, using as a tilt indicator. working well with FastLED test strip using simple cutoff values of -/+1500 in ax and ay directions

vid with micro controller hidden https://youtu.be/r2bdu4xeJmM
(hope that this is not against no showing of board rules)
 
Last edited:
@onehorse & defragster - I'm looking at the quaternonFilters file. The Madgwick look the same as this Arduino library (which happens to have the infamous Carmack WTF inverse sqrt optimization). Is there any reference for the source of the Mahony algorithm? Is it open source?

If Mahony is open source, I'd like to package it up into a similar library with the same API. I'm also working towards doing the same with Freescale's filter... but that's going to take me another day or two, since their code is very complicated.
 
I've updated the NXPMotionSense library with an API very similar to Arduino's for Curie's IMU. This is intended to become the primary library for using the Prop Shield, so I'd like to ask everyone to please give it a try. Of course, comparisons against other code are always welcome.

The library has 2 examples so far. MadgwickIMU runs the sensor and Madgwick filter, printing roll/pitch/yaw. It works with the Processing visualization program on Arduino's page.

The other example is CalibrateMagnetometer (formerly named RawData). It's meant to be run with an OpenGL-based GUI I've been developing. The GUI requires wxWidgets (which is a pain to set up with OpenGL support). On Linux, there's a non-wxWidgets command line program, which opens up another blank window for the OpenGL graphics. If anyone wants to give this a try, use "make imuread" to build only the command line version. If your Teensy isn't /dev/ttyACM0, edit the port name in imuread.h.

The GUI collects and shows hundreds of magnetometer readings. As you move the Teensy, it collects more and update the calibration. As you get a good calibration, you'll see the points form a nice sphere. When you're happy with the shape, press any key in the graphics window and it'll transmit the hard+soft iron calibration to Teensy, where it's stored in EEPROM. NXPMotionSense automatically reads the EEPROM and applied the calibration when you read the magnetometer as floating point. Results are reported in uTesla units.

Later today I'm going to add some bare necessities to the wxWidgets version (like being able to select the serial port, and a button to send the cal) and get Windows and Mac versions for you.

This is my first ever OpenGL program. I really need your help getting it tested on different versions of the operating systems and a variety of computers, especially with different graphics cards!
 
Last edited:
Status
Not open for further replies.
Back
Top