Shop OBEX P1 Docs P2 Docs Learn Events
ADC and DAC example — Parallax Forums

ADC and DAC example

cgraceycgracey Posts: 14,155
edited 2007-03-05 14:03 in Propeller 1
I did some experimentation yesterday to see how well (or if at all) the sigma-delta ADC concept works on the Propeller's CTR modules (each of the 8 COGs has two CTRs). At first, it was a disaster, like Peter had found by trying to do it on the breadboard. The trick was building the RC integrator VERY close to the pins. This circuit has an analog 'setup time' requirement that is on the order of nanoseconds. The breadboard implementation had enough parasitic C and L that this window got missed. Look what happens, though, when it's done in SMT near the pins. The picture below shows a 1kHz sine wave input on top, then the digitized and re-output version on the bottom. One COG is using its CTRA to do the sigma-delta ADC and its CTRB to do delta modulation for the DAC function. It's doing 11-bit conversions at 39k samples per second:

·attachment.php?attachmentid=40855

Here is the assembly code that makes it all happen:

attachment.php?attachmentid=40856

I've inlcuded the Spin file for this, too. It actually does a little more than shown, as it outputs hex samples to a TV for viewing.



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Chip Gracey
Parallax, Inc.

Post Edited (Chip Gracey) : 3/15/2006 11:24:15 PM GMT
800 x 600 - 64K
800 x 1013 - 89K

Comments

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2006-03-15 21:38
    Thanks for this, Chip, and the nice Propeller font circuit diagrams. That is so cool. I'll want to try out the circuit too, when I get a chance. I'm thinking about a project we did recently that monitors the size and velocity of individual raindrops and logs the individual events They are recording 50k to 100k events per rainstorm. The scheme involves a duration detector that gives velocity and an analog peak detector that gives drop diameter. (based on a laser curtain). The propeller might be able to do it with minimal external analog parts and handle the logging in the background.

    I'm still wondering about the issue with the breadboard that you and Peter observed.
    -- 1) will it work on the breadboard with a slower clock, say pll4x, albeit with slower response?

    -- 2) Still puzzled about the circuit model of why it doesn't work at 80mhz except with the SMT hack? I appreciate that inductance out from pin 8 and pin 9 (in series with every branch in fact) could make a "chaotic attractor" from multple resonances between the capacitors and the inductors. But it just doesn't add up.

    The voltage at the capacitor junctions should be practally DC compared with 80mhz. The capacitance of the breadboard is effectively in parallel with the integration capacitors and would be swamped. The only really high speed signal is the one coming out at the sigma-delta feedback pin A8 on the righthand side of the resistor, pushing pulse of current through the resistor into the capacitor(s). Inductance in that trace and resistor lead would slow down the rise time of the current pulse, but it couldn't really resonate with the capacitor because of the low Q due to the 1k resistor, and the the inductive impedance of that inch of trace would certainly be much less than 1kohms, so it couldn't have too much effect on the current. What I am looking at as a possible culprit is the *mutual* inductance & capacitance between the traces to A8 and A9, which run parallel for one inch and then up through the breadboard circuitry. If that is the case, a fat pulse of voltage could be induced directly from A8 and cause A9 to ring and give false triggering on A9. If that is the case, one way (the best) to address it is the SMT approach right by the pins. Perhaps a workaround would be to use pins that are further apart on the chip, or to use a guard trace or EM shield in between the traces, or ??.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • cgraceycgracey Posts: 14,155
    edited 2006-03-15 22:55
    Tracy,
    I think you just explained what the 'breadboard' problem really is: inductive and/or capacitive coupling between the 'in' and 'out' signals. This explanation makes better·sense than what I was saying. I'm going to try far-away pins to see what happens on the breadboard...
    Tracy Allen said...

    What I am looking at as a possible culprit is the *mutual* inductance & capacitance between the traces to A8 and A9, which run parallel for one inch and then up through the breadboard circuitry. If that is the case, a fat pulse of voltage could be induced directly from A8 and cause A9 to ring and give false triggering on A9. If that is the case, one way (the best) to address it is the SMT approach right by the pins. Perhaps a workaround would be to use pins that are further apart on the chip, or to use a guard trace or EM shield in between the traces, or ??.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • cgraceycgracey Posts: 14,155
    edited 2006-03-15 23:21
    Tracy,

    Indeed, adjacent pins on the breadboard behaved worse than far-apart pins. In any case, though, I·couldn't get things operating very well on the breadboard. It just introduces too much parasitic L and C. Adjacent pins are fine, though,·as long as you have a·tight layout.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • pjvpjv Posts: 1,903
    edited 2006-03-16 05:54
    Hi Chip;

    I still have more testing to do, but using the breadboard for the A/D seems to be OK now. I am running 12 bit and 16 bit versions in assembler cog, not using the CTR helpers (have not had time to learn/experiment with those yet), using a basic 2 uSec loop tick.

    I have this running, using a second assembler cog to spit out the values serially in SPI form, that is data together with a 10 usec clock, so I can observe the values on a scope.

    I also added a Spin (hooray, my first program), to calculate a 3/4 and 7/8 averaged filter values, and then also calculate the instantaneous difference from that average. All these three parameters are spit out via the "SPI" bits.

    I get an instability of 3 counts in the instantaneous reading.

    I would want to say, my Propeller ability is not extensive, but I AM learning, and I think I'm getting there...... the SX took a while too to become proficient.

    For anyone who cares, the attached code is by no means deemed to be optimum..... more like barely working, and not very "clean". But at least there is progress.



    Cheers,

    Peter (pjv)
  • cgraceycgracey Posts: 14,155
    edited 2006-03-16 07:01
    Peter,

    I'm excited that you've got this working. An instability of three counts is really good for 12-16 bits, I think.

    Seeing your software made me realize that everything the CTRs do (with the exception of the PLLs) can just as well be·done in software, albeit at a slower rate. The CTRs are like 'helpers' that can perform simple, repetitive operations to free the COG for other processing. They would automate your ADCLoop and make it 160x faster. I wonder if any special performance can be realized by ganging two CTRs in delta-sigma mode onto the same input signal.

    I noticed in your ADCLoop the following sequence:

    ············· mov······ Temp1,outa····················· 'read the output latches
    ······· if_z· or······· Temp1,#ADCOutPin··············· 'prep turn adc output on
    ······· if_nz and······ Temp1,#!ADCOutPin·············· 'prep turn adc output off
    ············· mov······ outa,Temp1····················· 'transfer to output

    This could be reduced to a single 'muxz outa,#ADCOutPin' instruction.

    I've been thinking about what can be done now that we have audio-bandwidth A/D conversion. We could execute Goertzel algorithms to make very narrow frequency sensors. Then we could output a DAC signal on one pin, send it through a transducer and through some mechanical medium, and then receive it back into another ADC circuit to check amplitude and phase differences. We could make a sweeper that finds resonances and anti-resonances. There have got to be some interesting applications. Maybe we could make something that would find the top three resonant·frequencies of a wine glass, and then output those frequencies in order to break it. Maybe we could make some wierd thing that creates standing wave patterns in water and then switches between them to form impossible-looking phenomena.

    We could at least make audio spectrum analyzers and and musical instrument tuners. We could output video·for feedback.

    At 8-bit sample quality using the CTRs, you can do 312k ADC conversions per second at 80 MHz. With that, we could make a 100kHz scope with a function generator and component tester built in. It could also have some kind of DMM function and a 5 MHz 16-channel logic analyzer. You could make a whole test instrument out of just the Propeller and some passives.

    I was talking to Andre LaMothe for a while last night and he was telling me how they use multiple COGs to render video without a bitmap. They have one COG use its video generator, and 1, 2, or 4 other COGs buffer up scan lines to be output, as needed. They work off algorithms, not raw memory. He's demonstrated NES-level graphics so far and he said he could do 'Doom' on the Propeller. This algorithmic display stuff is really neat because it uses very little RAM. For example, say you want a vector display. The obvious thing to do is make a bitmap that you draw lines into. Then, you double-buffer it so that you have a workspace and a displayspace. Too much memory! If you just had a list of line endpoints, and COGs sifting through this list in real-time as scan lines were rendered, the only RAM required would be for the endpoint coordinates. This frees up ~98% of what would have been display memory. This is really exciting to me, because it means that graphics memory usage will be reduced dramatically, and at the same time, all sorts of wild rendering techniques can be used to generate full-screen motion, with every frame completely unique. This is cool, not to mention completely unanticipated during the chip development!

    pjv said...

    Hi Chip;

    I still have more testing to do, but using the breadboard for the A/D seems to be OK now. I am running 12 bit and 16 bit versions in assembler cog, not using the CTR helpers (have not had time to learn/experiment with those yet), using a basic 2 uSec loop tick.

    I have this running, using a second assembler cog to spit out the values serially in SPI form, that is data together with a 10 usec clock, so I can observe the values on a scope.

    I also added a Spin (hooray, my first program), to calculate a 3/4 and 7/8 averaged filter values, and then also calculate the instantaneous difference from that average. All these three parameters are spit out via the "SPI" bits.

    I get an instability of 3 counts in the instantaneous reading.

    I would want to say, my Propeller ability is not extensive, but I AM learning, and I think I'm getting there...... the SX took a while too to become proficient.

    For anyone who cares, the attached code is by no means deemed to be optimum..... more like barely working, and not very "clean". But at least there is progress.



    Cheers,

    Peter (pjv)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.

    Post Edited (Chip Gracey) : 3/16/2006 7:04:39 AM GMT
  • pjvpjv Posts: 1,903
    edited 2006-03-16 17:13
    Hi Chip;

    Thanks for the tip! I didn't realize we HAD a MUXZ....although I had aleady used the MUXC for similar purposes.

    I also realized after posting that my filter has a flaw in it, and can be more easily done in the ADC assembler cog, and hence each reading will contribute to the average, rather than only those that are available when the Spin algorithm was done with the previous value.

    Just for fun, I'm going to make the changes, and for comparison add a monitor bit to my old program to see how often the Spin averager had been taking a new value.

    Also I found it useful to use the semaphores for "token passing" between the ADC cog and the SPI cog. This is not so easy to accomplish with I/O port bits. Ram bits is another option ablbeit slower.

    I appreciate your comments and wonderful musings about weird applications........ I'm sure gonna have a go at 'em !

    Cheers,

    Peter (pjv)
  • rprp Posts: 2
    edited 2006-08-09 15:45
    Ok, maybe I'm thinking about pushing this thing a little too hard. I saw the Propeller for the first time this past weekend (cool! [noparse]:D[/noparse]). I'm curious if you think it might be possible to build a software defined radio at around 13.5Mhz without using an external A to D converter. I'm thinking two options. The first is everything but the antenna and matching would be done in software - all downconverting and demodulation. Second option would be to build the first IF in analog to downcovert to around 1Mhz, then do the rest in the Propeller.

    It appears that all of the A/D you have discussed in you software implementations have been in the sub-megahertz range (most appears to be in the single digit kilohertz or sub-kilohertz range). So, how far up do you think it could be pushed?

    Thanks,
    Robert (rp)
  • IanMIanM Posts: 40
    edited 2006-08-10 01:41
    Hi Robert, my understanding of the A/D converter described is that the sampling rate depends on the dynamic range. For example, a sampling rate of 10KHz will give you a dynamic range of log2(80,000,000/10,000) about 13 bits or 78db.

    I've been thinking of using the propeller in an SDR myself. The simplest I could come up with for a 0-30MHz radio consists of a 30MHz low pass filter (7 poles seems about right), followed by a diode mixer (eg SBL-1 or equiv) feeding a 40MHz diplexor. The signal is converted to baseband using a quradrature sampling detector (SD) at 40MHz. This could be implemented using a 74ac74 and a 74hc4066. The 74ac74 would be clocked by complementary 80MHz signals from the propeller - thus producing a 40MHz quadrature signal for the SD. A very low noise op-amp would follow the 4066.

    To get the signals into the propeller assuming a 10Khz (or so) sampling rate you would need a LPF to eliminat the alias. An 8 pole butterworth at 3KHz in each of the I/Q channels would do the job. For tuning, the propeller would need to generate a 40MHz-70Mhz signal to drive the mixer. There have been discussions on how pure the signal is in this range but lets assume it's ok for a simple receiver. Anyway, with a bit of software intelligence perhaps the frequencies with the largest spurs can be avoided.

    The propeller would then need to do the demodulation. I'm not sure if it could be done using an FFT, but i'm pretty sure it could be done using a Hilbert transform (to shift one of the channels 90 degrees, the other channel needs to be delayed by about half the poles used for the Hilbert - too easy). This would enable LSB/USB/CW. For AM you can take the square root of the sum of the squares of I and Q (this signal could also be used to generate a digital AGC signal). Finally you could have an FIR on the output to give you some bandwidth control. The D/A should be easy smile.gif

    Once the hardware is organise the fun part is the software!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ian Mitchell
    www.research.utas.edu.au

    Post Edited (IanM) : 8/10/2006 3:21:34 AM GMT
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2006-08-10 11:05
    Chip Gracey (Parallax) said...
    P This is cool, not to mention completely unanticipated during the chip development!

    I just think that's fantastic, when something you have created can suprises you. The propeller is so powerful it is just a matter of being able to see the things is can do, the counters are something that I am new to but you can bet I am going to learn a lot about them!

    Graham
  • Ching LinChing Lin Posts: 11
    edited 2007-03-04 16:00
    Hi,

    I am trying to use Chip's ADC.spin to generate a square wave from a second cog.
    1) The square wave will be running at a fix frequency if the input sine wave is not available or out of a set frequency range.
    2) The square wave will synchronize to the input sine wave only to a set frequency range

    Thanks in advance
    Ching Lin
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-04 16:31
    Ching Lin,
    You should start another thread with your question/comment since it's not really a continuation of the original subject.

    Are you asking how to do what you want? If so, you're going to have to give much more information like frequency range, response time, signal levels, etc.
  • Ching LinChing Lin Posts: 11
    edited 2007-03-04 17:07
    Mike,

    I have started another thread "Synchronized square wave output".

    Thank you so much.
    Ching Lin
  • KlossKloss Posts: 43
    edited 2007-03-05 14:03
    Guys,

    what you've observed is absolutely normal for breadboards and microcontrollers
    in DIP packages.
    One example:
    If you read the datasheet of an Atmel ATMega16, you'll notice that Atmel does not
    guarantee 10 Bits performance of the ADC for the DIP version of the microcontroller.
    Full 10 Bits are only guaranteed for the TQFP and MLF variants.
    And it is clear why this is the case. The ADC input has a high impedance and the
    trace from the pin to the silicon chip is just too far away from signal ground.
    Therefore it is susceptible to all kinds of EMI. Either from the microcontroller itself
    or from the outside.
    This above mentioned microcontroller even has a special power down mode, that
    stops the microcontroller core while the A to D conversion is running, to reduce
    noice generated by the microcontroller itself.

    As the cog that does the conversion is always running at full speed, you cannot
    achieve the signal/noise ratio that you would expect from signal theory.
    You should even see higher noise levels with the start of additional cogs.

    Best regards
    Karl
Sign In or Register to comment.