Following Getting Started guide for Raspberry Pi (how do I use Analog pins)?

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.

1 Like

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.

1 Like

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;
}