"resource not available" when assigning P9 / G16 as ADC

  • Hello,

    After much headache I discovered this post (https://forum.pycom.io/topic/313/lopy-pin-out/3)
    where one user says that it's possible to find the correlation between chip pins and expansion board pins with a REPL command.
    And so I found out that P9 on the chip is G16 on the expansion board and this pin should have ADC capability.

    So I wrote in my code:

    adc = machine.ADC()
    sensorPin = adc.channel(pin="P9")

    But it keeps throwing a "OSError: resource not available" on that second line. I did import machine.

    What is this supposed to mean? That P9 is not G16 after all, or despite this diagram (https://docs.pycom.io/chapter/datasheets/downloads/lopy-pinout.pdf) saying that P9 has ADC, it does not? Or that some other feature on this port prevents me from using it?

    EDIT: after making sure I wasn't using ADC2 ( the ones on the left side), I got rid of this error for some time. Now it's come back, and it doesn't matter which pin I use: ADC is just not available as a resource, and I'm getting no clue what so ever as to why this is..

  • @robert-hh
    Hey Robert! Good to see you're still around. Not back at Pycom but some collaboration brewing up, watch this space ;-)

  • @jmarcelino Hello Jose. Are you back again?

  • @jmarcelino Thank you, noted. Will design accordingly.

  • @HenroRitchie
    I've not followed the Pycom developments too closely but at low level ADC2 is only available when WiFi is off "ADC2 is used by the Wi-Fi driver. Therefore the application can only use ADC2 when the Wi-Fi driver has not started."

    My guess is this complicates things in a dynamic Python environment where you can turn WiFi on and off at will so probably not a priority.

    To be honest ADC1 is quite noisy so I avoid the ESP32 ADCs altogether and now use a more "industrial grade" external solution.

  • @jmarcelino Is this still the case. I am trying to access ADC2 on a Lopy4 and get the same error OSError: resource not available. ADC1 seems to be working fine.

  • @robert-hh yes, sorry i know - I have been trying with the following pins with that code i send you now: "13, 14, 15 and 23". 13, 14 and 15 is adc1.

    I think maybe I understand the problem a tiny bit better now:
    it happens only when I'm doing a soft reset. When I do a hard reset, it works again. Is this because a soft reset doesn't free up the pins maybe?

  • @soren P23 belongs to ADC2 ..... You should write P14, or G4, like you state in the comment

  • @robert-hh

    Hi robert, as far as I can tell - I'm doing the same thing as you.. here is my code, it's on line 9 ("sensorPin = adc...) it reports this error:

    import machine 
    from machine import Pin
    import time
    import pycom
    from machine import ADC
    from machine import PWM
    adc = machine.ADC()
    sensorPin = adc.channel(pin='P23', attn=ADC.ATTN_11DB) # G4 on expansion board
    ledArray = [0x7f0000, 0x007f00, 0x0000ff] # red, green, blue
    step_p = Pin('P8', mode=Pin.OUT)
    stepDir_p = Pin('P21', mode=Pin.OUT)
    class ColorSensor:
        dosingPump_p = Pin('P21', mode=Pin.OUT)
        # SERVO:
        pwm = PWM(0, frequency=50)
        servo_p = pwm.channel(0, pin='P22', duty_cycle=0.127)
        # 0.107 # upright position
        # 0.03 # pouring position
        balanceSet = False
        colourArray = [0, 0, 0]
        whiteArray = [0, 0, 0]
        blackArray = [0, 0, 0]
        avgRead = 0
        def checkBalance(self):
            print("checking balance")
            if not self.balanceSet:
        def setBalance(self):
            print("setting balance")
            for num in range(0, 3): # set white bal
                pycom.rgbled(ledArray[num]) # set to color
                self.whiteArray[num] = self.avgRead
                print('avgRead from bal ', self.avgRead)
                pycom.rgbled(0x000000) # turn off led
            for num in range(0, 3): # set black bal
                self.blackArray[num] = self.avgRead
                pycom.rgbled(0x000000) # turn off led
            self.balanceSet = True
        def checkColour(self):
            for num in range(0, 3): # rinse glass 3 times
                dosingPump_p.value(1) # take in water from aquarium
                time.sleep_ms(500) # how much water to take in?
                dosingPump_p.value(0) # turn off dosing pump
                servo_p.duty_cycle(0.03) # pour out water
                servo_p.duty_cycle(0.107) # turn back glass
            print('rinsing finished! Taking in water...')
            dosingPump_p.value(1) # take in water from aquarium
            time.sleep_ms(500) # how much water to take in?
            dosingPump_p.value(0) # turn off dosing pump
            print('taking plunger down...')
            for num in range(0, 201): # take plunger down
                # check if plunger is all the way down and break ?
            print('plunger is down! Waiting for analysis...')
            time.sleep(1) # set to 3 minutes
            print('analysis ready! Reading colours...')
            for num in range(0, 3):
                pycom.rgbled(ledArray[num]) # set to color
                self.colourArray[num] = self.avgRead
                print('whitearray ', self.whiteArray[num], ' blackArray ', self.blackArray[num])
                greyDiff = self.whiteArray[num] - self.blackArray[num]
                print('greydiff: ', greyDiff)
                self.colourArray[num] = (self.colourArray[num] - self.blackArray[num])/(greyDiff)*255
                pycom.rgbled(0x000000) # turn off led
        def printColour(self):
            print('printing colour')
            return self.colourArray[0], self.colourArray[1], self.colourArray[2]
        def getReadings(self, times):
            reading = 0
            tally = 0
            for num in range(0, times+1):
                reading = sensorPin()
                print('reading ', reading)
                tally = reading + tally
            self.avgRead = (tally)/times
            print('avgRead ', self.avgRead)
            #print('avgRead ', avgRead)

  • @soren Are sou sure? I can do it here.

    import machine
    adc = machine.ADC()
    sensorPin = adc.channel(pin="P14")

  • @jmarcelino so now I'm also getting this error from ADC1 pins... P14, to be precise

  • @jmarcelino thank you very much for chiming in. i'm baffled why this isn't stated in capital letters on the official pinout diagrams

  • @soren
    The ADC2 pins are not available from Python, at least for the time being. You can only use ones starting with ADC1_...

Log in to reply

Pycom on Twitter