ADC working terrible (defect modules?)
-
Hi folks, for an IoT project I am working with 60 LoPy4 nodes.
I am using 3 sensors with analog output, requiring me to use the ADC class.
Now I am facing severe problems: while some nodes can read these fine, a large number of nodes have hardly any working ADC pin.
Pins 13 up to including 20 should be available to use is my understanding, but on some nodes I have maybe only one or two working pins (mostly P16 and P20).
All other pins always read 0 on pin.value() (or sometimes some small value if nothing is connected), unless I stuff straight 3.3V in it from the 3V3 pin..
One of the problematic devices had a measured adc.vref_to_pin() voltage of 3.73V (??) but manually setting adc.vref(3730) does not help the defective pins and only makes the working ones spit out incorrect values.Any suggestions for troubleshooting or other ideas to make this work? Very welcome and thanks in advance!
-
The LoPy4 Pin-Out does not show other connections, but these may exist on an expansion board, like the VBatt divider at P16, the User Button at P14 and the Accelerator IRQ at P13.
@robert-hh thanks for this reminder; it solved my troubles eventually. One of the LoPy seems to be defective, but on all others, everything is fine now after moving around some pins. Thanks!
-
@Steven-Boonstoppel And I do not have a plain vanilla Pycom expansion board. I have the flavored ones, like yptrack, pysense, ...
-
@robert-hh thanks for that test! Could you maybe try and run the same script on the same LoPy with an expansion board? Curious to see if that might be the cause for the ADC troubles. I don't have a UART bridge laying around so I cannot check your script unfortunately :(
-
@Steven-Boonstoppel So I grabbed a LoPy4 and ran a little ADC test. All inputs P13 - P18 worked as ADC input. I used a bare LoPy4, just connected to the PC by a USB/UART bridge. No other connections.
Firmware versionPycom MicroPython 1.20.2.r6 [v1.20.1.r2-402-gc5a0a97a-dirty] on 2021-12-01; LoPy4 with ESP32 Type "help()" for more information.
Which is more or less the legacy version an an recent firmware build. The test script:
from machine import Pin, ADC from time import sleep def run(ch="P13"): adc = ADC() apin = adc.channel(pin=ch, attn=ADC.ATTN_11DB) for _ in range (10): print(apin()) sleep(1) run()
The input signal was 1V DC from a signal generator with 50 Ohm output impedance, varied slightly to see, that the printed output follows the input voltage change. A typical output series at a constant 1 V input was:
1122 1118 1203 1057 1168 1072 1162 1093 1079 1104
So you see it's
-
@robert-hh thanks for the heads-up! But I still wouldn't expect to read a zero-value on almost all ADC pins, would I?
And even though the effective resolution may be ~8 bits, I'd expect to read some useful values at an 11-bit attenuation...
-
@Steven-Boonstoppel P13 to P18 are connected to ESP32 Pins that can act as ADC inputs. On some of the development & expansion boards, some of these pins are connected to on-board peripherals. At the FiPy, only 3 Pins are available for ADC. The LoPy4 Pin-Out does not show other connections, but these may exist on an expansion board, like the VBatt divider at P16, the User Button at P14 and the Accelerator IRQ at P13.
In any case, do not expect any kind of precision from the ADC. The effective resolution is ~8bit, and it is not overly linear and quite noisy. You can reduce the noise by placing a ceramic capacitor of a few nF between input and GND as close as possible to the ADC input.
-
@Miguel-Moreno sorry I was a bit tired after days of searching and debugging and wrote it frustated from my phone - here's from my PC with the requested info!
What are the minimum and maximum voltages of the signal you are reading ?
0 to 3.3V, I am using 11 dB attenuation.
I am also reading the battery voltage which could go up to 4.2V but that is behind a 1MOhm/1MOhm voltage divider.
Schematic for the project: P15, P18 and P20 are the analog inputs I am trying to read.
Schematic_Meet_je_leefomgeving_2022-08-10.pdfIdentical code for all three pins (except for their pin number):
adc = machine.ADC() self.adc = adc.channel(pin = pin, attn = machine.ADC.ATTN_11DB) val = self.adc.value()
I hope that'll help some!
-
Hello @Steven-Boonstoppel .
Can you share with us more about the specific way you are feeding the analog signals to your ADC inputs ?
More specifically:
- What are the minimum and maximum voltages of the signal you are reading ?
- Keep in mind that the ADC inputs have a maximum input of 1.1 V ( average from internal voltage reference ), so in case you are reading voltages higher than this you have to configure an attenuation parameter in your ADC pin.
- The absolute maximum voltage that you can feed directly to the ADC pins is 3.3 V ( internal MCU Vdd ), so anything above this voltage can potentially damage permanently the ADC circuit inside the MCU. If this is your case, you must have some sort of voltage divider before feeding the analog signal to the ADC pin and then consider the voltage divider reducing factor in your ADC value being read to scale it up in the same proportion.
Once you share more details with us we may be able to help you further.