Search code examples
pythonbeagleboardangstrom-linux

Reading analog-in on BeagleBone, avoiding "segmentation fault" error


I am new to the Beaglebone, and was moving along at a pretty good click until this strange problem popped-up. I spent all weekend trying to figure it out before posting here.

I am trying to read analog input using multiple sensors from a beaglebone with Angstrom 3.2.5+ and I have a problem that I think might be a hardware issue.

Using this Python script and Alexander Hiam's PyBBIO I have been able to test a photoresistor with success (the value responds to more and less incidental light):

# Import PyBBIO library:
from bbio import *

# Create a setup function:
def setup(): pass # Nothing to do here

# Create a main function:
def loop():

  print "-----"

  print "AIN0 [P9.39] - " + str(analogRead(A0))
  print "AIN1 [P9.40] - " + str(analogRead(A1))
  print "AIN2 [P9.37] - " + str(analogRead(A2))
  print "AIN3 [P9.38] - " + str(analogRead(A3))
  print "AIN4 [P9.35] - " + str(analogRead(A4))
  print "AIN5 [P9.36] - " + str(analogRead(A5))
  print "AIN6 [P9.33] - " + str(analogRead(A6))
  print "AIN7 [P9.39] - " + str(analogRead(A7))

  delay(500)

# Start the loop:
run(setup, loop)

But, any other analog-in (AINx(2-7)) I read with the script above always shows the same value of the photo resistor I have plugged-into AIN1

And, possibly related, I am unable to read any of the AINx(1-7) using cat with an error

cat /sys/bus/platform/devices/tsc/ain1
Segmentation fault

Any ideas? I am really stuck. Thanks in advance.

PS: More info...

My circuit consists of a 10k resistor and a photoresistor. My pin connections are:

  • Header P9 Pin 32 (VDD_ADC(1.8V)) to one end of photocell
  • Header P9 Pin 34 (GNDA_ADC) to the other end of the resistor
  • Header P9 Pin 39 (AIN0) to the other side of the photocell along with one end of pull-down resistor

Here is an image which matches my own circuit: enter image description here

The results from all of the AINx(1-7)'s and then some...

# cat /sys/bus/platform/devices/tsc/ain0 
cat: /sys/bus/platform/devices/tsc/ain0: No such file or directory 
# cat /sys/bus/platform/devices/tsc/ain1 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain2 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain3 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain4 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain5 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain6 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain7 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain8 
Segmentation fault 
# cat /sys/bus/platform/devices/tsc/ain9 
cat: /sys/bus/platform/devices/tsc/ain9: No such file or directory

UPDATE 1

I edited the analog_test_simple.py file to show all ADC ports on the BeagleBone. This is the result from the shell with no sensors plugged-in.

-----
AIN0 [P9.39] - 3948
AIN1 [P9.40] - 4016
AIN2 [P9.37] - 4002
AIN3 [P9.38] - 3934
AIN4 [P9.35] - 4001
AIN5 [P9.36] - 3935
AIN6 [P9.33] - 3968
AIN7 [P9.39] - 4005
-----
AIN0 [P9.39] - 3946
AIN1 [P9.40] - 4005
AIN2 [P9.37] - 3945
AIN3 [P9.38] - 3957
AIN4 [P9.35] - 4018
AIN5 [P9.36] - 3945
AIN6 [P9.33] - 3967
AIN7 [P9.39] - 3955
...

And if I plug the sensor back in I get a change in value, but again, they are all the same:

-----
AIN0 [P9.39] - 2836
AIN1 [P9.40] - 2836
AIN2 [P9.37] - 2837
AIN3 [P9.38] - 2831
AIN4 [P9.35] - 2840
AIN5 [P9.36] - 2837
AIN6 [P9.33] - 2837
AIN7 [P9.39] - 2837
-----
AIN0 [P9.39] - 2834
AIN1 [P9.40] - 2834
AIN2 [P9.37] - 2829
AIN3 [P9.38] - 2825
AIN4 [P9.35] - 2826
AIN5 [P9.36] - 2817
AIN6 [P9.33] - 2815
AIN7 [P9.39] - 2815
...

Solution

  • OK, the answer is that there are two separate problems, both of which are caused by using the PyBBIO library. Read on...

    PROBLEM 1: Inconsistent/incorrect sensor values

    A suggestion in the comments on my question prompted me to add a delay to my original PyBBIO-based script. Here it is without the sensor:

    # python PyBBIO/examples/analog_test_simple.py
    -----
    AIN0 [P9.39] - 3955
    AIN1 [P9.40] - 4015
    AIN2 [P9.37] - 4012
    AIN3 [P9.38] - 3950
    AIN4 [P9.33] - 3998
    AIN5 [P9.36] - 4007
    AIN6 [P9.35] - 3984
    -----
    AIN0 [P9.39] - 4007
    AIN1 [P9.40] - 3953
    AIN2 [P9.37] - 4005
    AIN3 [P9.38] - 3941
    AIN4 [P9.33] - 3956
    AIN5 [P9.36] - 3934
    AIN6 [P9.35] - 3946
    ...
    

    And here are the results after I plug-in the sensor:

    # python PyBBIO/examples/analog_test_simple.py
    -----
    AIN0 [P9.39] - 2888
    AIN1 [P9.40] - 2894
    AIN2 [P9.37] - 2899
    AIN3 [P9.38] - 2907
    AIN4 [P9.33] - 2914
    AIN5 [P9.36] - 2912
    AIN6 [P9.35] - 2914
    -----
    AIN0 [P9.39] - 2912
    AIN1 [P9.40] - 2905
    AIN2 [P9.37] - 2901
    AIN3 [P9.38] - 2891
    AIN4 [P9.33] - 2896
    AIN5 [P9.36] - 2890
    AIN6 [P9.35] - 2896
    ...
    

    You can see that plugging-in the sensor still affects all the values, regardless of the delay.

    After thinking about this a bit I decided to try to repeat the results with a script without using PyBBIO. I wrote a new Python file to test and print the reading from each analog-in pin on the BeagleBone using the Python os module. The file uses os.system('cat ...') to print the values, and includes a short delay between each. Here is the code:

    import os,time
    i = 1
    
    while(True):
        os.system("cat /sys/bus/platform/devices/tsc/ain" + str(i))
        print " - AIN" + str(i-1)
        if i==7: 
            i=1
            time.sleep(.5)
            print "------"
        else:
            i+=1    
        time.sleep(.1)
    

    Here are the results without any components plugged-into the BeagleBone:

    # python analog-test-all-pins.py
    ------
    3943 - AIN0
    3819 - AIN1
    3955 - AIN2
    2018 - AIN3
    2093 - AIN4
    3583 - AIN5
    3658 - AIN6
    ------
    3947 - AIN0
    3746 - AIN1
    3959 - AIN2
    2034 - AIN3
    2123 - AIN4
    3547 - AIN5
    3644 - AIN6
    ...
    

    And here are the results with the photoresistor circuit above plugged-into AIN0:

    # python analog-test-all-pins.py
    ------
    2915 - AIN0
    3347 - AIN1
    3556 - AIN2
    1478 - AIN3
    1602 - AIN4
    2393 - AIN5
    2402 - AIN6
    ------
    2913 - AIN0
    3337 - AIN1
    3560 - AIN2
    1487 - AIN3
    1606 - AIN4
    2350 - AIN5
    2489 - AIN6
    

    And here are the results with the photo resistor circuit data lead plugged-into AIN2:

    # python analog-test-all-pins.py
    ------
    3939 - AIN0
    3792 - AIN1
    2881 - AIN2
    1986 - AIN3
    2089 - AIN4
    3462 - AIN5
    3543 - AIN6
    ------
    3923 - AIN0
    3791 - AIN1
    2866 - AIN2
    1960 - AIN3
    2055 - AIN4
    3528 - AIN5
    3615 - AIN6
    ...
    

    AIN3:

    # python analog-test-all-pins.py
    ------
    3951 - AIN0
    3764 - AIN1
    3933 - AIN2
    2899 - AIN3
    2134 - AIN4
    3606 - AIN5
    3737 - AIN6
    ------
    3960 - AIN0
    3823 - AIN1
    3957 - AIN2
    2910 - AIN3
    2118 - AIN4
    3635 - AIN5
    3645 - AIN6
    ...
    

    photoresistor and TMP36 sensor

    And here are the results if I plug the photoresistor data lead back into AIN0 and plug a TMP36 temperature sensor into AIN3.

    # python analog-test-all-pins.py
    ------
    2866 - AIN0
    3340 - AIN1
    3540 - AIN2
    885 - AIN3
    1591 - AIN4
    2348 - AIN5
    2389 - AIN6
    ------
    2872 - AIN0
    3339 - AIN1
    3551 - AIN2
    884 - AIN3
    1560 - AIN4
    2383 - AIN5
    2434 - AIN6
    ...
    

    And just to confirm that the sensors are being read without affecting the other pins, here is the TMP36 on AIN5

    # python analog-test-all-pins.py
    ------
    2897 - AIN0
    3338 - AIN1
    3557 - AIN2
    1464 - AIN3
    1578 - AIN4
    888 - AIN5
    2459 - AIN6
    ------
    2901 - AIN0
    3344 - AIN1
    3561 - AIN2
    1460 - AIN3
    1579 - AIN4
    889 - AIN5
    2395 - AIN6
    ...
    

    This leads me to conclude that there is a issue with the PyBBIO library that is causing this. It is also causing the second problem, though I have no idea how...

    PROBLEM 2: Segmentation fault error

    The problem I had with the Segmentation fault error is due to something in the PyBBIO library. For example, if I restart the BeagleBoard and run:

    # cat /sys/bus/platform/devices/tsc/ain1
    3953
    # cat /sys/bus/platform/devices/tsc/ain2
    3818
    

    I get values which match the above output from the Python script using the os module.

    But if I run any PyBBIO script which accesses AIN pins (examples of which are above) and then run the cat again I get the error:

    # cat /sys/bus/platform/devices/tsc/ain1
    Segmentation fault
    # cat /sys/bus/platform/devices/tsc/ain2
    Segmentation fault
    

    If I restart the board (unplug and plug-in the power) I can use cat again:

    # cat /sys/bus/platform/devices/tsc/ain1
    2890
    # cat /sys/bus/platform/devices/tsc/ain2
    3366
    

    I also tried using Matt Richardson's mrBBIO library instead, with this file:

    from mrbbio import *
    
    def setup():
        #pinMode("P9.36", INPUT)
        pass
    
    def loop():
    
        print "-----"
    
        for key, value in analogPinDef.items():
            # There is currently an error in mrBBIO, as the analogPinDef dict points to:
            # ain[0-6] in /sys/devices/platform/tsc/ while it should point at: ain[1-7]
            if key=="P9.39": 
                print analogRead(key) + " - " + value
                delay(100)
    
        delay(1000)
    
    run (setup,loop)
    

    to get this:

    # python mrbbio/analog-test-all-pins.py
    -----
    2005 - ain4
    3636 - ain6
    3812 - ain2
    2114 - ain5
    3872 - ain3
    3950 - ain1
    -----
    2002 - ain4
    3530 - ain6
    3787 - ain2
    2059 - ain5
    3895 - ain3
    3952 - ain1
    ...
    Cleaning up. Unexporting the following pins:
    

    And I found it does not mess with my ability to get the results with cat -- possibly because it exports the pins at the end.

    # cat /sys/bus/platform/devices/tsc/ain1
    3960
    # cat /sys/bus/platform/devices/tsc/ain2
    3830