pico-coder / sigrok-pico

Use a raspberry pi pico (rp2040) as a logic analyzer and oscilloscope with sigrok
727 stars 83 forks source link

Allow measuring voltages above 3.3V by using voltage dividers plus a selection mechanism #26

Open Amanoo opened 1 year ago

Amanoo commented 1 year ago

The RPico could measures voltages well over 3.3V by using voltage dividers. It would even be possible for the Pico to select a specific divider, thus giving the RPico precise knowledge of the division factor being used, and allowing it to calculate the actual input voltage. For example, by using two 4k resistors, the voltage read by the Pico would be halved. If the Pico then reads 2.5V and it had preciously selected this voltage divider, it would know the actual input voltage was 5V, and could then notify Sigrok of this 5V signal. By selecting a different divider, the Pico could communicate even higher voltages.

Below is a picture of a network that allows the Pico to select a certain factor: circuit (4)

The leftmost opamp is a buffer. It simply repeats the input voltage. This adds a high impedance between the measuring circuit and the actual measure point. If you were to just hook up a bunch of resistors without a buffer, you might change the system you're trying to measure. The opamp has a 50V input voltage just to allow it to repeat up to 50V. This could be achieved via a boost converter which can be bought very cheaply. The input voltage of this boost coverter could just be USB. Not much current is needed, you just need a high voltage to allow the opamp to repeat a high input.

Right of that is a cascade of resistors acting as voltage dividers. You can choose to measure the raw voltage, half that voltage, a quarter, and eigth, or a 16th. This would set the maximum around 50V.

Each voltage divider has a relay, diode, and transistor, which allows the RPico to control which output is active. Only one of the select pins should be high at any given moment. This will close the corresponding relay. This does require 5 different selection pins on the RPico for each network, and you probably want a network for each analog input and possibly for each digital input as well. I would recommend using an I2C IO expander and maybe even some demultiplexers, just to keep most RPico pins free.

Finally, there's a 10k resistor, a zener diode, and another opamp, just to protect the RPico against receiving a jolt over 3.3V. The zender will ensure that the opamp never receives over 3.3V, the 10k resistor will in turn protect the zener against a high current, which should be moot since opamps are normally unable to deliver much power anyway. The output is then finally sent to the RPico.

I have tried to find a method without using relays to lower the costs, for example by replacing them with MOSFETs. Relays aren't very expensive on AliExpress, but the cost does add up. However, in my LTspice simulations, I was unable to find a method that didn't malfunction in certain cases. I got it mostly working, but there were too many edge cases where the output wouldn't be quite right. Enough edge cases to make it unpractical. Maybe a better electrical engineer than myself could find a method that would work.

The RPico would have to select a voltage divider in some way. One possible option would be to have some sort of GUI on the computer where the division factor could be selected. I don't know if Sigrok can already do this? I have never used Sigrok before. Another method might be to have the RPico switch between voltage dividers automatically. It could keep track of the highest voltage measured in the last 10 or so seconds. If this voltage exceeds 3V, it should switch to a higher division factor. If the highest voltage was very low, it could switch to a lower factor. This would only be possible on the analog pins however. The digital pins can't measure voltages, only an on or off state. It would be possible to add an Arduino to also change the division factor of the digital pins automatically in a similar fashion. Or again, just use a GUI. I'm just raising this in the form of an issue because looking through a thousand lines of code that's entirely unfamiliar to me, just to find a spot where I could add a system such as this, would be a significant challenge to me.

I estimate the cost of each network to be around 3 euros if ordering parts on AliExpress. While this cost is significant compared to the price of an RPico, the system would still be very cheap compared to a proper oscilloscope. Maybe 30 euros in total for a fully decked out system with lots of voltage dividers. Given that a professional oscilloscope is easily 10 times as expensive (although capable of much faster sampling rates), I think that is a good deal.

pico-coder commented 1 year ago

See https://github.com/pico-coder/sigrok-pico/issues/14 for a previous discussion on the topic. But basically you have two options: 1) Modify the scaling values in sr_device.h and rebuild the PICO uf2 file. 2) Use the Math functions of pulseview to scale relative to the 3.3V assumption of the default build. Aside from having to do that every time run pulseview, it is definitely the easiest.

Neither of those allows you to modify the settings via a GUI, but would at least allow you to get properly scaled values.

Notes: -The PICO never sends the "real" value, it only sends a 7 bit ADC value and it is up to the device to tell how it should be scaled.

Long term I might add some kind of startup command line option to pulseview so that the user can specify the ratios. That will at least support a different fixed ratio but won't allow something to be set.

What you propose is possible, but would require a bit of development and would only be useful for people who built the circuit. Also, with a single manually selectable ratio, say 10:1 and 1:1 you could measure up to 30V and down to as low as 3.3/128=25mV. While not automated, that seems to cover most peoples use cases, and it should be fairly easy to just multiply a signal value by 10 in your head... Granted, that isn't very fancy, but if we do something here I'd like it to be flexible across various use cases - i.e. what if someone wants to build divisor at 5x ratios how do we communicate what they are?

pico-coder commented 1 year ago

A few comments on your schematic: 1) While 50V supplies might be "cheap" they will likely be very noisy. 2) Opamps that operate up to 50V can be hard to find. 3) Many "cheap" opamps have limited gain bandwidth products which might not support signal rates at 100khz which the rp2040 might be useful to sample.

Here is what I came up with:

RP2040_Mux

S1 is a manual switch to select DC vs AC bias through C1. J1 and it's resistors implements a 100:1 attenuation and J2 implements a 1:1 input. R11 at 100k is to limit gate current on high input voltages. At high inputs J2 gate will forward conduct, but J1 will be used for measurements. Thus at high voltages the input resistance is 100k, but at lower voltages it will be around 1M due to R6/R7 (since the gate impedance of a JFET is very high).

The analog mux ADG5408 would be controlled by the PICO. Note that the ADG5408 won't work because it requires a minimum 10V supply, but there are other analog muxes which run on lower voltages.

Each JFET only supports a voltage swing of a volt or so, so Q3 is used to provide a bit of gain and to change the offset of the output to be offset from ground.

Some work needs to be done to get the biasing tweaked right but I think such a circuit would do the trick. The user could build as many JFET attenuators as they wanted to get whatever ranges were desired. For signal levels less than 1V p2p a following amplifier stage would need to be added before the mux.

Still not 100% sure how to communicate this via pulseview but likely through the Volts Per Division attribute.....