Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    WiPy ADC

    Scheduled Pinned Locked Moved Discussion
    wipyadcpin
    5 Posts 2 Posters 1.2k Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B Offline
      B_Rubble
      last edited by

      Hi all,

      I'm having some issues with the embedded ADC function, and was hoping to get some insight. I need to measure 0-10v, so I put together a simple voltage divider to scale that down to 0-1

      -My ADC is not registering different values, when fed 0.2v and 0.7v I received the same value.
      -Stability/Timing? I notice that my ADC values sporadically drop. I have tried with and without a 100ms pause, and with a 100nf capacitor, but this does not seem to help.

      def checkpin():
          time.sleep_ms(10)
          adc = ADC()
          adc_c = adc.channel(pin= 'P13', attn=ADC.ATTN_11DB)
          for i in range(10):
              time.sleep_ms(100)
              b = adc_c.voltage()
              time.sleep_ms(100)
              v = 3.3*b/4096
              print(b,", ",v)
              time.sleep_ms(100)
      

      An example output: (this does not change with different voltage input)

      348 ,  0.2803711
      3134 ,  2.524951
      3134 ,  2.524951
      142 ,  0.1144043
      142 ,  0.1144043
      3134 ,  2.524951
      142 ,  0.1144043
      3134 ,  2.524951
      3134 ,  2.524951
      3134 ,  2.524951
      

      Any thoughts/suggestions would be much appreciated. I have a ADS7818 which I can try uart with, but I'm just trying to determine the easiest way to measure 0-10v ±0.1

      Thank you

      robert-hhR 1 Reply Last reply Reply Quote 0
      • robert-hhR Offline
        robert-hh @B_Rubble
        last edited by

        @b_rubble The call to adc_c.voltage() returns a voltage scaled in mV, depending on the attenuation factor you have selected. That is 11db, so the range is about 0-3.3V. if you want to get the raw ADC values, you have to call adc_c.value() or simply adc_c(). That will return a raw value in the range of 0-4096.
        The ADC of the ESP32 is not very good. You get the best linearity at 6 dB attenuation, and the low offset is at about 70 mV.
        I cannot tell whether you see this much changing values. Besides high noise and non-linearity I did never observe such changes. It may be related to external factors like your circuitry, sockets, ....
        If I repeat the here on a LoPy4, I get plausible (albeit poor) values with you script, feeding 2V into P13. Note that only the first column is fine.

        1993 ,  1.605688
        2034 ,  1.638721
        1969 ,  1.586352
        1968 ,  1.585547
        1881 ,  1.515454
        1917 ,  1.544458
        1971 ,  1.587964
        1948 ,  1.569434
        2007 ,  1.616968
        1974 ,  1.590381
        
        B 1 Reply Last reply Reply Quote 0
        • B Offline
          B_Rubble @robert-hh
          last edited by

          @robert-hh thank you very much for your insight. I have actually used some of your previous posts to help troubleshoot other issues, so I definitely appreciate you taking the time to answer. I modified my script to just output value, voltage and fed in a fairly consistent 420mv (measured as 419-421mv through my fluke). Unfortunately it seems that even with calibration there would be too much noise for my uses. I continue to get very odd behavior, so I think I will use an off the shelf ADC to accomplish this task.

          Do you have experience or suggestions for off the shelf converters? I don't have SMT capabilities with my current setup, but I do have a ADS7818 which I will try to use with UART.

          Thank you

          robert-hhR 1 Reply Last reply Reply Quote 0
          • robert-hhR Offline
            robert-hh
            last edited by

            @b_rubble You can use the built-in ADC is the noise does not matter or if you can ignore the lower 4 bits.

            I have used an ADS1115 with an ESP8266, attached with I2C. It has a SMD package, but you can get modules at any size, down to a DIL8 pin layout. But this is a rather slow device. The ADS7818 is faster, and it should be possible to read that with SPI. UART won't work.
            So I do not know your application needs, speed or precision.

            1 Reply Last reply Reply Quote 0
            • robert-hhR Offline
              robert-hh @B_Rubble
              last edited by robert-hh

              @b_rubble Here is a sample script using the ADS7818 with SPI:

              # Drive the ADS7818 ADC using SPI
              # Connections:
              # xxPy | ADS7818
              # -----|-------
              # P10  |  CLK
              # P11  |  CONV
              # P14  |  DATA
              #
              from machine import SPI, Pin
              from ubinascii import hexlify
              
              spi = SPI(0, SPI.MASTER, baudrate=4000000, polarity=1, phase=1, bits=16)
              buf = bytearray(2)
              vref = 2.493 # measured at the ADS7818
              
              while True:
                  # start a conversion and get the result back
                  spi.write_readinto(b"\xe0\x00", buf)
              
                  # extract the raw ADC value and derive Voltage
                  value = ((buf[0] << 8) | buf[1]) & 0xfff
                  volt = 2.0 * vref * value / 4096
              
                  print(hexlify(buf), value, volt)
                  res= input("Next: ")
                  if res == "q":
                      break
              

              The conversion and reading back is done within the single spi.write_readinto() call. It is then easy to embed that in a small class.
              Note: Since the ADS7818 runs at 5V, insert a resistor of 3.3k to 10k into the data line back into the ESP32 to limit the current into the ESD diodes.

              1 Reply Last reply Reply Quote 0

              Hello! It looks like you're interested in this conversation, but you don't have an account yet.

              Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

              With your input, this post could be even better 💗

              Register Login
              • 1 / 1
              • First post
                Last post

              Pycom on Twitter

              Pycom