3

I'm seeking a solution how to do a two point scaling in electronics. I have tried an Op-amp, but it did not work very well. So I wonder if you have some ideas how to do two point scaling from e.g 0.6 V - 3.2 V to 0.0 V - 3.3 V?

When I apply 4 mA, I what the output to be 0.0 V or very close to 0.0 V. When I apply 20 mA, I want the output to be 3.3 V or very close to 3.3 V.

The Zener below is a 3.6 V Zener.

Is that possible?

enter image description here

Transistor
  • 168,990
  • 12
  • 186
  • 385
euraad
  • 1,025
  • 11
  • 30
  • 2
    Gain and offset. If the output is into an ADC with enough resolution, and the input range is entirely within the output range (as in your example) you can simply connect directly, and apply the required gain and offset in software. –  Mar 14 '21 at 13:32
  • @BrianDrummond I'm suing a STM32 but the ADC reference is 3.3V and when I apply 4mA, then I'm using a lot of the ADC. I don't what to do that. Or is it possible to change the ADC reference for the minimum voltage too? – euraad Mar 14 '21 at 13:34
  • @BrianDrummond Thank you! So lets take an example. If I got 160 Ohm resistor as above, then at 20mA, then I got 3.2V into the 12-bit ADC. If the ADC is configured to 3.3V. Then my ADC value is going to become 3.2/3.3*4095 = 3970. And when I apply 4mA, then I got 0.64/3.3*4095 = 794. You mean that I'm going to take minus 794 all the time so when I got 20mA, then I got ADC 3176. That's is not optimal according to me :) – euraad Mar 14 '21 at 13:40
  • @BrianDrummond I just want to do a two points scaling. Do a software subtraction, will results that I'm loosing 1 - (3.2/3.3*4095 - 794)/4095 = 22% of the ADC range. – euraad Mar 14 '21 at 13:47
  • Daniel, this expression will give you the current in uA, with two orders of magnitude lower error than your analog circuit: ((adc-794)*((20000-4000)/(3176-794)))+4000. Replace the two points according to your measurements. I'm assuming 32 bits integers. Depending on you STM32, you may even have floating point. – devnull Mar 14 '21 at 14:33

3 Answers3

6

I'm using a STM32 but the ADC reference is 3.3V and when I apply 4mA, then I'm using a lot of the ADC. I don't what to do that. Or is it possible to change the ADC reference for the minimum voltage too?

You're only losing 20% of the range and you have the advantage of a "live zero" which can be used to detect a break in the 4 - 20 mA loop. This is the standard solution taken by industrial PLCs and many of those do that on a 0 - 10 V input by addition of a 250 Ω shunt resistor to give only 5 V at 20 mA. Usually its simplicity wins out over the loss of resolution.

A further advantage in the industrial sensor applications is that sensor faults can be indicated by sending a 3 mA signal, for example.


From the comments:

But isn't 20% a little bit to much? I could detect current loop breaks with 5% waste.

That's for you to decide. You're using a 12-bit / 4096 step ADC. That's a step resolution of 0.02% of full-scale per step. Losing 20% gives you 0.03% of full-scale per step. You're going to have difficulty getting better than 0.1% shunt resistors - see Vishay for example and noise will introduce further problems. Introducing an op-amp to do the offset properly only makes it more difficult.

enter image description here

Figure 1. It appears that the top and bottom of the STM32 ADC are accessible.

The other option is to offset the ADC VREF- to 20% of VREF+. See page 68 of the datasheet.

Added by OP:

enter image description here

euraad
  • 1,025
  • 11
  • 30
Transistor
  • 168,990
  • 12
  • 186
  • 385
  • Yes. I think that's the solution! I have updated your question with my processor. It's an STM32F373CR – euraad Mar 14 '21 at 14:39
  • 3
    Right, now do your error calculations with the resistors you can afford (I've seen €13 for a 0.01% resistor) and see if you can beat the accuracy of doing the scaling offset in software. Let us know ... – Transistor Mar 14 '21 at 14:42
  • I think 0.1% resistor is good enough. But thanks for the answer. I till try that! – euraad Mar 14 '21 at 14:48
  • Vref- is only externally accessible on the UFBGA176 package on the datasheet Transistor linked, it's not available at all on the STM32F373 ( tied internally to Vssa). – Spehro Pefhany Mar 14 '21 at 14:52
  • @SpehroPefhany Yes. I notice that right now. Hmm...Need to find a way around this. – euraad Mar 14 '21 at 14:58
  • Here is the controller I'm using: https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-mainstream-mcus/stm32f3-series/stm32f373/stm32f373rc.html – euraad Mar 14 '21 at 14:59
  • 1
    *isin't 20% a little bit to much* Pause for a moment. Why do you need to ask this? Only **you** know the requirements for your data acquisition circuit. Given the resolution, linearity and stability requirements, you can know exactly whether it's too much or not. We can't answer it for you. You can ask how to calculate such things, but you need to provide the specifications/requirements you are trying to implement, since those drive the design. It may turn out that the built-in ADC will not be enough even if there was "0%" loss of range. We can't know that. – Kuba hasn't forgotten Monica Mar 14 '21 at 23:41
  • @Daniel, you have accepted my answer and then you have edited it to add another image with no caption and no explanation. It's not part of my answer so I'll delete it unless you actually *improve* my answer. – Transistor Mar 15 '21 at 18:16
3

You need gain and offset.

But if the output is into an ADC with enough resolution, and the input range is entirely within the output range (as in your example) you can simply connect directly, and apply the required gain and offset in software

Just connect directly.

There's really no need for anything more complex. Subtracting an offset in software is cheap and easy, and has the big advantage that you can use a value below that 4mA level to indicate a break in the current loop and report error, shutdown dangerous machines, etc.

The gain part of gain and offset is just multiplication. (Actually it may not even be that : it may reduce to editing a constant somewhere else in the software).

With both operations, of course, you must take care to handle any overflows or underflows that may occur (especially if you're using a language like C where they can happen silently producing unwanted results).

From comments:

Now we're getting to the stuff that's missing in the question.

Adding expense and complexity when a simpler solution meets your error budget is not optimal. But only you know your error budget; I'm not going to attempt to guess it from the question. You'll also have to justify if analog electronics with what? 1% resistors? will give you a more accurate, or less accurate, solution than using a 4000 step (0.025% error) ADC as a 3000 step (0.03% error) one.

One way of looking at it is taht we are losing 20% of the ADC range.

From another perspective, that is trivial. Each LSB is 0.03% of the remaining scale instead of 0.025%. How much would a couple of resistors cost, that will preserve 0.025% accuracy? (Say, 0.01% each)

  • Start with your error budget. What accuracy do you need?
  • Then list the error sources and apportion the error budget between them.
  • Then minimise overall cost by allocating more of the error budget to the most expensive component to reduce its cost.

If you need better than 1% absolute accuracy you can't use a 160 ohm 1% resistor and a standard 5% 3.3V regulator as the reference voltage. And if you don't, the loss of ADC range is the least of your concerns.

My suspicion is that you'll find a direct connection from a suitable 160 ohm resistor and NO VOLTAGE DIVIDER into a 12 bit ADC with a suitably accurate Vref is the best, simplest, most accurate and cheapest solution.

Without knowing your error budget, that's just my suspicion. And finally, from

I would be happy if I got 0.1V error. So when I have 4mA. Then I have 0.1V input to the ADC. When I got 20mA, then I got 3.2V input to the ADC

Distinguishing 3.2V (between 3.15 and 3.25) requires 50mV/3.2V or about 1.5% accuracy. You'll need to pay attention to the sense resistor accuracy and the Vref accuracy, and lip service to avoiding DC offsets.

The ADC range is practically irrelevant in comparison. In fact, adding complexity to use the full ADC range, without extraordinarily expensive close tolerance resistors, can only reduce accuracy.

  • What? We talking about 20% lose in the ADC range. – euraad Mar 14 '21 at 13:50
  • Which is trivial. Each LSB is 0.03% of the remaining scale instead of 0.025%. Now go and price a couple of resistors that will preserve 0.025% accuracy. –  Mar 14 '21 at 13:52
  • You mean I'm going to create a voltage divider to scale down the input voltage and then I change the ADC reference voltage as well? – euraad Mar 14 '21 at 13:53
  • Sorry. I don't understand you. I think you missing the point of the question. – euraad Mar 14 '21 at 13:57
  • 1
    @DanielMårtensson. What are your precision requirements? How precisely do you need to measure 4mA and 20 mA? Do you need do measure other intermediate values or values outside this range? – devnull Mar 14 '21 at 13:58
  • 2
    I would be happy if I got 0.1V error. So when I have 4mA. Then I have 0.1V input to the ADC. When I got 20mA, then I got 3.2V input to the ADC. – euraad Mar 14 '21 at 14:05
  • Excellent Daniel. Please see above that @BrianDrummond has updated the answer according to these requirements. – devnull Mar 14 '21 at 14:13
  • @vangelo Thank you. But I still don't understand how I'm going to do a two point scale. Brian says that an excellent solution is to do software subtraction. Sure. But the error is going to be 20% all the time. – euraad Mar 14 '21 at 14:18
  • 1
    No, Having subtracted 794, (and remember to take care of underflow!) you get 0 = 4mA and 3176 = 3.2V = 20mA. Where's the problem? –  Mar 14 '21 at 14:21
  • @BrianDrummond The problem is that I want close to 4095 at 20mA :) and close to 0 at 4mA. – euraad Mar 14 '21 at 14:22
  • 1
    Multiplication by 4095/3176 is cheaper than a resistor. That's the "Gain" part of the first line of the answer. Again, just remember to take care of any overflow. But that's just software. –  Mar 14 '21 at 14:23
  • @BrianDrummond But still, I'm using alot of the ADC. – euraad Mar 14 '21 at 14:31
  • @DanielMårtensson hah! It is difficult to see the other party's mental block - from both sides! To me, "gain" implies multiplication so obviously (after 40+ years) I never thought to translate it! Answer edited to (hopefully) clarify. –  Mar 14 '21 at 14:35
  • @BrianDrummond Have a look at Transistors answer. It sure looks good. – euraad Mar 14 '21 at 14:40
  • 1
    And he has set the accuracy challenge ... go to it! –  Mar 14 '21 at 14:47
  • 1
    IMHO, this is the way to go (subtract the offset in software), and if 0.3 or 0.4 bit loss of resolution makes a difference, then the ADC in the MCU is almost certainly inadequate to the task. – Spehro Pefhany Mar 14 '21 at 14:58
  • Yes, but that's only available for some specific microcontrollers. – euraad Mar 14 '21 at 14:58
2

If you really insist, you can generate a -5V supply if you don't have one already (eg. 7660 charge pump) and do something like this:

schematic

simulate this circuit – Schematic created using CircuitLab

There are a number of issues with something like this on top of the loss of accuracy and increased drift, such as the output going out of range of the MCU input when the current is more than 20mA or less than 4mA, and the total lack of any signal conditioning, so it's unsuitable for serious applications (and probably unserious ones), but it does exactly what you asked.

Spehro Pefhany
  • 376,485
  • 21
  • 320
  • 842