With it enabled I can cat /sys/bus/iio/devices/iio:device1/in_voltage0_raw
and get a value between 0 and 1024. Tested channel 0 with a 10k pot and a photoresistor, and it works.
Now I’m going to test it a bit more, submit my pull request and then work out some python code. It should be a simple matter of reading the in_voltage0_raw with open().
Here’s the python code to go with it. I’m getting some inaccurate results, but I had my chip wired wrong and it heated up substantially at one point, so that may be the cause of the problem. Also, for some reason, if I supply 5V to any pin, the rest of them read 1023 as well. Otherwise, it seems to work. The numbers change when I adjust the pot.
#!/usr/bin/env python3
import time
def read_mcp3008(channel=0, device=1):
'''Reads MCP3008 connected as an iio device.Takes a channel number (0-7)
and iio device number as arguments. Returns an integer from 0-1023'''
channel_path = f"/sys/bus/iio/devices/iio:device{device}/in_voltage{channel}_raw"
with open(channel_path, 'r') as f:
return(f.read())
def adc_to_voltage(reading, ref_voltage=5):
'''Converts a reading into a voltage. Takes reading and
reference voltage as arguments. Default ref_voltage is 5V.'''
n = float(reading) / 1023
return(n*ref_voltage)
while True:
for i in range(0, 8):
r = read_mcp3008(i)
v = adc_to_voltage(r)
print(f'channel{i} : {r} - {v}V')
print('***********************')
time.sleep(1)
Ah, that’s probably the issue!
You should probably change to “def adc_to_voltage(reading, ref_voltage=3.3):” and update the docstring accordingly.
That code should read every channel once every second and print to the terminal. Note that the value returned will also now be 0-1023. You’ll need to enable the overlay to use it. To do so you can download the wiring tool from my github (git clone or download the zip, whichever way is easiest for you). Open the directory “libretech-wiring-tool” in terminal and run “make” to compile. From within that same directory run “sudo ./ldto enable spicc spicc-mcp3008”.(If you don’t run it this way you’ll get the installed version, not the one you just maked[sic])
angus@aml-s905x-cc:~$ cd Projects/libretech-wiring-tool/
angus@aml-s905x-cc:~/Projects/libretech-wiring-tool$ make # you'll get more output from make
make: Nothing to be done for 'all'.
angus@aml-s905x-cc:~/Projects/libretech-wiring-tool$ sudo ./ldto enable spicc spicc-mcp3008
[sudo] password for angus:
Overlay spicc: applied
Overlay spicc-mcp3008: applied
Here’s my fork of the repo with the new overlay:
I’d also skim this:
You can just run “cat /sys/bus/iio/devices/iio:device1/in_voltage0_raw”" in terminal to read it with the overlay applied. it just show up as a file now. You can check it out using the file manager.
It just occured to me that I should mention this is based directly off the function I use to read the built-in 1.8V adc, which is iio:device0 so you could read channel 0 with “read_mcp3008(0, 0)” or channel 1 with “read_mcp3008(1, 0)” . Guess I should have kept the name “read_adc()”.
I have tested your code and it “appears to work”, but…It gives some random figures and as I am curious I tried to disconnect the mcp3008 pin by pin. The code gives more or less the same random figures whether it is connected or not. I think the readings are a noise signal within the Libre Computer.
I originally connected it to the SPI pins (23, 21, 19 and 29 for the CS). Is that wrong?
This is for cha = 0 dev = 0.
Nix that!(the part about mine being fried that is, the ce pin is really 24) I just got a wild hair and looked at a few other overlays. I got the sample rate wrong. Works fine now. The corrected overlay is up on my github. I’d download it fresh, there have been other commits since.
EDIT:
I just did the dead obvious thing and looked at the datasheet again. 5V is OK.
You are right. I did look as well. The MCP3008 uses 5V
After your update of the overlay I have a very odd problem with “make”. It processes the overlay (list a spicc-mcp3008.pre.dts) but when I use
$ sudo ldto enable spicc spicc-mcp3008
LDTO_enable: spicc-mcp3008 does not exist and cannot be added
Yesterday I was able to enable the overlay. What can I be doing wrong to day?
You need to cd into the libretech-wiring-tool directory and run “sudo ./ldto enable spicc spicc-mcp3008” the “./” bit tells the shell to run the version in the current directory instead of the installed system version.
Demonstrate my lack of knowledge of Linux. spicc-mcp3008 is now added.
But the test program still reads random values. The same values are read even when MCP3008 is disconnected.
Hmmm. If nothing is connected to an ADC the pins should “float” or give a random value. That essentially means any pin that’s not being used will return garbage. I’m not sure what the effect of unplugging a device and trying to read from the driver should be.
This is what I get with Ch0 connected to 3.3V and Ch1 to GND, and nothing else:
I don’t know how often the software is updated, but this overlay should be included in future versions of the tool, so you wont have to jump though these hoops forever. @librecomputer might be able to shed some light as to how that works; I’m pretty green when it comes to contributing. This was my first Pull Request. I don’t know anything about what happens between my PR being merged and downloading the new tool with a package manager.
Meanwhile back at the ranch…
I opened an issue about this on Adafruit’s github. It seems like the tater isn’t being recognized properly by Blinka, and it’s using generic Linux pinmapping. It’s a bit above my head. I offered to implement an iio version of the mp3xxx module. They didn’t seem keen, but are looking into fixing their current implementation. I might get bored and do it anyhow, I don’t know yet.
As much as I like the idea of being able to prototype on a SBC and move to a microcontroller when it’s time, Blinka seems kind of broken, at least if you don’t pay a pi scalper an arm and a leg for a piece of fruit. It doesn’t work right on this board, doesn’t work at all on my odroid. For projects that aren’t going to wind up living on a RP2040, I’m not going to bother with it anymore.
My ch0 is at 3.3V, ch1 = 0v, ch2 = potentiometer, ch3-ch7 are all grounded.
If I read from device 1 i get 1023 on all channels (0 -7)
It should be a simple task to read a value from a pin. I don’t understand the complexity in the basic code. I think it is so complex that nobody really understand how all the components works together (or not work together).
I have an Anduino board. I will try if it can run my application. Of cause I will need to learn that box and to reprogram everything, but it might be easier.
Thank you for all the time you have used trying to help me.
Henrik.
I’m not having any issues reading the device now. I’ve tried a pot, voltage divider, thermistor, photocell and vacuum pressure sensor all to good effect, so it can work. I don’t call using the python’s open() built-in to read a file difficult, especially compared to what Adafruit’s code is doing under the hood.
Thanks for presenting this challenge, anyhow. I was overjoyed when I saw the device on my breadboard show up in my filesystem.
You are right about the open().
I have found an error in my breadboard(sic) - no power or no GND to the MCP3008. Will try tomorrow with another breadboard.
Glad it worked! I’m new to this, so I’m sorry if it was a long road getting here. I know it’s not the best situation when the guy helping you is also learning things for the first time.
My main interest in embedded Linux is retro gaming agricultural so this was a good way to justify buying more ic’s to play with learning exercise. As soon as all the dust settles, and all the PRs are merged I’ll write a tutorial with some cleaner looking sample code and clear instructions.
I made a new AnalogIn class for use with iio devices I’m going to submit to Adafruit soon, and I’m also looking into the problem with Blinka that started all this. As strange as this may be to say on post # 45 on this thread, it turns out the Libre “just learn to do it the right way” solution was really the “easy” solution this time.
Blinka is a mess under the hood, thanks in part to soc/SBC makers not having any common standards. What should be a simple if/then is turned into this crazy soup of pin mapping and board-specific functions. Just for a taste, an instance of this monstrosity is created every time you import board:
I had 7 browser tabs open just trying to figure out what it does.