Thanks for the link. I remember seeing videos from that gentleman "w2aew" before, they're chock full of tips!
So I will try both methods.... one where I go through my PWM analogWrite method and convert it to an analog voltage using a filter (and that's another question entirely... what R/C combo would work best for the Arduino's PWM function to get a smooth output and what kind of attenuation will result).
And the other is using this R-2R ladder network and bit-writing the outputs.
I have 14 digital output pins available on the Arduino....so if I use 7 for X and another 7 for Y, then I have 128 levels (2^7) values per channel X or Y to write my binary words. That would give me quite a good resolution to get varying voltage outputs. Then I would compute a "sine table" which would basically just be the values of the sine-wave at equally spaced times converted to 7-bit values.... with my "-1" of the sine being 000,0000 (0 decimal) and my "0" level sine being 100,0000 (64) and my "+1" sine being 111,1111 (127).
As far as horizontal time-spacing, my array could be as short or long as I want. If I make my array of values 240-length (1 complete wave) then I could easily divide this into 2, 3, 4, 5, and 6 to get my various frequency ratios.
Given enough memory on the Arduino, I could represent a sinewave in an array of length 960..... one complete wave. Then if I have say my 1st channel running through every element of the array....all 960 levels..... while I have the 2nd channel skipping every other value in the array.... so it is "TWICE" the frequency of the 1st channel. When it gets to the end it loops back. Or if I want a 1:3 ratio for Lissajous curve formation, once again I have my first channel go through all 960 elements, while my 2nd channel jumps to every 3rd element per cycle.... my 2nd channel would run 3x faster than my 1st channel.
Each channel's 7 pins would then run through a R-2R DAC and display.
Code could look like this:
sinetable[960] = { ...... }
loop()
{
for (time=0; time<960; time++) // cycle through array
{
value = sinetable[time]; // get value of sine
for(bit=0; bit<7; b++) // shift through each bit and display
{
digitalWrite(pin[bit], bitread(value,bit))
}
}
}
So the above would essentially look up a 7-bit value for the sine wave in the array for each step in time, and write it out to the 7 pins. Now if I wanted to do the same except with 2 channels I would have to do the following:
sinetable[960] = { ...... }
loop()
{
for (time=0; time<960; time++) // cycle through array
{
value1 = sinetable[time]; // get value of sine for channel 1
value2 = sinetable[time*2 modulus 960]; // get value of sine for channel 2 at twice frequency
for(bit=0; bit<7; b++) // shift through each bit and display
{
digitalWrite(pin[bit], bitread(value1,bit)); // output binary word for channel 1 pins
digitalWrite(pin[bit+7],bitread(value2,bit)); // output binary word for channel 2 pins
}
}
}
Anyways, that's the rough code. I need to think about how to optimize it. Not sure what types of functions take more cycles (like "if" statements, versus "multiplier/division/modulus" and so on. Also wondering if perhaps this is not overkill on the resolution as it will slow things down having 128 voltage levels and 960 time steps. I'll know once I actually sit down and build myself the array and try it out.
I found this, might be handy....
http://fritzing.org/projects/arduino-simple-signal-generatorLooks like we are using 10k and 20k resistors? If I am not loading this at all, and we are just measuring on a scope, with these resistors I shouldn't be worried about drawing too much current from the Arduino I presume.
I also came across this, which will come in handy when I select a filter for my PWM to Analog version:
http://digital-diy.com/swordfish-example/314-digital-to-analogue-conversion-dac-via-pwm.html