Once I got a MCP3008 I tried to use the library I created but I had no success (always 0) with my Raspberry Pi.
I'm interested in solving this problem though.
@jvanier, Any input on this?
Once I got a MCP3008 I tried to use the library I created but I had no success (always 0) with my Raspberry Pi.
I'm interested in solving this problem though.
@jvanier, Any input on this?
I noticed that the Adafruit setup, (with its own 3008 library) which has 2 python test programs, provides a choice of âSoftware SPI configurationâ or âHardware SPI configurationâ. I donât understand the difference between these, but when I changed the Adafruit simpletest.py code to comment out software configuration and enable hardware configuration as follows:
# Software SPI configuration:
# CLK = 18
# MISO = 23
# MOSI = 24
# CS = 25
# mcp = Adafruit_MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)
# Hardware SPI configuration:
SPI_PORT = 0
SPI_DEVICE = 0
mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))
this worked for me. So I know that my hardware works properly and that the Adafruit software can read the ADCâs analog channels.
However, Particle still doesnât allow me to read the MCP3008 analog pins. Has anybody else managed to do this? Surely somebody has managed to use Particle successfully with the Raspberry Pi?
I would be very grateful for help on this as this forum seems to be the only place where I can solve this problem. Thanks in advance.
I have moved the library here: https://github.com/nrobinson2000/particle-pi-mcp3008
Iâll try to see if I can work on it some more.
@peekay123, you seem to be the in-house expert on libraries and hardware. Do you have any input on this?
@nrobinson2000, software SPI is essentially a bit-banged version of SPI to implement shift in/out of serial data. If not implemented correctly, it wonât work. In the case of the Pi, the timing may be too fast for the MCP3008 so I would try putting a small delay at the end of each for
loop in MCP3008.cpp to slow things down. If that doesnât work, put a delay after the clock pin toggles:
digitalWrite(_clockpin, HIGH);
delayMicroseconds(250);
digitalWrite(_clockpin, LOW);
You may need to experiment but you get the idea.
How much of a delay?
Try 100us. I suspect itâs the clock high/low time is too short so that delay may be worth trying first.
I tried 250us a little while ago without any success. Should I go higher?
@nrobinson2000, assuming the software SPI code actually works then everything I read indicates the SPI clock should be set somewhat low, say 100KHz. Also assuming that delayMicroseconds()
actually works on the rPi then I would try this:
// read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
int MCP3008::readADC(int adcnum) {
if ((adcnum > 7) || (adcnum < 0)) return -1; // Wrong adc address return -1
// algo
digitalWrite(_cspin, HIGH);
digitalWrite(_clockpin, LOW); // # start clock low
digitalWrite(_cspin, LOW); // # bring CS low
delayMicroseconds(2);
int commandout = adcnum;
commandout |= 0x18; // # start bit + single-ended bit
commandout <<= 3; // # we only need to send 5 bits here
for (int i=0; i<5; i++) {
if (commandout & 0x80)
digitalWrite(_mosipin, HIGH);
else
digitalWrite(_mosipin, LOW);
delayMicroseconds(2);
commandout <<= 1;
digitalWrite(_clockpin, HIGH);
delayMicroseconds(2);
digitalWrite(_clockpin, LOW);
delayMicroseconds(2);
}
int adcout = 0;
// read in one empty bit, one null bit and 10 ADC bits
for (int i=0; i<12; i++) {
digitalWrite(_clockpin, HIGH);
delayMicroseconds(2);
digitalWrite(_clockpin, LOW);
delayMicroseconds(2);
adcout <<= 1;
if (digitalRead(_misopin))
adcout |= 0x1;
}
delayMicroseconds(2);
digitalWrite(_cspin, HIGH);
adcout >>= 1; // # first bit is 'null' so drop it
return adcout;
}