PWM + Sampling at same frequency

Hi all

I’ve got an application where I need to generate a 1kHz square wave, and also measure the voltage on the positive half cycle (the square wave amplitude is pulled down externally).
The impedance of the signal is 220k which I know is on the high side - which leads to my first question, if sampling this signal at 1kHz, would it be recommended to use an op amp buffer on the signal? I suppose testing would be the way to go (which I will soon) but also just interested in others opinions as I’ve heard that the input impedance of the STM32F2 is relatively low.
Aside from this, in terms of the actual software implementation, to sample in sync with the generated PWM, could a solution be use the new IntervalTimer library at 1kHz and simultaneously toggle the output pin (to create the PWM) and also read the ADC at the same time? Is this an efficient method?
I’ll also need to vary the duty cycle of the PWM as well…

Any thoughts are much appreciated!

@G65434_2, can you provide a schematic or a more detailed description of what you are trying to do in terms of pulsing/sampling? It’s really not clear when you say “the impedance of the signal is 220K”. :smile:

Thanks @peekay123, I should have included one for a start, so what I meant was there is essentially a 220k resistance between the +12/-12V signal I’m measuring and the ADC input, the circuit shown is responsible for level shifting that to between 0-3.3V.
The ‘+12/-12V’ bipolar square wave is being driven by another part of the circuit, but suffice to say, it’s frequency is controlled by the software as well. In the application, the square wave can be loaded resistively and hence it’s amplitude may change, which is what I would like to measure, so yes I have to sample in the positive half cycle 1000 times a second to obtain that amplitude.

Hi @G65434_2

Are you trying to find the edges of the +/- 12V square wave or get some analog representation of it?

If you only need the edges, then an interrupt on a digital pin will likely do (although at 1kHz you almost don’t need interrupts).

If you want to see some sort of waveform, the I think you are going to need an op-amp buffer.

Hi @bko

I’m trying to measure the amplitude of the square wave (just in the positive half cycle) so I suppose this is what you mean? I imagine a fairly basic rail to rail op amp would suffice as the signal is pretty slow?

Yes, a simple op-amp configured as a voltage follower will work great. You want something that will work well on 0-3.3V like a LM358 or TLV2463 etc. If you need filtering too, you can built that in, but it doesn’t sound like you need it.

Thanks @bko, any recommendations as to the software implementation? Is the most efficient method just to trigger the first ADC conversion on the same timer as the PWM?

I think it depends on a few things:

  • Do you need an average voltage for the positive half?
  • Or do you need the peak voltage?
  • Are you worried about transients around the edges? If so, doing the analogRead() at a different time would be best.

I would probably not do the analogRead() inside the interrupt handler if I could avoid it.

Ideally an average voltage although it should be a pretty clean wave so it’s not crucial, although I don’t think I’d be wanting to sample on the very leading edge as there could be a bit of overshoot I suppose (as you’ve said).

So does the analogRead() function actually perform 10 ADC conversions and average them?

I have not looked at the Photon code yet, but on the Core (and it should be similar) it starts the A/D and its DMA channel and waits for 10 samples, and then averages them.

1 Like