Having a spare Arduino Nano and a small OLED screen laying around I thought that I would make a simple logic probe to detect the state of a pin in a project circuit. Nothing fancy, just detect the state and display it on the OLED
Given a common GND, then detecting HIGH and LOW is, of course, easy but can I detect and differentiate between those states and a pin whose state is floating or high impedance in order to report all 4 states ?
I don't want the circuit to get too complex, but adding an op-amp or two would be acceptable if needed. Adding software is, of course, acceptable.
To detect floating... Use an I/O with a serial diode and serial resistor to apply a "soft" HIGH to the tested pin, and an I/O input to detect.
Do the similiar to apply a "soft" LOW.
Resistor in series with the pin. Set it to output and write it low, set to input and see if it is still low. Set to output and write high, input, see if still high. If it stays where you put it then it’s probably floating. Needs some experimentation.
Railroader:
Is the output drive transistor still active when the pin is redirected to input mode?
No, how could it be?
On a PIC the register that controls whether the pin is input or output is called TRIS for tristate. Set it to input and the output drive becomes tristate, so effectively disconnected.
If you can use two pins, you connect a high value resistor (47 or 100k) from the test pin to the "puller" pin. If the test pin always follows the "puller" pin even after the "puller" is disabled (INPUT), it is floating.
Possibly simpler, 220k from pin to ground, switch between INPUT and INPUT_PULLUP. If it reads LOW in the first case and HIGH in the second, it is floating or at least a higher impedance.
220k from pin to ground, switch between INPUT and INPUT_PULLUP. If it reads LOW in the first case and HIGH in the second, it is floating or at least a higher impedance.
After a quick experiment that seems to be OK using a 100K resistor to GND. Using 200K causes false HIGHs to be reported when the input is floating
UKHeliBob:
After a quick experiment that seems to be OK using a 100K resistor to GND. Using 200K causes false HIGHs to be reported when the input is floating
Your code is running too fast! Slow it down a little.
I specified that value in order to make the voltage divider effect with the effective 47k of INPUT_PULLUP more positive. With a 100k resistor, you should get the pin to 2/3 Vcc which should certainly be a clear HIGH though this also could be delayed on switching by wiring capacitance.
For the ATmega328P, the I/O pin pull-up resistor is 20-50k. On the Nano, if you connect a 47K resistor from 3.3V to A0, then you could use A0 as your probe by connecting to any digital with a jumper.
Your code is running too fast! Slow it down a little.
Any suggestions as to the frequency that the two readings should be made at ?
The breadboard prototype ,complete with OLED output, seems to be working OK with a 100K resistor running at full speed. The OLED is only being updated when the output changes so it not slowing things down unduly
Electrically your proposal to add an opamp is a very good idea. If you use the non inverting input of the opamp as probe and you make a feedback loop 1:1 (simple non inverting amplifier), you will get a very high impedance.
Then connect the output of the opamp to an analog input of your test board and you are done.
If you want to regulate the sensitivity you can use a pot meter to connect the + input to GND and regulate the sensitivity (M ohms range). You can even amplify the signal to adapt the range if you want it.
If you have an input resistance of your measuring device that is in the same range of the voltage at the input you want to read, you create a voltage divider. Hence you measurement will influence your measured value so much that it risks not to be relevant any more and you have false conclusions.
So actually what you do this way is to make an impedance transforming circuit.
With an analog input it's sufficient to attach a 1:2 voltage divider (2 100k resistors from Vcc to Gnd) to that input. Then the idle (tristate, broken...) reading is 512 (Vcc/2), HIGH near 1023 and LOW near 0. An INPUT_PULLUP reads about 700-800.
The breadboard prototype seems to work OK with a digital input to GND via 200K with a 1 millisecond delay between INPUT and INPUT_PULLUP readings, so I am going to stick to that as it also works when reading the pins of an ESP32 (3.3V outputs)