RE: SPI and Adafruit_BBIO, the TRM for the BBB, and Me!

Hello,

I am running a python3 program that has to do w/ SPI on the BBBW and the Adafruit_BBIO library. I set up my pins, set up the source, and ran the code.

I got back some odd numbers that mean nothing. I was following some ideas from Rpi stuff and transferring data to the BBBW via the Adafruit_BBIO library to make things work.

So…

`

from LDRII import MCP3008 #I found this source online and I cannot figure out what site I found it at currently. Anyway…if this is your source, say so! I will give you credit.

adc = MCP3008()

print(adc.read(channel = 0))

`

is the source I run from this library…

`

from Adafruit_BBIO.SPI import SPI

SPI0_CS0 = “P9_17”
SPI0_D0 = “P9_21”
SPI0_D1 = “P9_18”
SPI0_SCLK = “P9_22”

spi = SPI(1, 0)

class MCP3008:
def init(self, bus = 0, device = 0):
self.bus, self.device = bus, device
self.spi = SPI()
self.open()

def open(self):
self.spi.open(self.bus, self.device)

def read(self, channel = 0):
adc = self.spi.xfer2([1, (8 + channel) << 4, 0])
data = ((adc[1] & 3) << 8) + adc[2]
return data

def close(self):
self.spi.close()

`

Now, what I figured would happen, happened and I cannot explain it (yet).

Do you see my error in computation here?

Seth

P.S. I have to use config-pin to set up the pins for use but I receive variable numerical values every time I run the source from above. Please send some advice if you have time.

Hello Again,

I am receiving now, what I think are voltage levels, some levels from some simple math added to the source.

Seth

P.S. Here:

`

voltage: 0.0032258064516129032
16
voltage: 0.0032258064516129032
16
voltage: 0.0032258064516129032
0
voltage: 0.0032258064516129032
24
voltage: 0.0032258064516129032
10
voltage: 0.0032258064516129032
1
voltage: 0.0032258064516129032
24

`

The line below voltage is the original numerical value w/ what I think is the a voltage to the right of voltage. Here is the updated source to the library:

`

from LDRII import MCP3008
import time

adc = MCP3008()

while True:
Vref = 3.3
Voltage = (Vref / 1023)
print(“voltage: \t”, Voltage)
print(adc.read(channel = 0))
time.sleep(4)

`

from LDRII import MCP3008 #I found this source online and I cannot figure
out what site I found it at currently. Anyway...if this is your source, say
so! I will give you credit.

  Based on Google, the MCP3008 is a multichannel ADC. The Raspberry Pi
examples require it because the R-Pi only has binary GPIO.

  The BBB has internal ADC (though limited to 1.8V peak, so one often
needs a voltage divider to reduce 3.3V (or 5V) data to fit into 0..1.8V)
(for safety, one might want to limit the peak to 1.7V, and adjust the
conversion equation somewhat).

https://www.linux.com/tutorials/how-get-analog-input-beaglebone-black/
https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc

from LDRII import MCP3008 #I found this source online and I cannot figure
out what site I found it at currently. Anyway...if this is your source, say
so! I will give you credit.

  Based on Google, the MCP3008 is a multichannel ADC. The Raspberry Pi
examples require it because the R-Pi only has binary GPIO.

  The BBB has internal ADC (though limited to 1.8V peak, so one often
needs a voltage divider to reduce 3.3V (or 5V) data to fit into 0..1.8V)
(for safety, one might want to limit the peak to 1.7V, and adjust the
conversion equation somewhat).

https://www.linux.com/tutorials/how-get-analog-input-beaglebone-black/
https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc

>from LDRII import MCP3008 #I found this source online and I cannot figure

out what site I found it at currently. Anyway...if this is your source, say
so! I will give you credit.

  Based on Google, the MCP3008 is a multichannel ADC. The Raspberry Pi
examples require it because the R-Pi only has binary GPIO.

  The BBB has internal ADC (though limited to 1.8V peak, so one often
needs a voltage divider to reduce 3.3V (or 5V) data to fit into 0..1.8V)
(for safety, one might want to limit the peak to 1.7V, and adjust the
conversion equation somewhat).

https://www.linux.com/tutorials/how-get-analog-input-beaglebone-black/
https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc

>from LDRII import MCP3008 #I found this source online and I cannot figure

out what site I found it at currently. Anyway...if this is your source, say
so! I will give you credit.

  Based on Google, the MCP3008 is a multichannel ADC. The Raspberry Pi
examples require it because the R-Pi only has binary GPIO.

  The BBB has internal ADC (though limited to 1.8V peak, so one often
needs a voltage divider to reduce 3.3V (or 5V) data to fit into 0..1.8V)
(for safety, one might want to limit the peak to 1.7V, and adjust the
conversion equation somewhat).

Using an opamp is much safer

That code is doing NOTHING with the ADC readings.

  What you have calculated as "Voltage" is just the STEP value for the
ADC and it will never change. You have to multiply the step value by the
ADC reading to get the measured voltage. NOTE: you are defining Vref as 3.3
on EVERY pass of the loop: IT, and the STEP should be constants defined
outside the loop.

  NOTE: those numbers you were reporting look a lot like noise on a
grounded signal pin. A reading of 16 is just 0.0516 volts.

  You might want to look at
https://github.com/adafruit/Adafruit_CircuitPython_MCP3xxx/
(Adafruit is phasing out system specific libraries for CircuitPython -- and
provides the blinka library to map regular Python [as found on R-Pi and
BBB] to the CircuitPython API)

https://learn.adafruit.com/circuitpython-on-raspberrypi-linux?view=all
(also applies to BBB if you follow the required install instructions for
blinka)

Hey and Hello,

I got the info. more suited to abide by actual rules instead of guessing like I did do earlier in my source.

Thank you for the links. I did get some help on Freenode too. I will look over the links. I have them up now.

Seth

P.S. Here is a setup maybe worth while?

`

from LDRone import MCP3008
import time

adc = MCP3008(bus=0, device=0, vref=3.3)

try:
while True:
voltage = adc.read(channel=0) # across resistor
current = voltage * 10000 # through resistor and LDR
resistance = (adc.vref - voltage) / current # of LDR
print(“voltage: \t”, voltage)
print(“current: \t”, current)
print(“resistance: \t”, resistance)
time.sleep(4)

except:
print(“Get gone!”)
pass

`

Here is LDRone.py

`

from Adafruit_BBIO.SPI import SPI

class MCP3008:
def init(self, bus, device, vref):
self.vref = vref
self.spi = SPI(bus, device)

def read(self, channel):
data = self.spi.xfer2([1, (8 + channel) << 4, 0])
value = ((data[1] & 3) << 8) + data[2]
return value * self.vref / 1023

def close(self):
self.spi.close()

`

Hello,

Yes…I know. I read earlier from a book that the op amp is a goto source for handling this device, i.e. the LDR/photoresistor.

Seth

P.S. Thank you for the heads up.

Just some stuff I scratched together -- all untested (read the
comments)

-=-=-=- adc-1.py
#!/usr/bin/env python3
"""
    adc-1.py ADC example using MCP3008 and mysterious LDRII library
    November 11, 2019 Dennis L Bieber

    *** UNTESTED **
    Not only do I not have access to an MCP3008 ADC chip, I have not
    been able to find the LDRII (Light Dependent Resistor?) library
    supporting said chip.
    The API used is based upon postings in comp.lang.python by one
    "Mala Dies" who, it seems, is having a truly bad day

    This code reads all 8 channels of the MCP3008. It may be worth
    checking the data sheet for the chip to determine which state
    draws the least current and using a 10KOhm or higher resister to
    pull-up/pull-down the unused inputs.
"""

import time
from LDRII import MCP3008

#constants from spec sheets
ADC_BITS = 10
ADC_REF = 3.3
ADC_CHANNELS = 8

T_DELTA = 5.0

#derived constants
ADC_MAX = (2 ** ADC_BITS) - 1
ADC_VSTEP = ADC_REF / ADC_MAX

#create ADC instance
adc = MCP3008()

t0 = t = time.time()
while True:
    print("\nT: %16.2f" % (time.time() - t0))
    for channel in range(ADC_CHANNELS):
        raw = adc.read(channel = channel)
        print("\tChannel: %2d\tCount: %4d\tVoltage: %6.3f"
              % (channel, raw, raw * ADC_VSTEP))
    t += T_DELTA
    time.sleep(t - time.time())

-=-=-=- adc-2.py
#!/usr/bin/env python3
"""
   adc-2.py ADC example using MCP3008 and Adafruit_Blinka
                   and Adafruit_CircuitPython_MCP3xxx libraries
   November 11, 2019 Dennis L Bieber

   *** UNTESTED **
   I do not have access to an MCP3008 ADC chip

   *** PREREQUISITES ***
       sudo pip3 install adafruit_blinka (might be adafruit-blinka)
       sudo pip3 install adafruit-circuitpython-mcp3xxx

   This code reads all 8 channels of the MCP3008. It may be worth
   checking the data sheet for the chip to determine which state
   draws the least current and using a 10KOhm or higher resister to
   pull-up/pull-down the unused inputs.
"""

import time

import busio
import digitalio
import board
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn

#constants from spec sheets
ADC_REF = 3.3
ADC_CHANNELS = 8

T_DELTA = 5.0

#create the SPI bus and ChipSelect
spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
cs = digitalio.DigitalInOut(board.DS)

#create ADC instance (note: ref_voltage default is 3.3 if not supplied)
adc = MCP.MCP3008(spi, cs, ref_voltage = ADC_REF)

#create ADC channel instances -- relies on MCP.P0 = 0, etc.
channels = [ AnalogIn(adc, chan) for chan in range(ADC_CHANNELS) ]

t0 = t = time.time()
while True:
   print("\nT: %16.2f" % (time.time() - t0))
   for channel in channels:
       #while a 10-bit ADC chip, the raw counts are scaled to 65472

  WHOOPS...

       raw, voltage = channels[channel].value, channels[channel].voltage

    raw, voltage = channel.value, channel.voltage

Actually, forget the immediately prior correction for adc-2

-=-=-=- adc-2.py
#!/usr/bin/env python3
"""
   adc-2.py ADC example using MCP3008 and Adafruit_Blinka
                   and Adafruit_CircuitPython_MCP3xxx libraries
   November 11, 2019 Dennis L Bieber

   *** UNTESTED **
   I do not have access to an MCP3008 ADC chip

   *** PREREQUISITES ***
       sudo pip3 install adafruit_blinka (might be adafruit-blinka)
       sudo pip3 install adafruit-circuitpython-mcp3xxx

   This code reads all 8 channels of the MCP3008. It may be worth
   checking the data sheet for the chip to determine which state
   draws the least current and using a 10KOhm or higher resister to
   pull-up/pull-down the unused inputs.
"""

import time

import busio
import digitalio
import board
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn

#constants from spec sheets
ADC_REF = 3.3
ADC_CHANNELS = 8

T_DELTA = 5.0

#create the SPI bus and ChipSelect
spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
cs = digitalio.DigitalInOut(board.DS)

#create ADC instance (note: ref_voltage default is 3.3 if not supplied)
adc = MCP.MCP3008(spi, cs, ref_voltage = ADC_REF)

#create ADC channel instances -- relies on MCP.P0 = 0, etc.
channels = [ AnalogIn(adc, chan) for chan in range(ADC_CHANNELS) ]

t0 = t = time.time()
while True:
   print("\nT: %16.2f" % (time.time() - t0))

  Replace following...

   for channel in channels:
       #while a 10-bit ADC chip, the raw counts are scaled to 65472
       raw, voltage = channels[channel].value, channels[channel].voltage
       print("\tChannel: %2d\tCount: %4d\tVoltage: %6.3f"
             % (channel, raw, voltage))

    for ch, channel in enumerate(channels):
        #while a 10-bit ADC chip, the raw counts are scaled to 65472
        raw, voltage = channel.value, channel.voltage
        print("\tChannel: %2d\tCount: %4d\tVoltage: %6.3f"
              % (ch, raw, voltage))

Hello Mr. Dennis,

Seth here. Thank you again. It is nice to have people just away ideas like this one. I know you know more than I do on this subject. I am new to SPI and using in Linux Distros on the BBBW never crossed my path until this task.

So, I will put in your source and see how it works. Would you like to know the answer or terminal writing, I am sure you already have tested it, when I run the source?

Seth