XMega256a3bu ADC to DAC Internal routing and Interrupts

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

Hey Everyone, 

 

I am using an XMega256a3bu XPlained board. Fairly new to this. I am trying to set up a mic->speaker circuit through the XMega. I wanted to use the ADC and DAC on the chip to handle the signals. I have figured out how to use the ADC (I think) but I'm not quite sure how to store the results of the conversion. Nay, what to store it in? The following is my interrupt routine. Any advice on this would be helpful. 

 

<code>

ISR(ADCA_CH2_vect)
    {
        register16_t Ad2_out = ADCA.CH2RES;
        ADCA.CTRLA |= (ADC_CH2START_bm);
    }

</code>

 

 

Secondly, I wanted to know if I could route this result internally to a DAC output, I read there are some internal input pins. especially if its possible using the 'event routing' XMega series boasts. If it is possible, how to get started? I don't need the code, for, this is my school project. I just want some insight into how to go about doing it. sort of a pseudo-code, if you may!

 

Thanks again for taking the time out to reply.   

Soul

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

I'd approach this one step at a time.

 

The Xmega's are great chips, but it takes a little work to get the various sub-systems up and running individually, much less auto-internal-routing the data!

 

Does you particular Xplained PCB have an LCD?

Start by getting the LCD up and running so you can display (ASCII) text and variables.

 

Next, connect a 10K pot from Vcc to Ground, with the wiper going to the ADC input pin.

Add a 0.1 uF cap from the input pin to Ground.

 

Now work on configuring the ADC and displaying the ADC value on the LCD.

No interrupts needed or used for either of these two tasks.

 

Setting up the ADC for single ended vs differential, with or without gain, X bits, justified L or R, single shot or continuous, etc.; will all take a bit of work and reading, and trial.

 

Know that the Max ADC value = the AVref level.

So if you set an internal Vref to 1.1 V, (I haven't look at the data sheet, so I don't know what your actual options are), the the max ADC count occurs when Vin = 1.1 V.

If you set Vref to Vcc, then the max ADC count occurs with Vin = Vcc.

 

You need to get this up and running, and understand it, before you move to the next steps.

 

Next you should be able to convert, in software, the ADC reading to an input voltage.

Display both the ADC count and the ADC voltage on the display.

 

With a voltmeter, DMM, or O'scope watching the input voltage on the ADC input pin, it should match your LCD display.

You just made a voltmeter!

 

Next, you probably want to post your mic input circuitry.

The ADC on the micro will only accept a positive voltage, not a negative voltage.

Also, the mic probably puts out a very low, (microvolt), signal level.

So you need an op-amp to amplify the mic's signal level, AND offset it from Ground to Vcc/2.

 

Hopefully as a student you have access to an O'scope, if you don't have one yourself.

 

Your goal is a mic signal level of Vcc/2 with no input, and perhaps 1/2 to 1 V excursion above and below the Vcc/2 midpoint with a tone or loud speech into the microphone.

You want a big signal for the ADC to work with.

 

There are lots of mic and op-amp schematics, and breadkout boards, on the web.

 

Recall that you are looking for a 3.3 V circuit.

You don't want to worry about your circuit feeding 5 V into you 3.3 V Xmega.

 

Now its time to start working with interrupts.

The Xmega has a priority interrupt controller.

Have you studied it in call or used it yet?

 

You want to set up your ISR to fire once every X mSec, at which point you read the last ADC sample and then trigger the Xmega to take another (the next) ADC sample.

How fast do you need to sample the input signal?

 

That is part of your course, hopefully, but have a look at the Shannon - Nyquist sampling theorem.

In short, if your input signal was from 0 - 10 kHz (low end audio), then you would want to sample at a rate of at least twice 10KHz.

So for starters, sampling at 20 - 30 kHz would be reasonable.

 

BUT, the Xmega doesn't have a whole lot of memory in which to store the ADC samples.

Which finally leads to your question.

Set up an array of two-byte values to store the data.

Every interrupt you store the current value and increment a pointer into the array, pointing to the next empty slot.

 

When you get this far then we can discuss your output options, typically a small audio amplifier chip and a speaker, or an O'scope.

Setting up the DAC also takes some learning.

 

JC

 

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

 

 

Thank you so much for the quick and helpful reply. 

 

That was my initial thought process too, to test the ADC using the on-board LCD. 

 

Most of the projects at school used polling, so, not much experience with the Interrupts, but hey, that's why we do projects like these to get such exposure! :)

 

I was debating storing the results at all, why not direct them to the intended output right away? I am planning to send the audio over wifi (esp8266) to another identical circuit which would then receive and play it over to this speaker. but for now I need to get this working on single board (direct this output to the speaker connected to the DAC of XMega). So, i was hoping to utilize max sampling speed the XMega offers for 12 bit resolution (about 300kHz)? I will start off with about 50 kHz since my bandpass allows upto 20kHz of signals. I am using an active filter with a variable gain. 

 

I'm building the mic and speaker circuit from scratch. but here's the mic one as you asked. 

 

Mic Circuit

 

This is the mic Circuit Schematic. This is the mic I've used: 

 

Vcc =12V btw. 

 

http://www.digikey.ca/product-de...

 

Having some trouble to get it working tbh but It must be something silly and I'll figure it out by time my ADC and DAC are working. Thanks a lot again, I'll get to it then and will let you know when I'm ready to output!

Soul

Last Edited: Sun. Jan 15, 2017 - 12:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can make a good echo/delay for a voice or guitar using the AVR ADC.  Pink Floyd's guitarist Dave Gillmore usually used about 350 milliseconds (0.35 sec) for most of the echo on their recordings in the 1970s.  You do need to have a RAM buffer of about 20-32K for a half-second to one-second of echo.

 

 Eight bit storage is musically OK. Be sure to use the upper-eight bits of the ten-bit conversion.   The easiest way to add RAM is use a cheap 8-pin serial RAM SPI-interface IC like the 23K256.  Serial RAM has higher processing overhead than the standard parallel SRAM ICs, but that doesn't matter because the sampling rate is relatively slow.

 

To make an echo-plex: first set all the RAM location values to 0x80.  This is the no-sound, Vcc/2 bias level of the echo.  Start at address 0x0000.  Get the value at this location.  Put this value into the audio-output 8-bit DAC.  Don't use a PWM DAC, because it is too slow.  Do an ADC conversion, keep the upper 8-bits and store this value into address 0x0000.  Wait for the sampling interval.  Increment the SRAM address.   Repeat.  You can compare the SRAM address to a pre-set value to change the length of the echo.  Basically the length of the echo is the number of SRAM bytes times the sampling interval.   This ignores all the correct ways of doing ADC "right" and ignores about 95% of the topics discussed in any ADC datasheet.  But again it doesn't matter.

 

You will need analog circuitry to raise your input signal to about 80% of your ADC input voltage range.  And this input signal has to be biased at 1/2 Vcc before it gets fed into the ADC.  And you need to amplify (or more likely) decrease the output volume of the DAC to about +/- 1 volt peak-to-peak for a line-input/guitar amplifier.  But you will get a half-second delay.  "hello....(hello)".  Take the output signal, run it through a buffering op-amp and a potentiometer, and mix it into the original input signal.  Set the pot to have the signal be just loud enough to generate multiple half-second echos, but not enough to start a feedback howl.  Now you have an echo-plex: "hello...(hello)...(hello)..."

 

Guitarist Robert Fripp and Brian Eno did a lot of work with long 15-30 second echos in the late 1970s.  The public library will likely have some of these CDs.

 

An interesting variation is to fill the SRAM buffer with samples and then not jumping back to first address to get the DAC value, but start from the last SRAM address and play the samples back to the first address.    Start with 0x0000, fill to 0x7fff (32K bytes), then store/ playback from 0x7fff back to 0x0000; sweeping back and forth.   This gives a real-time "backward guitar" effect popular in the 1960s.  For example, the Beatles "I'm Only Sleeping" (1966) and Jimi Hendrix "Are You Experienced" are full of backward guitar sounds make by playing tapes in reverse.  Shorter SRAM buffers actually work better because there is less time from the note being played and the pseudo-backwards version of being sounded.  

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

Simonetta wrote:

You can make a good echo/delay for a voice or guitar using the AVR ADC.  Pink Floyd's guitarist Dave Gillmore usually used about 350 milliseconds (0.35 sec) for most of the echo on their recordings in the 1970s.  You do need to have a RAM buffer of about 20-32K for a half-second to one-second of echo.

 

 Eight bit storage is musically OK. Be sure to use the upper-eight bits of the ten-bit conversion.   The easiest way to add RAM is use a cheap 8-pin serial RAM SPI-interface IC like the 23K256.  Serial RAM has higher processing overhead than the standard parallel SRAM ICs, but that doesn't matter because the sampling rate is relatively slow.

 

To make an echo-plex: first set all the RAM location values to 0x80.  This is the no-sound, Vcc/2 bias level of the echo.  Start at address 0x0000.  Get the value at this location.  Put this value into the audio-output 8-bit DAC.  Don't use a PWM DAC, because it is too slow.  Do an ADC conversion, keep the upper 8-bits and store this value into address 0x0000.  Wait for the sampling interval.  Increment the SRAM address.   Repeat.  You can compare the SRAM address to a pre-set value to change the length of the echo.  Basically the length of the echo is the number of SRAM bytes times the sampling interval.   This ignores all the correct ways of doing ADC "right" and ignores about 95% of the topics discussed in any ADC datasheet.  But again it doesn't matter.

 

You will need analog circuitry to raise your input signal to about 80% of your ADC input voltage range.  And this input signal has to be biased at 1/2 Vcc before it gets fed into the ADC.  And you need to amplify (or more likely) decrease the output volume of the DAC to about +/- 1 volt peak-to-peak for a line-input/guitar amplifier.  But you will get a half-second delay.  "hello....(hello)".  Take the output signal, run it through a buffering op-amp and a potentiometer, and mix it into the original input signal.  Set the pot to have the signal be just loud enough to generate multiple half-second echos, but not enough to start a feedback howl.  Now you have an echo-plex: "hello...(hello)...(hello)..."

 

Guitarist Robert Fripp and Brian Eno did a lot of work with long 15-30 second echos in the late 1970s.  The public library will likely have some of these CDs.

 

An interesting variation is to fill the SRAM buffer with samples and then not jumping back to first address to get the DAC value, but start from the last SRAM address and play the samples back to the first address.    Start with 0x0000, fill to 0x7fff (32K bytes), then store/ playback from 0x7fff back to 0x0000; sweeping back and forth.   This gives a real-time "backward guitar" effect popular in the 1960s.  For example, the Beatles "I'm Only Sleeping" (1966) and Jimi Hendrix "Are You Experienced" are full of backward guitar sounds make by playing tapes in reverse.  Shorter SRAM buffers actually work better because there is less time from the note being played and the pseudo-backwards version of being sounded.  

 

 

Well, thank you. I don't know how or why you posted about guitar amplification but this is some awesome information for my friend who's working on a Guitar tuner using Arduino! :) Thank you for your time! :) 

Soul

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

DocJC wrote:

I'd approach this one step at a time.

 

The Xmega's are great chips, but it takes a little work to get the various sub-systems up and running individually, much less auto-internal-routing the data!

 

Does you particular Xplained PCB have an LCD?

Start by getting the LCD up and running so you can display (ASCII) text and variables.

 

Next, connect a 10K pot from Vcc to Ground, with the wiper going to the ADC input pin.

Add a 0.1 uF cap from the input pin to Ground.

 

Now work on configuring the ADC and displaying the ADC value on the LCD.

No interrupts needed or used for either of these two tasks.

 

Setting up the ADC for single ended vs differential, with or without gain, X bits, justified L or R, single shot or continuous, etc.; will all take a bit of work and reading, and trial.

 

Know that the Max ADC value = the AVref level.

So if you set an internal Vref to 1.1 V, (I haven't look at the data sheet, so I don't know what your actual options are), the the max ADC count occurs when Vin = 1.1 V.

If you set Vref to Vcc, then the max ADC count occurs with Vin = Vcc.

 

You need to get this up and running, and understand it, before you move to the next steps.

 

Next you should be able to convert, in software, the ADC reading to an input voltage.

Display both the ADC count and the ADC voltage on the display.

 

With a voltmeter, DMM, or O'scope watching the input voltage on the ADC input pin, it should match your LCD display.

You just made a voltmeter!

 

Next, you probably want to post your mic input circuitry.

The ADC on the micro will only accept a positive voltage, not a negative voltage.

Also, the mic probably puts out a very low, (microvolt), signal level.

So you need an op-amp to amplify the mic's signal level, AND offset it from Ground to Vcc/2.

 

Hopefully as a student you have access to an O'scope, if you don't have one yourself.

 

Your goal is a mic signal level of Vcc/2 with no input, and perhaps 1/2 to 1 V excursion above and below the Vcc/2 midpoint with a tone or loud speech into the microphone.

You want a big signal for the ADC to work with.

 

There are lots of mic and op-amp schematics, and breadkout boards, on the web.

 

Recall that you are looking for a 3.3 V circuit.

You don't want to worry about your circuit feeding 5 V into you 3.3 V Xmega.

 

Now its time to start working with interrupts.

The Xmega has a priority interrupt controller.

Have you studied it in call or used it yet?

 

You want to set up your ISR to fire once every X mSec, at which point you read the last ADC sample and then trigger the Xmega to take another (the next) ADC sample.

How fast do you need to sample the input signal?

 

That is part of your course, hopefully, but have a look at the Shannon - Nyquist sampling theorem.

In short, if your input signal was from 0 - 10 kHz (low end audio), then you would want to sample at a rate of at least twice 10KHz.

So for starters, sampling at 20 - 30 kHz would be reasonable.

 

BUT, the Xmega doesn't have a whole lot of memory in which to store the ADC samples.

Which finally leads to your question.

Set up an array of two-byte values to store the data.

Every interrupt you store the current value and increment a pointer into the array, pointing to the next empty slot.

 

When you get this far then we can discuss your output options, typically a small audio amplifier chip and a speaker, or an O'scope.

Setting up the DAC also takes some learning.

 

JC

 

Hey! 

 

Thanks again for the help. I have the ADC working, although, having a bit of trouble with Interrupts. :/ 

 

I feel I'm ready to discuss the power options in the meanwhile. Also, If you could advise in interfacing and transferring this audio data over esp8266, in a similar fashion, I'll really be grateful! :) 

 

Thank you very much once more. 

Soul

Last Edited: Fri. Feb 3, 2017 - 03:21 AM