*
Please Note: This is mostly copy paste, with some edits, from my post at the Kerbal Space Program forums... I occasionally over explain things that we ALL ought to know around here!*
So, I was doing some math... and I believe I have a major issue... and it
is major... I don't think my current DAC design has a
chance of working.
It puts 100% of the workload on the Arduino to generate all 10 of the sine waves required, all at 400 Hz, with realtime waveform generation. Some basic math tells me this is a gargantuan task. Besides monitoring a serial input for axis updates, I need 10 sine waves. I can do MOST of the work using lookup tables, but I still need to calculate the offsets of yaw, pitch, and roll (by adding 120° and 240° to each of the three values) and looking up the attenuation values for each of the 9 results from a lookup table, for each data frame sent by the game, assuming 20-60 frames/second. I need to then multiply the reference sine wave (which can also be generated by lookup table) with the attenuation values (9 multiplications), and send the reference and the 9 results of the multiplications to the DACs, which requires 10 I2C transmits, with a digital out changed between each transmit to function as a chip select. These multiplications happen at the sampling rate of the sine wave, not the frame updates. I only update the multiplication
values once (x9) on each frame update.
If I need even 256 steps in my sine wave cycle (that's a low resolution, but It's my attenuation resolution that defines the angle of the navball, and temporal resolution would be somewhat smoothed out by filtering), then the math works out as follows:
At 400 Hz, if I have only 256 "slices" of the sine wave over one cycle, and 10 sine waves to update, I have to write the I2C bus 1024000 times EVERY SECOND... I... Is that even possible? I am fairly certain this exceeds the maximum data rate for I2C. There appear to be 4 speed standards: 100 kbit/s, 400 kbit/s, 1 mbit/s, and 3.2 Mbit/s... Even the fastest speed wouldn't handle the bandwidth of just 8 bits sent at that rate, and these are 12 bit DACs! If I could get the resolution out of the PWM to do it, it might work, but the PWM resolution isn't even high enough for one whole degree of ball rotation per step! Ouch! That's one jittery navball there!
I may reuse my DAC board for analog meter movement, if I can mod the amps to drive DC (they are audio amps, and can only drive AC, but I think that is only because they are AC coupled with a capacitor inline with the inputs and outputs). If I simply remove the amp boards and drive with a MOSFET or something, it will probably work fine. That could be a reasonable use for the I2C DACs. As it stands, the $40 or so dollars spent on my DAC board, and the time spent building it, are more or less wasted.
So...
The solution is VERY simple and elegant, and thanks to some part finding by someone on the Kerbal Space Program forums, far less expensive than I thought! It's still more expensive than my original plan, and more complex, hardware wise. It REALLY DOES solve my problems though. That part, is the 12-bit MCP4912/22 DAC.I need to use a totally different type of DAC. I need one with a proper adjustable voltage reference, and the MCP4922 has it. All I need to do is generate a single sine wave with a hardware sine wave generator (can be done with either an analog circuit, or the $7-12 MAX038 chip that swarms ebay). I just set it to produce a 400 Hz sine wave, and that's it. I need to feed that to a pair of op amps to create a differential pair (opposing cycle polarities), and use an analog switch to select either the un-inverted or the inverted sine wave to feed into the DAC's voltage reference.
This is:
1 hardware 400 Hz sine wave generator.
2 op-amps to create inverted and non inverted outputs.
20 analog switches (about 5 chips) to select whether to flip or not flip the reference sine wave.
9 DACs with adjustable voltage references.
10 power amplifiers driving transformers that drive the actual FDAI at the desired higher voltages.
So, the adjustable voltage reference input is the real trick to making this work. It's been brought up in pervious messages, and it WAS the correct path. If you have 0 attenuation, then the DAC is at maximum output, but the output will scale to the voltage reference, so as the sine wave applied tot he voltage reference rises and falls, the output matches it. If the attenuation were at 100%, then the DAC output would be at it's minimum, meaning no matter how high the input sine wave rises and falls, it's scaled down to nothing. As the attenuation scales between 0-100%, it scales the actual sine wave that is being input on the voltage reference.
The DAC basically just becomes a hardware attenuator. I MIGHT be able to reuse the amplifiers I installed on the DAC board by desoldering them. I may need to drive a power op amp though, to push enough current into the final transformer stage, in order to have enough power to actually drive the FDAI. I have around a dozen LM675 power op-amps that I hope can do the trick. Those were not cheap, but I already have them. I may end up needing to hand wind my own transformers, just to keep myself on budget. I have no idea what it'd cost me for 9 transformers to bump the voltages driven by the low voltage DAC circuit, to the 28 volts wanted by the FDAI.
This is actually an area where I am actively seeking advice. I need to take what will likely be a 0-5 volt sine wave (zero crossing at 1/2 Vcc), and will need to convert that to 28 volts. I DO have the LM675 power Op-amps that I can use as output stages. The transformers will all have one side of the primary tied to the signal, and the other side tied to ground. The secondary will have the center of the "Y" floating, with the other 3 wires tied to the FDAI inputs. The reference will be just a single winding between the output driver and ground.
One reason I never found this part on my own, was because it seems like Digikey and Analog Devices really like to return some VERY spendy chips when you specifically search for a multiplying DAC. You're guaranteed an adjustable voltage reference if you get one, but lots of chips can do the same, without costing $10 or more per DAC channel. Imagine, a company making it easier to find higher priced products...
Turns out, external voltage reference input wasn't a search criteria that was easy to sort for.
Thanks to someone else's knowledge, I was led to the MCP4922. Does what I need, since it has the all important external voltage reference input, handles a pair of 12-bit DAC channels per chip, and for just $2.76 a chip! Noice!
To top it all off, I have
90 74HC4066 quad bilateral switches
on hand, 20 DIP and 70 in a variety of SOIC and SOP packages. I have no worries about dealing with the analog switches to select whether to reference the inverted or non-inverted reference sine. I think I'll have enough parts!
Between the DACs having sufficient resolution to handle fractional degree increments of the navball, the sine being generated in hardware, the polarity flip being easily handled by the arduino using the analog switches and a pair of op-amps... I should have FAR less to process inside the Arduino, and I should be able to send out the data at a more than reasonable rate!
Even if I have a PEAK of 60 update frames per second, then I need to send 60 x 9 SPI transmits each second. That's only 540 transmissions per second! I'll need 5 Chip select lines, plus the SPI bus connections, and a single digital out to update all the DACs to their newly updated values. I'll also have an incoming serial bus that it will be watched for frame updates.
Again, I apologize if anything seems out of place, or if I explain things you guys already know. This post was a mix of two pieced together posts from a forum, plus some original typing. If I left any of those
CSI: Wherever style "explain the crap real professionals would already know for the audience" moments, it's because I originally put it in for some of the people on the other forum, where not all the people are as electronically gifted as the people here.
Anyway, it's also 1:25 AM... Going to bed now!