OK, we are going to talk about IMU's and GPS modules in detail here. I had a really hard time researching, compiling information and designing/testing solutions using GPS and IMU, so I want to capture what I found out here for your edification.What Cheezes Me
It seems that as time goes on and we as a maker culture become more and more sophisticated that we tend to make the same mistakes as they very organizations and institutions we are (intellectually) critical of. What I mean by this is that with the proliferation of Youtube videos and web sites devoted to making that a lot of them are either (1) to encapsulated and/or (2) way to vanilla-y (heavy on the handholding, light on the information).My Take On It
While I love PYTHON (and other maker environments) I think a deviation, at least for the intermediate to expert-level makers is called for to more generalized development environments. An issue with using Arduino and PYTHON is that after a while you are just as in love with it as a developer using VB.NET.
Because of this I like to drive my "master reference" to C (more specifically academic ANSI C....procedural) so from there I kind of internally "translate" (port?) my thinking to whatever language or environment I'm actually using.What we are asking for and what we are "being told"
We need to be continually driving to the purity of the maker experience as this encroachment phenomenon is insidious. Now before this turns into a manifesto instead of a passive observation, I'll get into the meat of it.
What we have been asking for is: I want the GPS coordinates as a float/double in my particular development environment. While I do appreciate being exposed to various libraries, IDE's and tools, I JUST NEED TO KNOW HOW TO DO IT. Please, I just need that set of 3 x 3 numbers, and even just a latitude/longitude/altitude in my program is ALL I need.
However what we are told is that (1) its difficult (which it isn't once its been explained) or (2) not so sure I should tell you (which they should) or (3) I know just about as much as you do and I don't have the time to do the leg work on this one. Ouch!A Real Example
This project will leave you with a completed "test rig" that has a properly mounted IMU module (and GPS module) that gives you the 9 numbers you are looking for from an IMU, and the 3 numbers you are looking for from a GPS module.
We are going to be talking about anything and everything that pertains DIRECTLY to the streamlined task of how to obtain these magic numbers for use in your projects.IMU's: a little theory
OK, part of what is mystifying you about IMU's is their differences. Let's talk about how IMU's work internally.
Their core feature is the sensor itself. It is the sensor that, at its root, is the obtainer of the magic numbers hence why we are talking about them. The kind of IMU's I'm talking about are the hobby and drone type that you might see on Adafruit or EBay btw.
In the early days, when you managed to procure an inertial sensor, for example an old ADXL150 (a single axis accelerometer chip) or a Murata Piezo Gyro their output from their pins was voltage, the range 0 (lowest value) to 5VDC (highest value) being typical.
To use realistically, you would need an analog, or preferably a digital, network with which to condition and read/utilize their output. For the purposes of this project, we will assume a:
sensor=>ADC=>internal MCU=>serial interface
type set up. What is throwing you here is that NOT all IMU's are set up this way (light goes off in one's head). "Oh so this is what they have been trying to keep from me" Yes, oh yes lol :D
For example, a very nice board at a reasonable price of let's say $55 USD at Adafruit or wherever might seem to you to be a logical place to start. How about if we talk about this for a moment before you buy?
If you take a close look at the board you might notice that they have merely mounted the voltage-output sensors (because even the more sophisticated boards use this methodology internally) with maybe some signal-conditioning discretes added. The value-added here is that you have a SOIC (ie. an SMD) chip that you can now access easily its pins (ie. DIP). However this is a tiny portion of the total task to get those majick 12 numbers (acc/gyro/mag/gps)Important Tip: Select the RIGHT board first
If you understand what these boards are about, then you can buy a board that has the most of those fiddly, tedious steps already incorporated into the board. Not all boards do.
"OK, so a lot of these boards just output a voltage" Yes, and you'll spend months or years doing those very things that the experts wave their hands at and say "a trivial exersize in electrical engineering".that interestingly enough takes most of them similar amounts of time to mess around with too.
If you WANT to mess with I2C and external ADC's and PRU's then do it their way, however if you just need those magick 12 numbers in .NET or on a Beagleboard Black then read on.Important Tip: Don't get to hot a board
Interestingly, there are a few board out there with something called "attitude engines" on them that I would keep away from because of their unique ability to extend hospitality to agents of the US Government, the KAUFMAN being one of them. If you try to buy one of these off of EBay or somewhere, you will get a warning from them that you might be in contravention of law even buying one of these boards (but still offered for next to nothing from Hong Kong or somewhere).
You don't need a board this hot, so don't bother.
The reason for this is the firmware on them is so advanced that it implements a large amount of the circuitry necessary to building an actual military-grade item.Let's talk about boards...
A nice board is an MPU-6050. Problem is the interface. Its only I2C. A lot of other boards only have SPI (SPI isn't serial technically btw). However, a nice board if you have like an Arduino MEGA or something.
To evaluate the difference between these boards, a good place to start is the DOF number on them. To quickly cover what 1DOF or 6 or 9-DOF is, its how many axis or "degrees of freedom" the board will measure. Technically with an IMU there are physically (maximum) 6 DOF's (x,y,z acceleration and x,y,z rotational angle) but on a 9DOF board the gyro's x,y, and z angles are "overloaded" with identical angles supplied by measuring the earth's magnetic field such that a redundant set of three x,y,z angles are returned that can be cross-correlated with the gyro angles.
Another important issue you NEED to take into consideration is their operating voltage. Most of the stuff these days is 3.3VDC and you WILL fry them trying to supply them the more traditional 5VDC (TTL - transister-tranister-logic) voltage level. These days I exclusively use single-channel optoisolators to step-up and step down voltages with dissimilar levels (ie. between a PIC at 5V and an IMU board at 3.3V typically).ESD Procedures
Something that is not talked about often enough is ESD procedures. With the proliferation of MCU's buried in regular circuits, you have to, in my opinion, treat every component or discrete as if it was a naked microprocessor. The easiest way to do this is to pop a short piece of solder into the ground rail of your rig and every time you get up and walk around just rub a finger across it. Some people just get in the habit of touching the USB housing on their SBC or whatever everytime they walk around and come back.The board I settled on...
For the purposes of this project, which is to connect an IMU to your Windows 10 PC (which doesn't natively have an I2C port or an SPI port) a common board that can talk something called TTL-serial (which is different from RS-232 serial, but directly translatable) is the ArduIMU aka the "Razor" IMU board.
How you tell that you have this board is you do a search on ATmega328 (the overseeing MCU for this board) and its usually the one I'm talking about here.
For example this one here is perfect: ArduIMU/RazorCompleting the Hardware for the Project
You will have to buy something called a TTL-serial-to-RS232 converter which is a generic item on Ebay that has a lot of uses and goes for about $5, free shipping (as of the time of this writing). You can wire with telephone wire if you desire (real telephone wire, not telephone extension wire....solid core copper). While you are at EBay or wherever pick up an inexpensive breadboard or two, and some LED's and some 1K resistors, and some optoisolators (an LTV-816 is a nice one...try mouser.com) .Project Prep
Check the schematics section on how to set up the converter. Hooked up lengths of wire to the terminals on it long enough so you can perch you breadboard near the front of your PC. Put a little tape with the words "gnd", "vdd","tx" and "rx" on the exposed ends it so you keep the wires straight.Important Tip
OK, here is the counter-intuitive part. Guess what...you have to power the converter. "You're kidding me, why doesn't it just power out of the serial? That's how serial works...right?" Not in this case. Find a wall transformer or something to send 5VDC down that line (the Vdd, or Vin) back to the PC. lol I'm serious....threw me for a little bit. But like anything I say, double check what I say.
To prep the Razor (aka the ArduIMU), solder on the 0.1 header onto the pins so you can easily insert it into the breadboard. Now REMEMBER, that a Razor is 3.3VDC so you'll need another wall transformer (or equivalent 3.3VDC supply) for it.Wiring it Up
Check the schematic for how to hook it up. Basically you insert the Razor into your breadboard and hook it up to 3.3VDC power. If it starts flashing after a few moments, then you know its good (AND actually transmitting the numbers you need). (Ummm, in case you've never used a breadboard before you should look up and read how they work... I remember when I was young that I thought it was counterintutive...its not like perf board).
The dicey part here is keeping your 5V away from your 3.3V (and visa versa). If you just hook it up exactly like in the schematics, it will work the first time. If it doesn't you have something like a 3.3V converter and just some good old fashioned logic will get it sorted out in a few minutes.
What you have to do is pass the Razor's TX (its serial transmit line) and its RX (its serial receive line) to the converter plug through two optoisolators (one for each line). To refresh your memory, the signal goes in through the LED side and the signal comes out the phototransistor side. Drive them "high-side", that's why the phototransistor's drain is connected to the serial line (make a note of this: all of your voltage zones have their ground in common... it's their positive voltages that are different).
Remember that TX goes to RX and RX to TX (to remember, you speak into someone's ear and you listen to their mouth).What are the LEDs for?
You don't need an O-scope for this project. The IMU transmits often enough that with the help of a few 20-cent LED you can see the difference between it transmitting and not transmitting. Makes troubleshooting as easy as falling off a log. Its very bright when not transmitting, and dim when transmitting.
"Are you sure about that?" (Patronizingly) I am, thank you. It has to do with TTL serial that to retain compatibility with RS-232 that it has to be driven high (i.e. its "start" bit) most of the time. Ergo, when its transmitting, it is dim. When its not connected right, its off, and when it is hooked up right AND not transmitting, its bright red.
Don't forget to get a $5 harbor freight DMM as you might have to check some levels (volts, milliamps) here and there.Oh nowhere near done yet!
OK we have the hardware together, but that's only half the job. We need to get the software up. Because I'm taking a generic approach here, we're going to use VB6 (a legacy version of VB.NET) to show how you (1) receive the IMU's data stream and (just as importantly) (2) decode it. BY "decoding" I mean how you take that gobbly gook and parse out those magic numbers into program variables (which is where we need it for out little projects).
VB6 uses a "custom control" called an mscomm control to do its serial communication (i.e. COM1, COM2, COM3). So make a new project, drop in a form and a mscomm control (add it via References) on that form. Also put a large multiline textbox and a button on it. Change the button's caption to "Open Port" and cut and paste the VB6 code from the code section of this tutorial into the code of the form. As long as you don't change any of the control's default names, you should be good.
But since this is about understanding how to do it, go over the code over and over again and figure out exactly how works. Its only a few lines.What the program does...
All the program does is display bytes coming in on the PC's serial port. The only high-speed thing it does is decode the data stream pulling out the required 3 or 6 or 9 numbers and putting them in variables for use.
So run it and if you have everything hooked up correctly you will see the little boxes fill up with the information you want, in the form you want: program variables.
Turn your breadboard around, upside down and stuff and you'll notice the numbers change a lot.Conclusions
End of Project. Congratulations!
Addendum: "How do I get serial coms on my UNIX SBC (i.e. R-Pi, Beagleboard)?"
A: Let's talk UNIX and C for a bit. Serial communication is done quite a bit differently there than in let's say Windows. Your serial port is abstracted as a stream in UNIX, and therefore can be manipulated just like reading to and from an open file. So to access the serial port in UNIX you must first open the stream, a la:
To read a byte from the port you just go:
To write a byte to the port you just go:
where "c" is variable of type char (ie. an 8-bit byte). And, of course, remember to formally close the stream when finished with:
Just check the man pages for those stream functions you can use; a few of them don't work as in they don't have any application to serial communication (for example, fseek doesn't make any sense for a serial port because the data isn't stored on in a permanent medium where it can be traversed like that).
Addendum: "OK, that's nice and all, but how do I realistically get my SBC to do it?"
You will find the previous explanation works perfectly on UNIX PC's, however the SBC's that are out there are so horribly configurable and powerful that you have to do their their particular procedure to set up their GPIO pins such that the UART's are selected and exposed through the header.
I understand this is a major maker issue right now is the plea for THE way to do this on a particular small-board computer. However once you successfully configure and test the UART's it is accessed as explained as above.