Showing posts with label Custom Hardware. Show all posts
Showing posts with label Custom Hardware. Show all posts

Saturday, July 22, 2017

Today's Episode of "It's my responsibility, but..."

"...The datasheet diagrams didn't have the pins labeled."

This time, it is the encoder board.


Here, it isn't obvious which pad in the footprint goes with which pad on the part.

It doesn't matter anyway, because a closer examination of the footprint and the Digikey list of optical sensors reveals that I bought the wrong part. The footprint on the board is marked QRE1113, but it is actually for an Omron EE-SY193. D'oh!


Well, back to the fab again, for both boards. I'll use the QRE1113 parts that I have to test if the parts even fit in the hole. If not, I'll have to use the EE-SY193.

All parts of this project are my responsibility. It can't be otherwise, since there isn't anyone I report to or who reports to me. My partner is a special case.

Friday, July 21, 2017

Dagnabbit!

That beautiful purple board I received yesterday won't work. If it had been stuffed and plugged in, it would have immediately shorted out anything plugged into it.

One of the features on the board is a super-wide (for a 6-mil PCB) strap between the two adjacent 5V pins coming from the Pi. When I had a close look at it, I saw a thin little gold crescent around part of the hole. It took a little bit for it to dawn on me that this was the ground plane, which was visible through the mask, plated in gold, and not protected from shorting with the other contacts:
 The effect is everywhere on the board. I saw it first on the strap in the upper-left, but this magnified version shows it on the motor power section and connection to the Arduino. Note the crescents around the top of D3~ and RST, and the slivers of ground plane visible through the mask around the isolator footprint.

I don't think that there is anything that can be done to fix it. I also don't think that the encoder board is affected, so at least I can still use that. I'll try to stuff it, but I will check continuity closely. If any of the solder bridges the 6mil gap, then the short will exist.

I'm pretty sure the problem comes from settings in the ground plane. Since OSHPark can make 6mil boards, I take full advantage of the feature. Unfortunately, this interacts with a bad default in Kicad. Fortunately, that is easy to change, but it would have been nice to know fifteen dollars and two week ago. The money isn't a big deal, it's the time.

Kicad was even trying to tell me that something bad was about to happen. Not from the DRC (although that would have been nice) but in the images. Here is the old, bad design:

The purple rings around the pads are the soldermask gap. You can see a slight red tinge around the edge where the mask gap overlaps the ground plane.
The OpenGL preview shows it too, perhaps in an easier-to-understand form.

To fix it, use the Dimensions/Pads Mask Clearance menu option

Change the Solder mask clearance value from its default... (Yes, I design my boards in US units. You got a problem with that?)

Change it to zero.

The borders of all the pads are now black, indicating the solder mask gap doesn't span the space between the pad and the ground plane




 This option has settings in several places: The global setting I talk about above, the zone setting (which I haven't found), the footprint setting, and the individual pad setting. The later settings in the list have priority over the earlier ones, but the earlier ones are used as defaults.

In general with modern fab processes, you should set this value to zero. This will describe a hole in the solder mask the exact size of the pad. The fab can and will edit this to match their process, so don't worry about getting it too small.

Thanks to a YouTube video by My 2uF for help finding this setting.



Saturday, August 6, 2016

August 20 progress passed!

Yesterday Yukari 4 passed the August 20 progress verification point. A whole 15 days early, too. Here is video proof:


Thursday, July 28, 2016

St Kwan's Is Expanding

We would like to welcome Kirktopode to the St Kwan's Family! He has the goal to enter the embedded electronics field, and I have the goal of completing the robot without going crazy. We are perfect for each other!

Also, all of the robot code and design stuff is now on Github. Kirktopode is holding the master version, and I have a fork of it. I am using another one of my projects to hold the wiki in which I am documenting things in English.

Sunday, July 24, 2016

Robodometer

Last year I tried to implement a wheel encoder in between heats and failed. The ambient light was just too bright. So this time I am building the wheel encoder into the gearbox. I took the spare gearbox apart to see what the best way to do it is. Inside the casing is a differential gear in the form of a cylinder with gear teeth around the outside and the differential gears inside. The cylinder is sealed, held together with 4 screws. But, the outside of the cylinder is perfect for my design. The gearbox cover plate in that part of the gearbox is relatively easy to remove, and in just the right spot. If a hole is drilled through that plateau optical sensor can be set up to look through the hole and read the half of the differential cylinder face which is painted white. Two such sensors can be used to mak single-track quadrature encoder, which can tell whether the wheel is turning forward or reverse.

I have a pair of QRF1114 sensors specifically designed and obtained for this purpose. This part is basically just an infrared LED and an infrared phototransistor in the same case. It isn't directly useful as-is, but I combined it with a few resistors and made a three-terminal analog device.





Friday, February 12, 2016

Getting on board the LPC4078

A few things make the LPC4078 dramatically different from the LPC2148 that I am used to:

  1. This is a Cortex-M4, with a much different interrupt and reset vector table. Instead of a set of ldr pc,[pc,#24] instructions followed by addresses 24 bytes later, we have just a table of addresses. The first one is the value to put into the stack pointer upon reset (so there is no required stack setup code) and the second one is the value to put in PC on reset. Subsequent values include exception and interrupt handler addresses.
  2. As with the 2148, there is a bootstrap program. On reset, the bootstrap vector table is mapped to 0x00000000, rather than the more obvious solution of having the reset value of the vector table address register point at the bootstrap.
One of the ugly things about my old LPC2148 is that much of it was Not Invented Here. Since this is a hobby project, I can use as much of my time to do whatever I feel like, including reinvent wheels! So, I get to figure out how to start up a Cortex-M4 from scratch.

I'm not there yet.

I haven't gotten my code to run directly yet, so there is still a problem with my vector table. But, I can get my code to run with the help of the ISP, after some experimentation.

The ISP maps a total of 512 (0x200) bytes of memory as its vector table. This is room for 128 vectors, while the actual number of vectors it uses is only 7. I can tell because the reset vector points at what would be in slot 7. In any case, this code is mapped to address 0 at startup. When I was using the ISP to launch my code, I originally had only exactly enough memory reserved to hold my table, and my code started immediately after, at address 0xE4 as it happened. Well, that code was covered up by the bootstrap. After rearranging my program so that a full 512 bytes was allocated for the table, things worked much better.

Also, the ISP uses an autobaud feature when it sets up the serial port. You send a question mark, and it times the bits on that to set up thebaud rate registers. However, the ISP uses a feature I don't, and that is the fractional baud rate register. This is able to tune the baud rate at a relatively fine grain to between 1x and 2x the rate called for by the coarse baud rate registers. When the ISP is used to kick off my code, my code sets the coarse baud rate, but didn't touch the fractional baud rate register, which was left at about 1.5 . Therefore the part was programmed to talk at the wrong rate by 50%, out of tolerance for the serial port. The FT232 could tell that the part was talking, but couldn't understand any of it.

With those two things taken care of, I can now start my code with the ISP, from the very beginning of my code. Next step is to see what I am doing wrong such that my code doesn't start itself.

Tuesday, February 9, 2016

LPC4078 operational

I am continuing my project of doing robot stuff with a buddget of zero, plus the stuff on my bench. Well, the stuff on my bench includes a Loginator2368 purple board, and a box of LPC4078 Cortex-M4 microcontrollers. Those controllers happen to be pin-compatible with the LPC2368 the board was designed for. In this case that means that all the power pins have the same jobs and voltage levels (even if they have different names and perhaps different internal connections), all the special pins like reset are in the same place, and all the GPIO pins have the same numbers, and where the 2368 and 4078 have the same peripherals, they have compatible pin assignments.

One thing that the 4078 has that the 2148 doesn't is internal pullup resistors. I can take advantage of these to reduce the part count in several places.

Therefore I got out my soldering iron and finally attached the board and LPC4078. I was trying to figure out what was the minimum amount of components I could get away with, since I can't find my solder paste stencil for this board, and would have to manually solder everything. I decided to skip the power section, so no external battery or regulator. I skipped the USB section, the LEDs, and the voltage reference. I also skipped the crystal, since the part has an internal RC oscillator which is good enough for now. I even skipped all of the bypass caps.

The only part that it looked like I absolutely needed was the reset button, since my first read on the datasheet didn't show the reset pin as having a pullup. It turns out that it does, so, I didn't even need that. I did end up stealing a push button from another board and using it as a reset switch.

I did the normal SMD IC soldering thing. I carefully lined up the part on the board, then used a normal soldering iron and normal solder to glob all the pins on each side down, and to each other. I then used wick to clean up all the bridges. This naturally leaves the connections to the board intact. I then soldered on the reset button, more as a convenience than anything. (Next time, leave a reset terminal on the edge!) Also solder a shield 6-pin top-and-bottom connector onto the power and serial connections.

Then, hook it up to power. No smoke, the chip isn't hot, it passes the smoke test. But, I've seen this board not work before, with the LPC2368 that it was designed for. So, the real test is running the ISP.

?
Synchronized
Synchronized
OK
12000
OK 

It works!!! I had to guess at the frequency it wants, since I don't have an oscillator attached at all. The internal RC oscillator runs at 12MHz, so I put that in.

Now to massively restructure the code. A Cortex-M4 is quite a different beast than an ARM7TDMI. It has an FPU and built-in VIC instead of the VIC as a peripheral. It also doesn't use 32-bit ARM instructions, but (mostly) 16-bit Thumb2 instructions. The 4078 is also a much different part than the 2148, with a different set of registers in different places. But, probably 90% of the code can be in common, if we carefully separate the code into the part which is different and the part which is common. That's the next big adventure. Throw one switch in the Makefile and compile for a 4078 instead of 2148.

Wednesday, June 17, 2015

Operations Manual

The instructuions for the robot in its current state, which might actually work.

  1. The robot has two batteries, one for running the motors and one for running the controller. Make sure that both are charged. Use the motor battery charger to charge the motor battery. The battery may get hot during a charge, so its instructions say to charge it outside the vehicle. The controller may be charged either with the 5V/3.3V FTDI cable plugged into its jack, or with a USB MiniB plugged into the jack on the Loginator. Only do one of these, and don't try to charge with a 3.3V FTDI module.
  2. Make sure that the SD cards are in place. The Loginator card is the 16GB red/gray Sandisk card. It is a good idea to format it (backing up old data first, of course). Make sure that it has the proper CONFIG.TXT for the course. 'make format' will do both of these things. The camera card can be formatted using the menu of the camera.
  3. Set the switches as follows: SW1 (GPS TX->Loginator RX) is ON, SW2 (FTDI TX->Loginator RX) is OFF, SW3 (Boostrap mode) is ON.
  4. Make sure the GPS is in lock. You should see the red PPS light on the GPS interface blink once per second.
  5. Turn on the Loginator. You will see the light blink green or cyan, as the GPS and bootloader try and fail to talk to each other.
  6. Switch SW3 to OFF. This will boot the robot into the main firmware the next time that the controller is reset
  7. Turn on the motor power by sliding the switch forward. The green light on the ESC should blink but then stay off. If the steering is off-center, manually turn the wheels to center.
  8. Take the robot to the starting line. Approach the line from behind, and walk for several seconds in the direction the robot needs to go for the first leg. This sets the GPS heading appropriately.
  9. Set the robot on the line.
  10. Turn on the camera and start recording.
  11. At the starting signal, push the RESET button. This will boot the robot and it will take off within 2-4 seconds.
  12. When the robot comes to a halt, either due to finishing or to hitting an obstacle, turn the motor power off by sliding the switch backwards.
  13. Turn off the Loginator.
  14. Stop recording on the camera and turn it off.
  15. Remove the card, plug it into a computer, and copy the data from the card on to the host computer
  16. Use extractPacket and a spreadsheet to analyze the data. Use the NMEA files produced to drop into Google Earth for map visualization.
  17. Pull the MicroSD card from the camera and copy the results to the host.
The intended startup is slightly different:

  1. Make sure both batteries are charged as above.
  2. Make sure the SD cards are in place as above.
  3. Set the switches to SW1 ON, SW2 OFF, SW3 OFF (changed from above). We will bring the robot up into the main firmware, because it won't go until we push a button.
  4. Make sure the GPS is in lock as above.
  5. Turn on the Loginator as above. The red light for the LED should come on also, which means that the light will blink red/white. This is not an error condition - Those are indicated by a red or blue light blinking out a blink code at one second on, one second off. The robot is now recording GPS and inertial measurements, and actively sending zero throttle and steering commands.
  6. SW3 will already be off.
  7. Turn the motor on as above. It should center the steering automatically, and the drive wheels should not spin. The green light on the ESC should be steady on.
  8. Take the robot to the starting line by any route. The robot will no longer use GPS heading to initialize
  9. Set the robot so that it is pointed as accurately as possible towards the first waypoint. The robot assumes that its initial heading is towards the first waypoint, and uses that as its initial reference.
  10. Turn on the camera and start recording as above. Do this at least 5 seconds before the start of the race. Any jiggling is in principle remembered forever and incorporated int Average G, but in practice is more than 99% forgotten after 2.5 seconds.
  11. At the starting signal, push the STOP button on the Loginator or the green button. Do this quickly, since if the robot is jiggling before half a second before you push the button, the robot will incorporate that jiggling into its average G. We don't want that.
  12. When the robot stops, turn the motor off as above.
  13. Turn off the Loginator as above.
  14. Stop camera recording as above.
  15. Read the log as above.
  16. Use the analysis tools as above.
  17. Copy the camera video as above.
To burn a new program into the robot

  1. Set SW1 to OFF and SW2 to ON. Don't let both SW1 and SW2 be on at the same time.
  2. Set SW3 to ON.
  3. Plug in the FTDI cord to its jack, paying attention to the colors. The black wire is closest to the corner. Make sure there is no USB cord plugged into the Loginator USB jack.
  4. Reset the robot by pushing RESET on the Loginator. The robot should come up in bootloader mode.
  5. Use 'make program' to program the robot.

Friday, April 24, 2015

Is this a spacecraft?

This is not a pipe. (It is a picture of a pipe)
Is this a picture of a spacecraft?
I have discussed my rocketometer project on this blog in depth before. That's it, the purple board in the picture above. I think I can lay claim to it being a full-blown spacecraft.

  • It has structure. 
  • It has command/data handling. 
  • It has a science payload with multiple instruments. 
  • It has independent power - it is charged from the rocket payload, but carries its own battery and is capable of operating for the whole mission from launch through recovery. In fact, it did operate on its own power during entry and descent. From the point of view of the Rocketometer, the external power system is ground support equipment.
  • It is capable of operating in the vacuum and freefall of space. If it were magically transported into orbit, it would operate for at least a little while (it lacks thermal control). 
  • It lacks propulsion and recover, but so do many spacecraft. 

The biggest strike against it is that it was bolted inside another spacecraft. How many other systems in the rocket would I count as a spacecraft under this same definition?

The other biggest strike is that it has no telecom system. I know of spacecraft which have been flown with transmitters but no receivers, but the only spacecraft I can think of that had neither were things like Echo, Lageos, and Starshine. Do those count as spacecraft?

Note (2025-04-05) The pictured Rocketometer has two solder connections and no other connections on the pin header populated. I have two nearly identical rocketometers, but I care which one actually went to space and is the trophy. One of them has all 8 pins soldered to a pin header, while the other one has never had any pins soldered to it -- all holes are still gold and shiny. Other details like particular capacitors shifted to one side or another (like the resistor to the left of the 32kiHz crystal) match the one with pins. I therefore conclude that the one with pins is the one that flew. This one is marked "2" in yellow ink on the "back" side with the SD card slot.

Monday, December 15, 2014

The Useless Machine

Once upon a time, I accidentally designed and built an electronic circuit that turned itself off, therefore accidentally re-inventing the Useless Machine. My nephew saw a YouTube video of one, and fell in love with the concept. So I got one:

It's a quite elegant machine, in that it is completely powered off when closed, and runs on two switches, with no other logic, no ICs, no nothing. It's circuit is a DPDT toggle switch, which appears to be the "on/off" switch but is more accurately referred to as the "forward/reverse" switch. It also has a microswitch inside which trips when the arm pulls all the way in. When the switch is forward, the motor runs forward until the arm pops out, collides with the switch, and puts it into reverse. The reverse circuit switch is in series with the microswitch, so it only runs until the arm retracts completely. It's kind of an interesting logic problem: How do you arrange the switches to do what is desired?


Tuesday, September 2, 2014

Mt Evans and the amorphous project

This is the benchmark on the "top" of Mt Evans. I say "top" because there is another boulder within 20 feet which is about 3-4 feet higher, and another one within 50 feet which is 2-3 feet higher still. However, this is the one with a readable altitude (if just barely). The two devices are my phone in GPS mode, and the controller for Project Yukari, running a program called "Southwest" because I intend to take it on various flights I make around the country in the future. One of the interesting things about this recorder is that it carries a pressure and temperature sensor.

Sunday, June 22, 2014

A custom board for Yukari

The Loginator is a fine circuit. It is great at what it was designed for, logging. Even as a robot controller, it still spends a good chunk of time logging.

To really spiff it up as a robot controller, it needs a couple of things:

  • Two free PWM pins. PWM5 is AD6, so it is already free. PWM1 and 3 are also UART0, and PWM4 and 6 are also UART1. PWM2 is also part of SPI0, which talks to the SD card, but any GPIO can do the CS thing. All the other pins are already used, but I wouldn't mind parting with one of the I2C ports. In particular, I2C1 is used to talk to the 11DoF. It might make sense to switch that to I2C0, since SDA1 is also BSL. Then again, SDA1 and BSL don't interfere with each other. Another alternative is to give up AD7 or AD8, since I don't use the free pins much.
  • A GP2106 port. I have no complaints about the GP2106. It worked fine. It should have a port on the Loginator, either to interface with the existing breakout, or direct with the 1.8V parts on the Loginator board directly.
  • Perhaps rather than the 11DoF port, have the sensors directly attached.
An LPC2368 would go a long way towards fixing all of these things. It has 100 pins, so there is less overlap. Perhaps a Propeller would work too.

Wednesday, April 2, 2014

Regulator

Once again this is hooked up as indicated in the MIC5319 datasheet. I finally am using the switch right, no more useless machine (and useless transistor) for me. As it turns out, that transistor was effectively built-in to the regulator, that's what the EN input is there for. This circuit supplies a nice 3.3V output on VCC to everything else. Previous versions had a current sensor, but this one doesn't, as I haven't gotten one of those to work yet.

It isn't visible in this image, but the bottom rail is GND.

Charging Circuit

This one is a pretty straightforward hookup of the MCP73831 charging circuit, with one addition: D302 is there so that the charging circuit does not have to treat the whole device as a battery to be charged. If USB is connected, VIN will get the full 5V (minus the voltage drop of a Schottky diode). If not, the battery is used (again minus the voltage drop). Finally, both diodes need to be there so that the battery doesn't feed back to the charger input and try to charge itself. The programming resistor tells the resistor to charge the battery at a maximum of 100mA. This is 1C for a 100mAh battery, the smallest one I have and the one that flies with the Rocketometer.

The status light uses a resistor from the 1.5k pack in the USB connection.

Other versions of this circuit have had a voltage divider between VLIPO and GND so as to allow the MCU to measure the battery voltage. I haven't used it in a while, and it does draw some current, so it is gone from this circuit.

Doing USB right

AN11392 - Guidelines for full-speed USB on NXP's LPC microcontrollers (19 Feb 2014). This finally answers all my questions about what all the USB parts are. Based on it, let's review the Loginator USB/charge/power supply section.

We are now using a Micro USB connector with through-hole posts for better mechanical security and easier alignment during soldering. Micro USB takes up less board space and is compatible with the cords used for Android phone charging.

The first thing the app note says is that there must be a 33 ohm resistor on each of D+ and D-. This, plus the internal resistance of the LPC itself, add up to the 90 ohm total impedance required. It implies that there is 12 ohms on each of the pins inside the LPC. This is what I have been carrying all along from the Logomatic design.

Secondly, USB_Softconnect is required if the device is self-powered, or if it takes longer than a certain amount of time to boot up. Since my device can be self-powered and might never boot up and connect, I intend to use this as intended. However, I still like a PMOS rather than PNP transistor. The 1.5k resistor required for softconnect to work is also well-sized for the LED, so I use an array.

The signal lines have capacitors to ground, for exactly the purpose I deduced - shorting high-frequency signals to ground. The app note says that they are not strictly necessary but that it has been reported to improve certain noise issues. I have always built circuits with these included, so I shall continue. These are one of the rare cases where it makes sense to use a capacitor array.

Next, we have R011 and R015, which I completely whiffed on. In my defense, I am not the only one. My design came from the Logomatic, which came from the microbuilder.eu LPC2148 Reference Design which appears to be a mistranscription of the Keil MCB2140 schematic. Even then, the Keil board does not seem to be what was intended.

The idea is that P0.23, USB_ON, is 5V tolerant if and only if the rest of the circuit is powered. So, if it is not possible for the MCU to be off while the USB voltage is present, then you can just plug VBUS into P0.23. However, if the MCU is not powered, the voltage on that pin is supposed to be limited to less than 3.6V. The app note recommends a voltage divider, with 24k on the high side and 39k on the low side, resulting in about 3.09V on the input.

The way both the microbuilder circuit and Logomatic circuits are arranged, that isn't a voltage divider at all, and the pin eats a full 5V. Since the MCU can be turned off (the power switch disables the 3.3V VCC line), this is technically out of spec.

R011 should be connected to the right pin of R015B, and should be closer to 20k. This divider will draw three times as much current as the recommended value, but that is still less than 1mA.

There is supposed to be between 1 and 10 uF between VBUS and ground, visible through regulators and other parts. The real spec is that the inrush current should be limited, but I don't intend to ever submit my device to USB compliance testing, so as long as it works for me, it's fine. There is 4.7uF on the input to the voltage regulator, so I do not inculde any intentional capacitance in this section.

Wednesday, July 31, 2013

Rocketometer has been integrated

The rocketometer is now an integral part of the rocket payload
Attached to the CCD heater card

In the control section card cage



And here we have a short video demonstrating the size of the Rocketometer:

Wednesday, May 29, 2013

Yet another Rocketometer

The Arduino Leonardo can effectively be thought of as an Arduino on a chip, except that an Arduino pretty much already is one chip. What makes a Leonardo special is that its core is an ATMega32U4, which has a USB port. The chip can be programmed as normal over ISP, and once it is programmed with the appropriate Arduino bootloader, it can be programmed over the USB port. The Arduino library for Leonardo also supports using the USB as a CDC serial port, and has much other USB support.

The chip only runs at 8MHz. It can run at 16MHz at 5V, but I am planning on running it in the Rocketometer, which only has 3.3V available, which limits the chip to the aforementioned 8MHz.

Now how do I think I can get away with this? Simple: Even with the LPC2148 running at 60MHz, it was spending most of its time waiting for the bits to crawl across the I2C and SPI buses. And how much can we optimize a busy wait loop?

I bought a Leonardo to practice with, and a Sparkfun Pro Micro to practice some more, especially programming the bootloader. I will not be using the 6-pin ISP header on the Rocketometer, but I got the great idea to use the MicroSD sniffer to get at the SPI signals through the Rocketometer MicroSD slot, and I can just hold down the reset button, or solder one wire to the contact of the Reset switch - which reminds me, I should put the solder bridge on the top side of the reset switch. In that case, I can use the solder bridge itself as a temporary terminal, solder a wire to it long enough to program, connect the rest of the SPI signals to the microSD sniffer, then program it with an ArduinoISP.

While I was at it, I also designed a Precision clock around this new chip. It doesn't need a hardware UART to program or talk to the host computer, so no FT232 and no multiplexer is needed. The chip has more pins, so this design doesn't use literally every single possible pin (those two ADC-only pins don't count, since they are not possible to use in this project).

Sunday, April 28, 2013

DirectTask and nested interrupts

One problem with the old rocketometer code is that the sensor readout and SD card writing code were in the same thread, meaning that when the SD card took its endless milliseconds to write the data, the sensors were not being read, leaving an irregular gap in the record. My brilliant idea was to read the sensors in a task at interrupt priority, effectively creating another thread. First effort was with the task manager I described below, which was a dismal failure.

For whatever reason, and perhaps the same reason (see below), the task was not able to read the sensors. I came up with a much simpler task manager with which I am getting incredible accuracy.

I call it the DirectTask manager. Its concept: Rather than using one match channel of the timer and a heap priority queue, we just use all three available match channels (there are four, but the zeroth channel resets the timer every 1 minute). This limits the flexibility enormously, but I only need two tasks. I set up one task to reschedule itself on a regular basis (5ms in my first test) and I use the other task to read the BMP sensor.

However, the sensor readout runs an I2C read, which itself is interrupt driven. The code does not currently support nested interrupts, which means all interrupts are delayed until the current one returns. The I2C state machine was interrupt drive, and its interrupts were getting delayed, including the one which makes the state machine stop waiting forever, so the state machine waited forever.

So, we put in an option to I2C to run without interrupts, instead using a busy loop to check the I2C interrupt status bit, then calling the same state machine driver. We weren't getting anything by being interrupt driven anyway, since we had to wait for the read to finish.

With that, the DirectTask manager worked fine. Maybe the heap task manager would have worked fine too, but this one is simpler.

It takes 641 microseconds to read the sensors. We could probably easily bump the read rate to 500Hz, and maybe to 1000Hz, but this doesn't count anything but reading the MPU and HighAcc sensors.