bit DAC, plus PWM if better filtering is required
PWM will actually leave you with a more noisy signal than a DAC - at the same sample rate.
I should have mentioned that the sine frequencies need to be specified to 0.1Hz, e.g. 42.7Hz. Does this affect the chosen sample rate?
You could sample each frequency at a sample rate which is a fixed factor above the signal frequency, e.g. by 100 times the signal frequency. Thus you'd sample the 0.1 Hz sine at 10 Hz, the 42.7 Hz at 4270 Hz etc. But that will make recombining these signals into one more complex. The easiest way (in my opinion) is to use a fixed sampling frequency. 1 kHz or higher. That will allow you to add the samples within the same cycle as they are generated.
I am also not clear on how to generate 5 different sine waves simultaneously from one LUT. Is it done with loops?
You may use a loop or an interrupt routine. But not a loop over the frequencies but a loop over the samples. I'll give you an example. You'll have to refine that and work it out for your specific frequencies of the signals, sample rate and the way your LUT is constructed.
I'll make some very simplified assumptions to illustrate the method. You need to detail these:
- Assume a LUT with 31416 entries (6283 equal to approx. 1000 × 2 ×Pi) representing a full sine wave (I will not go into the details of optimization by using e.g. a 1/4 sine LUT). The step between 2 adjacent entries is then (2 × Pi)/1000. The LUT value for each sample is then LUT(x) = sin((2 × PI)/1000 × x)
- Assume a sample rate of 1 kHz equal to one sample every 1 µs.
- Assume you have set up an interrupt routine that is called every 1 µs, i.e. at the same rate as the sample rate.
If you now take one sample step by step from the LUT during each interrupt, you'll create a full sine wave after 1000 interrupts because (2 × Pi)/1000 × 1000 = 2 × Pi.
1000 interrupts at 1 kHz interrupt rated is equal to 1 s. Therefore the resulting sine wave has a frequency of 1 Hz (approximately since the Table is not exactly 2 × Pi long).
If you take every second sample from the LUT, you will have gone 2 times through the table during the same 1 s interval, therefore the sine wave has a frequency of 2 Hz.
Generally the frequency of the output signal will be fout
To create multiple sines of different frequencies at the same time all you have to do is to use different stepwidths:
f1 = stepwidth_1 (e.g. 1 Hz from the above example)
f2 = stepwidth_2 (e.g. 2 Hz from the above example)
signal_out = f1 + f2 + ...
To create fractional frequencies (e.g. 1.5 Hz) you need to change sampling rate and stepwidth in step. For example reduce the sampling rate to 500 Hz, then a step of 1 is equal to an output frequency of 0.5 Hz. To create 1 Hz set the stepwidth to 2. For 1.5 Hz set the stepwidth to 3 and so on. For more granularity like eg 0.1 Hz you would have to lower the sampling rate to less than 500 Hz which is not suitable for your 100 Hz (max) requirement. You will have to use a longer LUT in this case.
I'm sorry, I can't elaborate the full code for you. You'll have to do some research using your favorite search tool. Lots of examples on the internet.