"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)
        dosingPump_p.value(0)
        # SERVO:
        pwm = PWM(0, frequency=50)
        servo_p = pwm.channel(0, pin='P22', duty_cycle=0.127)
        servo_p.duty_cycle(0.107)
        # 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:
                self.setBalance()
    
        def setBalance(self):
            print("setting balance")
            time.sleep(5)
            for num in range(0, 3): # set white bal
                print(num)
                pycom.rgbled(ledArray[num]) # set to color
                time.sleep(0.1)
                self.getReadings(5)
                self.whiteArray[num] = self.avgRead
                print('avgRead from bal ', self.avgRead)
                pycom.rgbled(0x000000) # turn off led
                time.sleep(0.1)
            time.sleep(5)
            for num in range(0, 3): # set black bal
                pycom.rgbled(ledArray[num])
                time.sleep(0.1)
                self.getReadings(5)
                self.blackArray[num] = self.avgRead
                pycom.rgbled(0x000000) # turn off led
                time.sleep(0.1)
            self.balanceSet = True
            time.sleep(5)
    
    
        def checkColour(self):
            print("rinsing...")
            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
                time.sleep(1)
                servo_p.duty_cycle(0.03) # pour out water
                time.sleep(4)
                servo_p.duty_cycle(0.107) # turn back glass
                time.sleep(4)
            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
            time.sleep(1)
    
            print('taking plunger down...')
            for num in range(0, 201): # take plunger down
                step_p.value(1)
                time.sleep_ms(500)
                step_p.value(0)
                time.sleep_ms(500)
                # 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
                time.sleep(0.1)
                self.getReadings(5)
                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
                time.sleep(0.1)
    
        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
                time.sleep(0.01)
            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