Go Down

Topic: Audio exciters driven simultaneously (Read 2090 times) previous topic - next topic

birdm3n

#15
Jan 17, 2018, 11:29 am Last Edit: Jan 17, 2018, 12:01 pm by birdm3n
Thank you very much!

Can the impedence of the amplifier interfere in the system or it is unimportant?

One last thing, in that guide, it is required the Greatest Common Factor and in his case it was correct because he has different frequencies but in my case the greatest common factor is the frequency itself due to the fact that all the frequencies are the same. How can I calculate the number of counters after which the program has to reset the counter?

Grumpy_Mike

Quote
Can the impedence of the amplifier interfere in the system
Which amplifier and which impedance? Normally all amplifiers have a high input impedance and a low output impedance.

Quote
One last thing, in that guide, it is required the Greatest Common Factor and in his case it was correct because he has different frequencies but in my case the greatest common factor is the frequency itself due to the fact that all the frequencies are the same.
No, the common factor is the number of entries that you have in the waveform look up table. The more entries the greater the phase adjustment resolution is.

birdm3n

The amplifier has 100 kOhm in input and 4 Ohm in output. How does the impedance can influence the system?

I don't understand what you mean with the waveform look up table. Also because looking at the guide, the guy increases the value from 50 to 64 due to the fact that it has to trade off. So in my opinion it is not true that the greater the value the better the phase adjustment resolution is and I can't understand what value I have to use to divide the period of the signal.

Grumpy_Mike

Quote
So in my opinion it is not true that the greater the value the better the phase adjustment resolution is
So that means you are not understanding a lot of what I have told you.

Quote
I don't understand what you mean with the waveform look up table.
So when I mentioned look up tables in reply #14 why did you not mention this in reply #15, you just gave the impression that you had understood it?

I did warn you that this was not a beginners project. For look up tables see:- https://en.wikipedia.org/wiki/Wavetable_synthesis

Maybe look at this project for the look up table bit:- http://interface.khm.de/index.php/labor/experimente/arduino-realtime-audio-processing/ He uses the PWM method for output but you can just take the sample and feed it to an A/D.

Maybe a bit more background knowledge is needed, try reading this PDF:- https://www.elektormagazine.com/files/attachment/331 written by our very own David Cuartielles.

Quote
The amplifier has 100 kOhm in input and 4 Ohm in output.
So if this the amplifiers that drive the "sound exciters", then this looks about right to me for that job.

birdm3n

I read all the links that you sent me and now I have an idea of what you meant. So I have to create a lookup table with the values of the sine wave (the great common division, as the guy calls it, is just the dimension of the lookup table and the greater it is, the greater the resolution of the sine wave is, correct?) and implementing an interrupt system I have to increment the counter that will be the index for the lookup table. At every interrupt, the DAC outputs the sine wave value of the lookup table corresponding at the position pointed by the counter, correct?

Code: [Select]

   /* We need to calculate a proper value to load the counter.
   * The following loads the value 248 into the Timer 2 counter
   * The math behind this is:
   * (Desired period) = 64us.
   * (CPU frequency) / (prescaler value) = 125000 Hz -> 8us.
   * (desired period) / 8us = 8.
   * MAX(uint8) - 8 = 248;
   */


In my case, how can I identify my period and the prescaler value? It is not specified anywhere

Grumpy_Mike

#20
Jan 17, 2018, 09:54 pm Last Edit: Jan 17, 2018, 09:54 pm by Grumpy_Mike
Quote
the greater it is, the greater the resolution of the sine wave is, correct?
Yes. Well the greater is the time resolution that is.

Quote
At every interrupt, the DAC outputs the sine wave value of the lookup table corresponding at the position pointed by the counter, correct?
Correct.

Quote
In my case, how can I identify my period and the prescaler value?
The period of the interrupts should be set such that once round the lookup table gives you the frequency you want, in this case 100Hz. Use the prescaler value such that the counter value you choose is as big as possible to fit into the byte register.

birdm3n

I'm sorry but I still don't understand the math to calculate the parameters. Considering that I need a frequency of 100Hz, supposing that I want a counter equal to 60, the desired period is equal to: (1/f)/60 = 166,67microseconds, correct?

I looked around the internet but I didn't find anything that could me help in choosing the prescaler value, can you help me with that?

I suppose that the final value 248 is the dimension of the lookup table right?

I know that this project is really hard but I must do it, thanks for the patience.

Grumpy_Mike

Quote
Considering that I need a frequency of 100Hz, supposing that I want a counter equal to 60, the desired period is equal to: (1/f)/60 = 166,67microseconds, correct?
Yes. By the way 60 is quite short for a look up table, consider 256 or 512, as if the number of entries is a power of two it is simple to make the count wrap round.

Quote
I looked around the internet but I didn't find anything that could me help in choosing the prescaler value
That is because that information is in the processor's data sheet. Do you understand what a prescaler value is? It is the division from the master clock to use before decrementing the count down register.
From the data sheet of a ATmega 328 chip.
Quote
The Timer/Counter can be clocked directly by the system clock (by setting the CSn2:0 = 1). This provides the fastest operation, with a maximum Timer/Counter clock frequency equal to system clock frequency (fCLK_I/O). Alternatively, one of four taps from the prescaler can be used as a clock source. The prescaled clock has a frequency of either fCLK_I/O/8, fCLK_I/O/64, fCLK_I/O/256, or
fCLK_I/O/1024.
The frequency of the fCLK_I/O is half that of the crystal of 16MHz.
So calculate how many clock pulses you will need for each interrupt ( that is the 166.67 uS you had before ). Now if that is greater than 256 then you can't get it in the 8 bit counter register. So see what the smallest value of prescaler you can get so that it is lower than 256.

Smajdalf

The frequency of the fCLK_I/O is half that of the crystal of 16MHz.
AFAIK frequency of I/O clock is equal to the main clock. Unless you use the System Clock Prescaler to reduce the frequency (not used in Arduino by default and there is little reason to do so) the fCLK_I/O is equal to frequency of the crystal, not half of it.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

Grumpy_Mike


birdm3n

#25
Jan 19, 2018, 04:44 pm Last Edit: Jan 19, 2018, 04:52 pm by birdm3n
Well, tell me if this math is right. I followed the formulas used in the commented code that I posted:

- 1 / 100Hz = 10ms
- period = 10ms/256 = 39.06us with 256 as size of the lookup table
- 48MHz is the clock frequency
- Considering that the prescaler value of the arduino m0 are: 1,2,4,8,64,256,1024:
    48MHz/1 = 48MHz => 20.83nsec
    48MHz/2 = 24MHz => 41.66nsec
    48MHz/4 = 12MHz => 83.33nsec
    48MHz/8 = 6MHz => 166,66nsec
    48MHz/64 = 750KHz => 1.33usec
    48MHz/256 = 187.5KHz => 5.33usec
    48MHz/1024 = 46.87KHz => 21.34usec
- Dividing the period by the clock divided by the prescaler, I obtain:
    39.06usec/20.83nsec = 1875.18
    39.06usec/41.66nsec = 937.6
    39.06usec/83.33nsec = 468.74
    39.06usec/166.66nsec = 234.37
    39.06usec/1.33usec = 29.37
    39.06usec/5.33usec = 7.33
    39.06usec/21.34usec = 1.83

Now according to the guy's calculation, due to the fact that the register is 8bit, I have to subtract 256 with one of the number of the final calculation. Due to the fact that I need a number close to 256, I should get 1.83 and so, have a reload of the timer with 254, correct?

Moreover the count of the interrupt has to arrive to 256 and then has to be reset, right?

Grumpy_Mike

Quote
39.06usec/166.66nsec = 234.37
Is the prescaler value you need, so a value of 8.
Quote
due to the fact that the register is 8bit, I have to subtract 256 with one of the number of the final calculation.
No.
You want a count of 234 which is less than 256. So reload with 234. Notice you will not get exactly 100Hz but that is computers and counting chains for you.

Quote
Moreover the count of the interrupt has to arrive to 256 and then has to be reset, right?
Yes but if you use a byte for the counter then it will reset automatically as it wraps round.

birdm3n

But looking at the code of the guide, I still don't get the meaning of the variable tcnt2 that reloads the timer at every interrupt, also because it is not used or modified anywhere.
Code: [Select]
   /* Reload the timer */
    TCNT2 = tcnt2;


So what you are suggesting is to have
Code: [Select]

if (count1 == 60)
    {
        digitalWrite(FREQ1, toggle1 == 0 ? HIGH : LOW);
        toggle1 = ~toggle1;
        count1 = 0;
    }


this code with the count that is reset when it is equal to 234 instead of 60, right?

Grumpy_Mike

Quote
So what you are suggesting is to have .......
No, no one is suggesting that in any way.
Each time the timer interrupts happens then you have to load the new value in for next time.
Each time the timer interrupts happen you have to increment the count.
Each time the timer interrupt happens you have to load in the value pointed by count in the look up table and output it to the D/A.

birdm3n

Quote
Each time the timer interrupts happens then you have to load the new value in for next time.
What do you mean? What new value does it have to be loaded for next time?

I agree with you for the other two operations but I miss the first one.

What is the reload timer (tcnt2) code that I posted used for at each timer interrupt?

In case I would like to change and use the PWM method, I just have to use a code similar to the one posted in the previous post, correct?

Go Up