User avatar
Grumpy Mike
Posts: 914
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
Contact: Website

Reading two MCP3008 A/Ds

Thu Sep 22, 2016 7:22 pm

I can read the MCP3008 with the PiZero libiary or the wiringPi2 library. Each libiary allows you to choose what SPI channel the MCP3008 is on. This is determined by the GPIO pin used for the chip select pin on the MCP3008.
However, I am at a loss to find out how to read two MCP3008s, one on each SPI channel with either PiZero or wiringPi2.

At the moment I am using both libraries, one for each MCP3008, but surely there is a way to use only one libiary, any one know how?

Thanks

tom.slick
Posts: 190
Joined: Wed Jan 06, 2016 9:23 pm

Re: Reading two MCP3008 A/Ds

Thu Sep 22, 2016 7:57 pm

Couldn't you just call wiringPiSPISetup twice, once for channel 0 and then again for channel 1
wiringPiSPISetup (int channel, int speed)

and then use wiringPiSPIDataRW
int wiringPiSPIDataRW (int channel, unsigned char *data, int len)

User avatar
Grumpy Mike
Posts: 914
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
Contact: Website

Re: Reading two MCP3008 A/Ds

Fri Sep 23, 2016 6:10 am

Thanks Tom.
However how do you send:-
int wiringPiSPIDataRW (int channel, unsigned char *data, int len)
especially the pointer *data in Python?
Googling around I came across this solution but it did not work.

Code: Select all

myData = str(70)+'\n'
wiringpi2.wiringPiSPIDataRW(1,myData)
print myData

User avatar
joan
Posts: 14359
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Reading two MCP3008 A/Ds

Fri Sep 23, 2016 7:46 am

pigpio uses the following variants to send the SPI data bytes. wiringPi2 may work in a similar fashion.

pi.spi_xfer(h, b'\x01\x80\x00')

pi.spi_xfer(h, [1, 128, 0])

pi.spi_xfer(h, b"hello")

pi.spi_xfer(h, "hello")

h identifies the SPI channel.

The first two examples are what you need to send to a MCP3008 to read input 0.

User avatar
Grumpy Mike
Posts: 914
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
Contact: Website

Re: Reading two MCP3008 A/Ds

Fri Sep 23, 2016 10:13 am

Thanks joan,
The trick is to regenerate the variable that holds the data every time you do the SPI call because it writes all over it.
The code then:-

Code: Select all

data = chr(0x1)+chr(0x80)+chr(0)
rx = io.wiringPiSPIDataRW(0,data)
print rx
returns the tantalising
[3, '\x00\x01\xa4']
which the last two numbers are indeed the required data from the A/D converter.

But in typical Linux text adventure style I now find it impossible to extract the numbers from this. Attempts at printing rx[1] as anything seem to fail. Any idea on that please.

User avatar
joan
Posts: 14359
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Reading two MCP3008 A/Ds

Fri Sep 23, 2016 10:30 am

It appears to return a list with two entries. The first entry is the number of returned bytes, the second is a string containing the bytes.

rx[0] will be the count.
rx[1] will be the string.

rx[1][x] will be the x'th character of the string.

Try

value = ((ord(rx[1][1])&3)<<8) + ord(rx[1][2])

User avatar
Grumpy Mike
Posts: 914
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
Contact: Website

Re: Reading two MCP3008 A/Ds

Fri Sep 23, 2016 11:15 am

Thanks joan,
that did the trick. It was the ord function I was forgetting about.
Cheers
:D

User avatar
Grumpy Mike
Posts: 914
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
Contact: Website

Re: Reading two MCP3008 A/Ds

Fri Sep 23, 2016 3:35 pm

Just for completeness if anyone wants to know you can do this with PiZero as well. The problem was that the documentation is not very comprehensive. To read all the channels from two converters then you need this code:-

Code: Select all

#!/usr/bin/env python
import gpiozero
d1= [ gpiozero.MCP3008(channel=ch, device=0)
      for ch in range(0,8) ]
d2= [ gpiozero.MCP3008(channel=ch, device=1)
      for ch in range(0,8) ]

while(1):
  for channel in range(0,8) :  
     v1 = d1[channel].raw_value
     v2 = d2[channel].raw_value
     print v1, v2,
  print  

Return to “Python”