I want to convert/transfer a program, which reads humidity sensors via a MCP3008 ADC, from Raspberry PI 4 to Le Potato.
The program looks like this:
import time
import tkinter
from time import gmtime, strftime
import pin_mapping
import libregpio as GPIO
from libregpio import OUT, IN
from tkinter import *
import pathlib
from pathlib import Path
import busio
import smbus
import serial
import adafruit_blinka
#from analogio import analogin
import digitalio
import board
# create the spi bus
spi = busio.SPI((pin.SPI0_SCLK), (pin.SPI0_MOSI), (pin.SPI0_MISO))
# create the cs (chip select)
cs = digitalio.DigitalInOut(P26)
# create the mcp object
mcp = MCP.MCP3008(spi, cs)
# create an analog input channel on pin 0
chan = AnalogIn(mcp, MCP.P0)
print("Raw data: ", chan)
print ("voltage: "+str(chan.voltage)+"V")
The output of the first print is: raw data: <adafruit_mcp3xxx.analog_in.AnalogIn object at 0xffffbb859040>
The next print result in the following error:
It looks like youāre using Blinka, both it and libgpiod need to be installed through apt, donāt install libgpiod through pip. You didnāt show your imports, so I donāt know what the module āpinā is from, Iād use board instead, and implicitly specify pin numbers rather than board.SCLK, etc. I also needed to use adafruit_extended_bus rather than busio to get i2c working, it would be a good idea to use this instead because it allows you to specify the device.
Thank angus for your answer.
I have added my INPORTs in my original question
SPI is enabled as required and libgpiod was installed by: sudo apt-get install python3-libgpiod
I donāt know if āadafruit_extended_busā can be used for SPI, or how?
Henrik
MCP3008 is already supported by the Linux kernel mcp320x driver. You just need to create a spi overlay with the proper compatible to use the driver. It will show up as a kernel IIO device.
There is sample code in the link I provided, but you might be able to get it working with busio if youāre using spidev 0.0.
Iāve only used SPI in CircuitPython with a microcontroller and a LCD, so Iāll need some time to put together an example.
A few things Iāve noticed right off the bat:
It looks like you have competing libraries imported to handle GPIO. I donāt Imagine this is good practice. Since youāre using Blinka, you can just use board and digitalio to handle the pins.
Also anlogio is used but the import statement is commented out.
You want to āprint(chan.value)ā otherwise you get the object itās self, not the variable stored within.
I donāt see āchan1ā declared anywhere. I think that should be āchan.voltageā.
The print statements are indented, not sure why.
SPI setup should be something like this:
spi = busio.SPI(board.P23, MISO=board.P21, MOSI=board.P19)
cs = digitalio.DigitalInOut(board.P26)
MCP3008 is already supported by the Linux kernel mcp320x driver. You just need to create a spi overlay with the proper compatible to use the driver. It will show up as a kernel IIO device.
I understand the first sentence - but not a word of the rest. What a "compatible"? and where will it "show up"?
I added an MCP3008 to my Adafruit order. Iāll see if I can get it working both ways (@librecomputer 's way is something Iāve been trying to teach myself). In the mean time there are two 1.8V ADCs built in to the potato. Youāll have to do some level shifting, but Iāve used it to read a photoresistor. Iāll dig up the code for you, but in a nutshell you just use open() to read the file.
Answer from angus:
If I delete the āImport libregpioā it makes no difference. I use libregpio as an easy way to specify GPIO names to handle relays
You want to āprint(chan.value) ā otherwise you get the object itās self, not the variable stored within.
Yes, but it is the only call that works. As soon as I add an argument [as in (chan.value) or (chan.voltage) ],
I just get the: āInvalid argumentā error for that statement.
When I use your proposal: spi = busio.SPI(board.P23, MISO=board.P21,ā¦) I function as well, but I still get the āInvalid argumentā error.
Itās just printing the objectās address in memory though, so thatās not really working either.
Just Noticed:
In the sample code, instead of the regular āanalogio.AnalogIn()ā they use āadafruit_mcp3xxx.analog_in.AnalogIn()ā.
The āanalogio.AnalogIn()ā class only accepts one pin as an argument, and I think is more of a micro-controller thing. Thatās probably the invalid argument error.
so try āfrom adafruit_mcp3xxx.analog_in import AnalogInā instead of the line thatās commented out in your imports.
I also just noticed AnalogIn is all lowercase in your import. That could muck things up for sure. Classes are usually EachWordUppercse in python (as per style guide anyhow).
so try āfrom adafruit_mcp3xxx.analog_in import AnalogIn ā instead of the line thatās commented out in your imports.
I have done so, but no change.
However I tried to change "print("ADC value: " chan.value) to chan.VALUE and have then the repons
AttributeError: āAnalogInā object has no attribute āVALUEā
With other words: āvalueā is a valid attribute. But what is then ment with āinvalid argumentā? To what āargumentā is the system referering.
Answer to angus
I am not using analogio, but mcp3008.analog_in
Did I mention that my code is working correctly on my Raspberry Pi ? The problem has something to do with the actual board ( AML-S905X-CC)
PS. I want to move this small program to Le Potato in order to use the RPI 4 for something else.
I have reinstalled everything, even flashed the microSD, in order to ensure that there is no conflicting modules or different releases - but I still get the same error related to adafruit_mcp3xxx.mcp3008
File ā/home/librecomputer/.local/lib/python3.9/site-packages/Adafruit_PureIO/spi.pyā, line 420, in transfer
ioctl(self.handle, SPI._IOC_MESSAGE, spi_ioc_transfer)
OSError: [Errno 22] Invalid argument
As mentioned before, the code works on an RPI 4.
Any ideas?
I know, this was the solution I was most familiar with, so I tried it first. Iām preparing to do a deep dive into Device Tree Overlays this week. I still intend to work on that solution too. My family went on holiday an left me to tinker in peace, so maybe Iāll make some quick progress.
My main interest in getting the Adafruit library working is creating code that will run on my RP2040 based microcontrollers as well, without too much modification. I donāt intend to use much circuitpyton on projects that permanantly live on a potato, but there is some value in getting this to work this way, for me at least.
The photoresistor Iām testing this with can easily be read with the adc pins, I just made a simple voltage divider to turn the 3.3V to 1.8V and used pythons built in functions to read the file. Thatās not a great solution either though, and wont work for something more sophisticated that runs off 5V.