switch IC

Go To Last Post
43 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using an Arduino Mega to drive a pair of MCP4725 (DAC's) which will output separate sine waves. I need to switch SDA/SCL between them at a rate higher than Nyquest. I would be grateful for a suggestion for a switch IC, a simple 2 channel switch that can switch a digital signal between two outputs under the control of the uC.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why, your AVR as a Master can do it without Nyquist. Use CD4053.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 I need to switch SDA/SCL between them at a rate higher than Nyquest.

 This makes absolutely no sense whatsoever ..Where'd you get this crazy thought? You are sending your sinewave VALUES to the DACS

 

Send your data to the DAC1 address whenever needed, and to DAC2 address whenever needed.  Tie address pin  A0 high on one chip and low on the other.

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also, why not use a dual DAC (prob cheaper than 2 singles)?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

grohote wrote:
Use CD4053

 

Use of A0 is good to switch between two DAC. For more than 2, i.e. for 3 or 4 DAC, you may need CD4053.

 

You also may use selector lines, and address only the lowest one, for example: one A0 is 0, all others A0 are 1.

(It is even better than CD4053 which may be a solution for non-I2C like 2xUSART)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I2C is designed to have multiple devices on the same bus. Just wire up the two DACs so that they have different addresses. Set A0 low on one and high on the other.

 

Task done. No switch is needed.

 

As a side note, you always have to include a device address in an I2C message, so addressing takes no extra time.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Fri. Jun 17, 2022 - 01:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks. The A0 idea is excellent. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is the way I2C (TWI) is intended to work!

 

By the way, watch out for 7 bit addresses vs 8 bit ones. If they give you separate read/write addresses, then its 8 bit and you can use those numbers directly. If they give you one address, it is most likely 7 bit and it needs to be left-shifted by one bit, and the read/write bit inserted in the least significant bit.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jimlake wrote:
Thanks. The A0 idea is excellent.

I'm absolutely gobsmacked at the simplicity of this solution. sad

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


A0 is realized either directly to the connector, or as an option. Blue board is better.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I got the red ones from Spark Fun for about 6$. The address is 7 bits. Thanks for the i2c tips. I see how that is supposed to work now. Thanks again for the good ideas.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 I see how that is supposed to work now.

Were you not aware the chips have assignable addresses?  Some chips provide a wider selection than others.  That allows the bus to have many items connected.  Rememebr, generally only one pullup per SDA/SCL line, though you might get away with some deviation.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
only one pullup per SDA/SCL line

 

There are two 4k7 at each board.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This problem is a bit more complex than I had originally thought. I want the two DAC outputs to be different frequencies. That means that the loop in the uC that sends the digital data to the DAC has to send each data point at a specific frequency such that all of the data points are sent during one wavelength. So, if I want two different output frequencies, the loop for the first one has to fire at a different rate than the loop for the second one. That means I can't use a single main loop, like I would normally use. I think that a pair of interrupts running on two different timers is the way to do it. Each interrupt fires at a rate set by its timer. Something like this:

ISR TIMER1_COMPA_VECT
{ 
 send data point to DAC 1 via i2c
}
ISR TIMER3_COMPA_vect
{
 send data point to DAC2    
}

I think that will work but I'm not sure how to do it in Arduino C++ because it doesn't use timers in the same way that I am accustomed to.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What you probably want is called a "DDS"; making two tones this way is pretty common. Think DTMF phone dialing. Simply search for DDS on Freaks. The classic one is by Jesper and there are a number of others derived from his. 

 

Oh, by the way, if those two tones get combined, then you really only need one DAC.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Fri. Jun 17, 2022 - 09:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That means that the loop in the uC that sends the digital data to the DAC has to send each data point at a specific frequency such that all of the data points are sent during one wavelength.

Well pick a freq and send them cheeky.  For example, you could pick 40KHz as the sending freq  (40K samples/sec).  Each time, send 2 values (2 dacs).  You could have one generated freq be 2.67 KHz and the other 3.9513KHz. 

The generated freq must be much smaller than the send freq for easy filtering.

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jimlake wrote:
I want the two DAC outputs to be different frequencies. That means that the loop in the uC that sends the digital data to the DAC has to send each data point at a specific frequency

Rubbish.

At the moment I'm listening to a Stereo Audio DAC where samples are clocked in at a fixed 48KHz. I can clearly hear that there are a multitude of different frequencies present in each output.

 

Last Edited: Sat. Jun 18, 2022 - 10:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, apparently I am unable to state clearly what I am trying to do. I'll try again. I wish to produce two separate (not to be combined) audio streams, one at 100 HZ (base) and one at 105 Hz (beat). I have two DAC's and one uC with one i2c to send digital audio data to the DACs. I'm looking for your opinion on the quickest, cleanest way to do that. I need to be able to vary both the base and the beat frequency somewhat.

 

Right now, I am using a signal generator to create the audio streams. This device will replace it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

100Hz and 105Hz is pretty easy. You can generate, lets say, 100 samples per cycle for both simultaneously, and only have to send new values out the TWI port 20KHz rate. Counting address byte and two data bytes that is only 60 Kbytes per second. 400 KHz is a standard I2C clock rate so maybe you only do 80 samples per cycle, which is still good. Use the DDS scheme to determine the sine values for each sample and send them out at the same rate for both channels.

 

DDS give you quite high frequency resolution. DDS works nicely for DTMF (telephone dual-tone dialing system) where the tones are in the KHz range, so you should have no real problem, at all.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wish to produce two separate (not to be combined) audio streams, one at 100 HZ (base) and one at 105 Hz (beat). 

Ok, to avoid aliasing, you need an absolute min sample rate of 210 Hz (that's every 180 degrees, min), but in reality much more than that.  Use 10 kHz, filtering will be much easier.   That's 5000 samples/sec for each output, that will be way more samples/sec for each wave--they will be easy to filter.

 

Use a 10 kHz interrupt.  send one point of A, then next time send one point of B, then next time send one point of A, then next time send one point of B.......

 

105 Hz is 37800 deg/sec.  5000 points per second means each sample advances 7.56 degrees of your waveform data.  For example 7.56*256=1935.36 (1935 or 99.981%)...so keep adding  1935 to a large total and divide the total by 256 each time to get your current degrees value (sin data) to send.  (total 0-->deg data, total 1935-->deg data, 3870-->15 deg   5085-->23, 7740-->30....)

 

As you can see, this is running slightly less than 8 deg/sample

(meaning 7.56, or really 7.56*1935/1935.36= 7.55859375deg/sample,  or 5000sample/sec*7.55859375deg/sample/360deg= 104.9805 Hz)  same as 105*1935/1935.36 

If you divide by larger (512, 1024, etc) the error is even less.  256 should be plenty

 

100 Hz is 36000 deg/sec 7.2 deg/sample..7.2*256=1843.2....add 1843 to another total each time. gives 100*1843/1843.2= 99.989 Hz

 

 

What kind of audio stream is 100 Hz?? 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Jun 18, 2022 - 04:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Its a clean 100 HZ pure sine wave intended to produce a clean 100Hz audio tone. Same for the 105 Hz signal. The two will be used to produce an audible 5HZ beat frequency. If you were to send these to stereo speakers you'd get that wa,wa,wa,wa...... at 5Hz.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The two will be used to produce an audible 5HZ beat frequency.

Is that for some sort of room low freq calibration or speaker optimization?  Or perhaps building a haunted house?   Don't make your paintings fall down!

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jimlake wrote:
100 HZ

 

Rubbish, yes, you will note this 5Hz /somehow/ but you will hear very strong 100 Hz.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes you do hear the 5Hz. Unzip the FLAC file from this ZIP. It is only 1s duration so play it on repeat.

 

The sound I generated here has 100Hz sine in the left channel and 105Hz sine in the right.

Attachment(s): 

Last Edited: Sun. Jun 19, 2022 - 09:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You asked. The signals get amplified and then sent to a pair of 'puck' type vibrators (used for video game kinesthetics). These go in the armpit under each arm. There is pot to set amplitude to a low pulsing vibration. The vibration at 5hz is intended to reinforce the theta wave (5-8Hz) to aid meditators to reach a deeper meditative state. I am experimenting with it on myself. I have preliminary indications that are promising, but there is much experimentation to be done.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 The vibration at 5 Hz is intended to reinforce the theta wave (5-8Hz) 

So why not just generate the desired 5Hz?  You likely don't need a sinewave, may be a ramp or triangle shape would be fine (though they would have additional freq components).

I am experimenting with it on myself. 

Reminds me of some old Star Trek episode with a chair and whirling light.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The transducers probably won't reproduce 5Hz very well. At first, I had the same thought.

 

Another option might be a  several hundred Hz PWM width-modulated at 5Hz. Or, you can amplitude modulate your 100Hz at 5Hz. You could do that with one DAC and send the same signal to both transducers for symmetrical coupling into the body. Amplitude modulated sine would be pretty easy since only one DAC would be involved.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Sun. Jun 19, 2022 - 12:28 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim, I am going to try what you suggested at some point. I have tested this machine (generating the signals with my signal generator) and you can easily feel the 5Hz beat frequency, which is the idea. I did it this way because it seemed like an easy way to do it with stuff I had on hand, but I think your idea of modulating the base frequency would also do the same thing. How would you approach modulating the 100 Hz?

 

I've been using a lookup table of 512 sine values and just sending them at the right frequency (100 * 512), so every 20 microseconds. The 5 Hz would be (5*512)=2560, or every 390 usec. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Jimlake, remember if you want to throw an interrupt every N pre-scaled cycles, you have to choose OCRnx = N-1.  From the data sheet:

\ 

 

'at the next timer clock cycle' being the clue.  Not a big deal if you are throwing an interrupt every 500 cycles, but a very big deal if you are pre-scaling at 1024, and throwing an interrupt every 4096 cycles of the system clock.  The difference between OCRnx = 3 or 4 becomes real apparent.

 

jimlake wrote:
reinforce the theta wave (5-8Hz)

Doesn't that make humans have to defecate? 

 

I thought you wanted the alpha state at 8-12 Hz for meditation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, modulating a 100Hz sine.

 

Lets start  by assuming that your sine table is SIGNED. Doing this will save arithmetic operations and that will save time. Intuitively, wthout modulation, you would probably use a table of 1+sinx because that uses a unipolar DAC most effectively. You indicated that you wanted 512 samples. [Note: that is FAR more than you really need; 64 is probably quite adequate. 512 leaves you far too little time to do any modulation, let alone tie send it serially to the DAC.]  In any case, lets assume N samples per cycle, counted, 0, ... ,N-1. With sample 0 at a zero crossing, sample N-1 will be one sample short of the next zero crossing of the same slope. That way, when you start the table over, going from sample N-1 to sample 0, the value will be at the appropriate zero crossing 

 

Lets assume that n is the sample number and runs fron 0 to N-1, then rolls back to zero and starts over. If your signal has a period of P seconds, then each sample  is at an interval of P/N seconds. Thus, P/N is the sample rate or "tick interval"; you read table entry n from the sine table every tick, incrementing (or rolling over) n after each read.

 

To properly amplitude modulate it (rather than doing a single sideband modulation), you need to multiply each table value by (1+siny) where siny is your 5Hz sine. Note that 1+siny varies from 0 to 2 so that you will want to scale both the sine table and the modulation so that the result fits into your DAC data width.

 

Now, here is a surprise. You can use the same table for both the 100Hz "carrier" and the 5Hz "modulation". To get 5Hz out of that table, you read every 100Hz/5Hz = 20th value from the table. Use a different index and a different sample counter and it will work just fine. Add 1 (properly scaled for the table data range to the value to get the (1+siny) value. For the 19 carrier samples that doin't have new modulation values, just assume that the modulation stays constant during that interval. Or, if you want to get fancy, you can do a sort of "linear interpolation" between modulation samples, but, then the amount of computation starts to add up.

 

After multiplying the carrier by the modulation function, you MAY need to rescale the result to fit the DAC. OR, scale the table data so that scaling is not needed. You will also have to add a constant to the result so that carrier zero crossings come out to be close to the mid-point of the numerical range of the DAC.

 

Should point out that the sine table can be an integer table and you can do integer additions and multiplications. No need for floating point. After all, the DAC takes integer values!

 

Hope this helps

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Sun. Jun 19, 2022 - 06:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

In your experimenting on yourself phase, why not use a PC based waveform editor and amplify the line out or headphone output ?

 

Here I used  Wavosaur a very lightweight editor, to generate 100Hz sine and multiplied by by a 5Hz sine.

 

 

Once you have determined the ideal waveform then write the AVR code to generate it.

 

Last Edited: Sun. Jun 19, 2022 - 09:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did I understand correctly that you're expecting a 5Hz beat frequency with 100Hz under one arm and 105Hz under the other? That is, the only coupling between the two signals is acoustically through the human body? That suggests rather a lot of energy from the primary transducers, and that at clearly audible frequencies...

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim: That's a great explanation, thank you.

NW: Also a great idea, I'm going to do that too.

MT: I have not noticed that effect. But, I'll be on the lookout for it. Could be useful. I'll be able to alter both the base freq and the beat freq. so I can change it as necessary.

Neil: The amp is 35W/channel, and I have been running at about 1/4 power. So there is a lot of energy involved. Power comes from an SMPS driven by mains. The pucks don't heat up noticeably 100hz, but when I tested it at 40 Hz, they did start to get hot.   I can hear it with my ears, but it is not loud (I will measure that with a db meter). Most of the energy gets absorbed by my body as vibration, which is quite noticeable, but not uncomfortable. I realize that there are infrasound issues here too, but that's why I'm the test sub. The primary issue for me is how well it works at its intended purpose, and that is up in the air.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, OK, so you've got longitudinal waves effectively being transferred through the fluids/solids (and air in the lungs) from both sides and interfering with each other somewhere in between :)

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. I can feel the 100 HZ, but I can also feel the 5 HZ in my chest and throat and sinus spaces. The 100 Hz harmonizes with my voice if I hummm at the same time, which creates resonance in the air passages. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can I have a copy of that file?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn't save it but it took <= 1 minute to remake.

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I made it after I asked. Thanks. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Let's get back to the basic goal: feed two DAC's so that they each output their own, separate, periodic waveform. In this case the period of one is 1s/100 = 10ms. The period of the other is 1s/105 = 9.5ms (approximately.) What we want to do is construct two lookup tables, one for each DAC. At some fixed interval, we send one value from each lookup table to its associated DAC, then increment the index counter into each lookup table so that the next time around we use the next value in each lookup table. When either index counter reaches the size of its lookup table, reset the index counter to zero. The lookup tables will be different lengths because to the two signals have different periods. We'll go through the 100Hz table every 10ms and the 105Hz table approximately every 9.5ms.

 

This is where it gets a little tricky. We need to choose an update rate that is a multiple of both 100 and 105 so that both signals can be output without glitches. We also need that update rate to be something that can be accurately created with an ATMega2560 running at 16MHz (Arduino Mega.) 100*105 = 10500Hz works well as far as the lookup tables go, but there's no way to create an interrupt that triggers exactly 10500 times per second with a uC running at 16MHz. In fact, I used the short python program below to look for any frequency that is a multiple of both 100 and 105 and could be generated by scaling a16MHz clock and found none.

 

Unless you can either change the clock frequency of your Mega or use signal frequencies other than 100 and 105, you're screwed.

 

for f in range(106,16000000):
    if (f/100).is_integer() and (f/105).is_integer() and (16000000/f).is_integer():
        print(f)

 

Brian Fairchild wrote:

It's at this point that we really do need the OP to come back and engage with us. So many questions..........

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is nothing sacred about either the 100 or the 105. Something close will accomplish the same thing, I suspect. I don't know for sure. This is a research project based upon the Monroe Institute's Gateway Experience, which I have been doing for some time. Bob Monroe's very fascinating discovery that sound is key to manipulating consciousness is simple to prove to yourself. Try it, you'll see. It occurred to me that this experience MIGHT be enhanced by supplementing hemi-synch audio with body vibration or vibration of the air in the lungs and air passages in the same frequency range. That's what I'm trying to do. Bob Monroe doesn't reveal the technical details of his research, so I have been doing some experimenting on this with myself as a test subject. The results I got showed me its worth pursuing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In that case, setup a timer to overflow at 15625 Hz (16MHz/1024.) Have it trigger an interrupt at every overflow. Inside the interrupt set a flag. Inside your main loop, check the flag. When you see it set, clear it and send data from the lookup tables to the DACs. If one of the tables is 156 samples long, then it will repeat at 100.16 Hz. If the other table is 149 samples long then it will repeat every 104.87 Hz.

 

Or some variation of that, if you get the idea. If that's too much I2C traffic, then make the tables only half as big and send data alternately to one or the other DAC as avrcandies suggested. Or run the timer slower than 15625 Hz. Or some variation of that.

 

At least that's what I would do.

Brian Fairchild wrote:

It's at this point that we really do need the OP to come back and engage with us. So many questions..........

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What we want to do is construct two lookup tables, one for each DAC.

Well you certainly could, but why not use the same for both?  The table really doesn't care about freq at all.  Say your table has 4096 points (a lot) spread over 360 degrees.  You can step thorough the degrees as fast or slow as you need to create whatever freq you want.  The stepping just becomes a little less  perfectly sequential.  Instead of 1 2,3,4,5,6,7,8,9... you might have others

 

This shows 21% faster compared to base (higher freq), and 17% slower compared to base (lower freq)...these larger percent's better show the effect.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Jun 20, 2022 - 03:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or consider a simple table of (say) 256 sine values - really, you only need 90 degrees worth, but 360 keeps it simple. Now generate a timer interrupt at 1024 Hz.

 

On each tick, read a sample from the table and output it, and increment the pointer to the next value (if the pointer gets past the end of the table, subtract 256 from it). Obviously the output here will be a sine wave at a frequency of 1024/256 - 4Hz.

 

Now change the step size. If instead of incrementing by one, you increment by two, the output will be at 8Hz, and so on for any integer step size.

 

But the trick here is that you can generate any frequency you want (Nyquist limited by the 1024Hz sampling rate to 512Hz, or real world, a shade less). Instead of integer step sizes, you maintain a higher precision count - say 65536 - and use the high byte of that count as the index into the table. Now you can select a fractional value: if you want a 100Hz output then you select the step value as (1024/100) * 256 =  2621.44 (0x0a3d)

 

Selecting the high byte as the index will produce values of 10, 20, 30, 40, 51, 61, 71, 81, 92... you can see the step size is fractional, and the next cycle will be offset into a different sequence of indices but with a similar stepping pattern. The frequency isn't quite accurate - that odd .44 remainder in the division but I don't believe it to be critical. If it is, use a faster timer - say, the 15625 suggested by Eugene - or use more bits in the fractional stepping size.

 

Using the original values, the step value for 105Hz would be (1024/105) * 256 = 2496.6 (0x09c0) - so the step size is slightly smaller as you would expect for a higher frequency.

 

The neat thing about this method is that you need only one table and only one timer tick:

// untested dodgy pseudo code!!!

#define FLO_STEP 0x0a3d                 // (1024/100) * 256
#define FHI_STEP 0x09c0                 // (1024/105) * 256

int16_t sine[256] = {
    ...sines from 0-360 degrees...
}

void on_timer_interrupt (void)
{
    static uint16_t flo_ptr = 0;        // 100Hz
    static uint16_t fhi_ptr = 0;        // 105Hz
    
    int16_t adclo_val;
    int16_t adchi_val;
    
    adclo_val = sine[flo_ptr >> 8];     // get the values for the current sample
    adchi_val = sine[fhi_ptr >> 8];
    
    // output the samples to the ADCs here
    
    flo_ptr += FLO_STEP;                // increment the step counters
    fhi_ptr += FHI_STEP;                
}

A couple of caveats: the first is the assumption that overflowing a uint16_t discards the high order bit. I have an idea that this is one of C's implementation defined parts, though I don't know of a compiler where it doesn't do this. Also, the samples are output in the timer interrupt because for any audio handling you want the most precise sample timing you can get - the ear is very good at hearing the noise caused by sample timing errors.

 

An alternative approach would be to use more precision in the step size and interpolate between the samples. However, this requires more complex arithmetic - again, the ear is very good at hearing the errors, and linear interpolation for a generic audio application is insufficient. For your application, I think this is both accurate enough and simple enough. One observation is that using the same timer interrupt and table, one can generate as many signals as you need...

 

Neil