Analog Comparator falling edge setup

Somewhere I heard, that interrupts aren't allowed within interrupts.

You can nest interrupts. But that's not for the faint of heart.

In your case, the ACI flag will be set while the timer isr is being serviced. The execution will return to where it was before the timer isr was executed, and then jump right back to the analog comparator isr (assuming no other interrupt flags are set).

I'm using Timer1 to generate an interrupt every Xµs that triggers the pulse for the comparator.

That's a weird set up.

dhenry:

I'm using Timer1 to generate an interrupt every Xµs that triggers the pulse for the comparator.

That's a weird set up.

The pulse controls external circuitry and the result of that circuit(very fast) triggers the comparator interrupt. Still weird? How could I improve it?

So the timer will trigger an external device to create a voltage which the analog comparator is going to compare against?

What does the whole thing do?

dhenry:
So the timer will trigger an external device to create a voltage which the analog comparator is going to compare against?

What does the whole thing do?

Measure the ESR of a cap

I assume that you aren't using a bridge here.

The typical approach then is to charge up a fully depleted cap and measure the current during the initial charge up. The comparator is probably not a very good tool for this.

Unless you have a different approach?

dhenry:
I assume that you aren't using a bridge here.

The typical approach then is to charge up a fully depleted cap and measure the current during the initial charge up. The comparator is probably not a very good tool for this.

Unless you have a different approach?

I feed the DUT with a constant current(chopped by the generated pulse), amplify the generated voltage over the DUT and compare it to the voltage of a reference cap that is being charged by a constant current(==> linear rising voltage). If you want to read more, here's a link: http://members.ozemail.com.au/~bobpar/k7214.pdf I basically just added some stuff I wanted and converted it to be Arduino based.

But my question was if you know a better way with only one interrupt :wink:

But my question was if you know a better way with only one interrupt

I think his approach is quite convoluted - C10 for example only serves to tell time, which the mcu can do with ease.

The basic theory here is that when you charge up a capacitor with a constant current, the voltage rise

deltaV = I * Tc / C, assuming deltaV is sufficiently small and ESR is sufficiently small.

When you discharge, the residual voltage at Td is

Vd = deltaV * exp(-Td / (ESR * C)).

So after each charge/discharge cycle, the voltage across the capacitor has gone up by Vd.

If, after n such cycles, the voltage across the capacitor is V, you have

V/n = (I * Tc / C) * exp (-Td / (ESR * C)), assuming of course V is sufficiently small.

If you know V, n, I, Tc, Td, C, you can solve for ESR from the above.

You can take his hardware, and you can rewrite the software:

  1. charge the capacitor at I for Tc;
  2. discharge the capacitor for Td;
  3. go back to 1 for n times;
  4. measure the voltage across the capacitor, V;
  5. calculate ESR.

No need to have a comparator.

The comparator(and C10) is essentially there for an extremely fast analogRead(), which otherwise wouldn't be possible fast enough.
The goal of an ESR meter is to make measurements in circuit possible and if you charge the capacitor you'd activate other stuff in there.

dhenry:
If you know V, n, I, Tc, Td, C, you can solve for ESR from the above.

Where should the µC know C from? I don't want to enter it every time.

Anyhow, can I improve my software solution or do I require two interrupts, without changes to the way the measurement is done?

The comparator(and C10) is essentially there

No.

Where should the µC know C from?

The meter you are trying to build does not measure ESR: it provides an indication of ESR, in conjunction with a known C.

Anyhow, can I improve my software solution or do I require two interrupts, without changes to the way the measurement is done?

Yes. This would be what I would do:

  1. measure the voltage on the capacitor, V0;
  2. charge up the capacitor for a known period of time, Tc;
  3. measure the voltage on the capacitor, V1; C = (V1-V0) / (I * Tc);
  4. discharge the capacitor for a known period of time, Td;
  5. measure the voltage, V2: V2 = V1 * exp (-Td / (ESR * C)), solve for ESR.

Done.

It uses the same hardware.

Somehow I knew that I shouldn't have said what I'm building because there is always someone who just wants to argue instead of helping someone.
Btw, the Meter has been sold tens on thousands of times (as a kit and prebuild) and is still being sold, so the method of "indication" can't be too wrong.

daywalkerdha:
Somewhere I heard, that interrupts aren't allowed within interrupts. Is that true? If the Arduino "remembers" that there was another(different) interrupt during the timer interrupt and executes it afterwards, that would be fine ...

It wouldn't work very well if it could only handle one interrupt source at a time. Yes it will remember interrupt events. The ISR will not be entered until the current one completes, and one more instruction is executed. Then the highest priority outstanding interrupt (if any) will be serviced.

Thanks!

I have another question on timing inside an interrupt. Currently a

bitWrite(PORTD, measurementRange, 0);

is just called multiple times inside a timer interrupt to make a pulse with a width of somewhere between 4µs and 15µs(adjustable) because i read here » Pin I/O performance » JeeLabs that it takes about 1µs to execute a bitWrite(). Is there a better way for such short timings? It doesn't have to be that precise, just the same amount of delay every time once it's set.

You could call delayMicroseconds instead, but I'm not sure what the minimum delay you can get with it is.

dc42:
You could call delayMicroseconds instead, but I'm not sure what the minimum delay you can get with it is.

On the Arduino website, it says around 3µs. But can I call it inside a timer interrupt?

This function works very accurately in the range 3 microseconds and up. We cannot assure that delayMicroseconds will perform precisely for smaller delay-times.

Yes, you can call it inside an ISR. However, inside an ISR you should use it only for short delays, because you are lengthening the time it takes to complete the ISR and hence the time before other interrupts can be serviced.

dc42:
Yes, you can call it inside an ISR. However, inside an ISR you should use it only for short delays, because you are lengthening the tie it takes to complete the ISR and hence the time before other interrupts can be serviced.

Ok, thanks! The interrupt will be executed every 500µs and inside it will only be one delayMicroseconds() of around 10µs and the whole routine should take no longer than 15µs, including the delay.

You can do the whole thing with PWM. In my project of making VGA output I needed both vertical and horizontal sync pulses. It sounds similar to what you are doing. You need the pulses a certain width apart, and with a short pulse time. Project page:

Example screenshot:

In that case I had a 4 uS pulse with a 32 uS period. Those figures can be changed by the timer configuration values. This doesn't rely on ISRs at all (for the pulses) since the timer does that.

Yes, but I need to switch the pulse between three pins to change the range for my measurement. That would only be possible with software PWM, right?