Shop OBEX P1 Docs P2 Docs Learn Events
Need help with MCP3208 ADC and multiple cogs — Parallax Forums

Need help with MCP3208 ADC and multiple cogs

One Who WaitsOne Who Waits Posts: 7
edited 2007-11-05 18:31 in Propeller 1
Hello, guys!
I'm an absolute newbie, but it just happens that I really have to construct not so simple (for me) device.)
Briefly, I need to have three simultaneous processes, started in different cogs: first one will act as 30us width /10 Hz square pulse generator and the rest two connected to 2 MCP3208 (or 04, 01, doesnt really matter) chips. The idea is to measure very short signal (~100 ns) that's triggered (with a small delay) with the rising edge of the 30 us pulse using two synchronous detectors connected to MCP3208's. By far, I've been experimenting with the MCP3208 object from ObEx. The problem is that it uses assembly language (which I don't understand at all). According to the datasheet, conversion time depends on the sampling rate. I assume that in our case it's it's quiet high (~100 ksps), which makes it quiet difficult to synchronize. Could you please help me to figure out, how one could make the sampling time ~ 20-60 us and sampling rate 10 ksps. Just adding a 100 ms delay wouldn't change sampling time. I also had problems with starting the main procedure from MCP3208_test object in a new cog. Could this be because of the assembly part of it or shared variables? I'm really looking forward to your replies. If any one of you possibly have an assembler-free object for this chip, could you please share it with me. I know that SPI is a·really simple interface, but right now I just have no time to go throu it.
Thanks very much.
···

Comments

  • Erik FriesenErik Friesen Posts: 1,071
    edited 2007-10-25 15:01
    I'm not sure I totally understand what you are trying to do but I think If you just allow the assembly program to run like it is written and then access the variables through spin you might be able to do what you want to.· You will have to be carefull with your spin program so that it is quick enough.· To access the variable the quickest I think you will have to pass the address of the array back to the main program.· It will look something like this. (return @variable).· Then you access it similar to what the mcp3208 program is doing in its spin part.· The mcp3208 object will be in the background sampling at its own rate and you just access the the variables at the rate you desire.·
  • One Who WaitsOne Who Waits Posts: 7
    edited 2007-10-25 20:48
    Thanks very much for reply, still the way you've proposed is completely opposite to what I'm willing to do), for I don't want the assembler part run freely rather than it should be sync'd with another procedures in other cogs. Anyway, I found an easier way). There's LTC1298 object at ObEx for a 12 bit ADC with SPI. I managed to make it wark with the MCP3208, still one thing bothers me. According to specs, their SPI routines should be completely identical except for the Din information. So I changed Din configuration bits like that: CH0 = %00011, but it didn't work. Then, in PRI write method I put "repeat i from 13 to 0" instead of "repeat i from 12 to 0". This time everything works fine, but I really don't get it. Seems like MSB is shifted by one bit, but I'm not quiet sure about that. Anyway, this "spin-only" object is so much easier to understand. Again, any input's welcomed).
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2007-10-25 21:21
    The way you would syncronize the procedures within the cogs would be using the cnt register.· I think the faster you can sample the more accurate the mcp3208 will be.·
  • mynet43mynet43 Posts: 644
    edited 2007-10-25 23:32
    I'm not sure exactly what you're trying to accomplish. However, if you want to run the MCP3208 in a deterministic mode, I think I have what you need.

    I have a modified version of MCP3208.spin that does all of the work in assembly language.

    At 80 MHz it always takes exactly 6624 clock cycles to retrieve a single adc sample, using the MCP3208 chip specs for clock frequency. The original code varies between 2500 and 16000 clock cycles because of the way it's written.

    For an average of 10 samples, the new code takes 21,776 clock cycles. The original code takes about 135,000 clock cycles. That's more than 6 times as fast.

    Notice that it can take a 10 sample average in a little over 3 times what it takes to get a single sample.

    I've used it for a while and it seems to be very reliable. See the attached pics.

    Let me know if you'd like the code.

    Jim
    2560 x 1920 - 639K
    2560 x 1920 - 506K
  • Jim FouchJim Fouch Posts: 395
    edited 2007-10-26 02:43
    Jim I would love a copy of your improved driver. I have a project that I'm using this ADC and a faster driver would be great.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jim Fouch

    FOUCH SOFTWARE
  • mynet43mynet43 Posts: 644
    edited 2007-10-26 15:54
    Here's a copy of the fast MCP3208.spin.

    It has exactly the same calling sequence as the original.

    There are a few operational changes, listed below:

    ''MCP3208_fast.spin
    ''
    ''*****************************************************
    ''*  MCP3208 12-bit/8-channel ADC Driver              *
    ''*  Works w/indiv channel on chip rather than all 8  *
    ''*  Provides single sample or average of n samples   *
    ''*  Provides single mode only, no differential mode  *
    ''*  Does not provide DAC output like original code   *
    ''*****************************************************
    
    



    For a 10 sample average it is 6 times faster than the original.

    The output is deterministic, in that it takes the same number of cycles each time it is called.

    It there is enough interest, I'll post it in the object exchange.

    Jim
  • One Who WaitsOne Who Waits Posts: 7
    edited 2007-10-26 16:24
    Thanks very much for sharing, Jim.·Ah, this low-level stuff is killing me). Anyway, I've managed to change another ADC's object to work with MCP3208. It's totally high-level and since I don't need high sample rates,·works perfectly for me. Right now I'm trying to sync 3 different processes in 3 cogs: 2 ADC objects working in·parallel with 2 different chips·and one "square wave generator" cog. The whole idea is that·rising edge of this square wave triggers with unknown delay (~100-500 ns, maybe even 1 us)·another very short·signal (like 20 - 100ns) which I want to·measure. Right now, the difficulty (at least for me) is to make this·signal fit into·tsample of·ADC, which in my case it's ~ 4-6·us.·How do you measure clock cycles required·for·the method?
  • mynet43mynet43 Posts: 644
    edited 2007-10-26 17:26
    If you're trying to measure an analog signal in the 20-100ns range, you'll need something faster than the MCP3208.

    The spec sheet lists a maximum sample rate of 100,000 samples per second, which is one sample every 10uS.

    10uS is 10,000ns, so what you need isn't even close to what this chip can supply.

    I assume you're trying to "see what the signal looks like", so you'd need at least several samples within your sample period of 10-100ns.

    Am I missing something?

    Jim
  • One Who WaitsOne Who Waits Posts: 7
    edited 2007-10-26 19:02
    Well, actually, yes. I don't really need to see it's shape or envelope or something. What I really need is to measure it's integral energy or, actually, its integral power density. It will be stored on a Csample of ADC's sample-and-hold subunit during tsample. And even if there're any mistakes in this procedure, they will be eliminated by normalizing the result using parallel ADC's samples. So my only concern is to fit (with all inevitable delays) this signal into tsample every time the conversion takes place.
  • mynet43mynet43 Posts: 644
    edited 2007-10-27 00:29
    Maybe if you could sketch a picture of the waveform you're trying to capture, with a time scale, it would enable us to better understand exactly what you're trying to accomplish. Right now, I still can't see how the MCP3208 could do what you need.

    To get the power density or integral energy I think you need the area under the curve. I don't see how you can get this without getting several samples during its cycle. The chip does not take an instantaneous sample, it takes a certain amount of time for it to derive the sample and this time may be longer than your entire sample.

    Sorry to seem dense.

    Jim
  • One Who WaitsOne Who Waits Posts: 7
    edited 2007-10-27 09:26
    Yes, you're right about the area bounded by signal's curve. That's math. In real life, what we get is a full charge flowed throu the circuit during tsample. It's consists of "signal's charge" and some amount of "noise charge". The last one is dependent an many factors, even on tsample interval length, but can be eliminated by averaging and other techniques (it's a different story). That's why it doesnt really matter if tsample is one order longer than tsignal - consider that signal curve's ordinate is 0 outside those 100 ns, so it won't add to the integral. Anyway, I've been using that method for quite a long time (with AD7893) and it seems to be appropriate. See attached picture for the idea. Those two 20 us pulses with 100 us delay·at P0/P1 pins of Propeller are required to trigger the·the Signal. I guess I could use waitpeq·P1 = 1 and add a delay·to trigger the conversion.·But I need to know·how long does·Din·sequense take to calculate this delay. Maybe, you'll have a better idea.
    800 x 600 - 99K
  • mynet43mynet43 Posts: 644
    edited 2007-10-27 15:38
    Thanks for posting the picture of the signal superimposed on the MCP3208 timing diagram, that really helps.

    I have a couple of questions:

    1. You didn't say what frequency you are clocking the MCP3208 at. If your drawing is to scale, then it looks like the 20us pulse is the same as the clock frequency, which would be 50KHz.

    2. You didn't say what voltage you're using to power the MCP3208. If you're using 3.3V, then the clock frequency is limited to 1.0MHz. If you're using 5.0V then the clock frequency can be set to 2MHz.

    Suggestions:

    1. Use a scope to determine the timing. You should be able to trigger on CS going negative. This will let you easily adjust the timing parameters.

    2. I think your goal should be to maximize the ratio of t-signal to t-sample. Since the ADC is charging a capacitor, maximizing this ratio will allow it to charge higher during t-sample and give you a better sample.

    You said your t-signal is 20-100ns, let's say it's 50ns as an example.

    If your clock frequency is 50KHz, then t-sample is 30us and the ratio is 0.05us/30us = 0.0017.

    If you can use 5.0V and 2MHz clock frequency, then t-sample is 0.75us and the ratio is 0.05us/0.75us = 0.067, which should give you a better sample.

    I hope this helps.

    Jim
  • One Who WaitsOne Who Waits Posts: 7
    edited 2007-10-28 13:59
    Thanks for reply.
    1) The picture isn't really to scale. In fact, it's rather difficult to speak about clocking with this object for according to scope, it provides different clock periods at different stages of conversion).
    2) I'm using 3,3 V supply. Didn't want to bother with output levels of MCP3208. By the way, do I have to do anything to connect it to Prop in case of 5 V supply, for the output logic 1 level would be also almost 5 V? Like voltage dividers or something?
    Anyway, I measured the last Din clock cycles and it seems that tsample with this object exceeds 50 us! So I had to quit using it. Now I'm using the standard object for MCP3208. I believe you understand it perfectly. Is it possible to estimate time interval from calling "in" method to the "start" of tsample? So I could add a required delay.
  • deSilvadeSilva Posts: 2,967
    edited 2007-10-28 14:39
    @one who waits: I did not follow this thread for the last days, as I did not understand your real problem upto now..
    From what you say, you want to meassure the energy of a very small pulse of undefined shape, but aproximable by a square pulse of around dT = 60 ns +/-40 ns . What you want to learn is dT*Umean.

    An A/D converter is a very unapt mean for this... As mynet remarked you need a sample rate of at least 5 ns = 200MHz for it... These exist but don't look at the price tag...

    The standard procedure for this is to let electronics do their fast working in the disguise of a tiny cap.
    Cut away all the lower MHzs by a suitable high pass and catch the pulse (=charge) with a low pass, buffer between both filters with a high impedance output (common gate) circuit.

    Note that this is basically an "integrator" so you have to compute the difference between two (slow) samples from yor ADC. There is the noise, steadily ramping up, and the signal, noticable by a jump and its value

    Post Edited (deSilva) : 10/28/2007 8:14:52 PM GMT
  • mynet43mynet43 Posts: 644
    edited 2007-10-28 20:07
    @One Who Waits

    You asked what to do if you use a 5V supply on the MCP3208. If you do this, make both the supply and the reference pins 5V. Then simply use a 1K resistor on your Din/Dout line between the Prop and the MCP3208. This will limit the current and should work great.

    This would allow you to use the 2MHz clock and get a usable reading for your signal.

    Let me know if you need help with the 2MHz clock to the SPI interface. I just posted a fast MCP3208 routing to the object exchange. It operates at a 1MHz clock to accommodate the 3V3 voltage restriction. I can probably supply you a 2MHz version if you want it. I've tested the chip at even higher clock frequencies and it works great.

    Jim
  • One Who WaitsOne Who Waits Posts: 7
    edited 2007-11-05 18:31
    Thanks very much for support. I guess I don't really need faster object for I've just finished setting up my device. I was able to use 1 GHz·Tektronix scope, so I could alter any delays I had to.
Sign In or Register to comment.