I have hardwired a MCP3008 IC into the SPI input on a Raspberry Pi3.
MCP3008 is wired as follows:
pin 10 (CS) to Pi GPIO_10 (pin 24) this is CE0
pin 11 (Din) to Pi GPIO_12 (pin 19) this is MOSI
pin 12 (Dout) to Pi GPIO_13 (pin 21) this is MISO
pin 13 (CLK) to Pi GPIO_14 (pin 23) this is SCLK
I am using a single TMP36 wired into channel 0, pin 1 of the MCP3008.
When I measure the voltage of the TMP36 output it is correlating to the measured surface temperature of the board it is mounted to, which is approximately 23 degrees celsius. For those interested, I am using a Fluke 62 MAX+ IR thermometer to take the measurement.
My problem is twofold:
1) I read nothing but zero in my java program, and in a python script I wrote for comparison. Here is the output I get when I make a HTTP GET request to the resource.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<gpioRepresentation>
<garageDoorFeedbackState>LOW</garageDoorFeedbackState>
<zoneOneState>LOW</zoneOneState>
<zoneTwoState>LOW</zoneTwoState>
<zoneThreeState>LOW</zoneThreeState>
<garageDoorRelayState>LOW</garageDoorRelayState>
<panelTemperature>0.0</panelTemperature>
<zoneOneRelayState>LOW</zoneOneRelayState>
<zoneThreeRelayState>LOW</zoneThreeRelayState>
<zoneTwoRelayState>LOW</zoneTwoRelayState>
</gpioRepresentation>
2) Why is both CE0 and CE1 measuring 3.3Vdc?
My understanding of SPI is that the active channel must have its corresponding chip select logic level LOW or 0Vdc. So why is it high? How can I drive it low using the pi4j library or in python?
Here is the class with the code I wrote for this. I have included all imports, fields, and the constructor. I have omitted getters and setters as they take too much space and aren't relevant to this.
...
import com.pi4j.gpio.extension.base.AdcGpioProvider;
import com.pi4j.gpio.extension.mcp.MCP3008GpioProvider;
import com.pi4j.gpio.extension.mcp.MCP3008Pin;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinAnalogInput;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.event.GpioPinAnalogValueChangeEvent;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerAnalog;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;
import com.pi4j.io.spi.SpiChannel;
import com.pi4j.io.spi.SpiMode;
...
/**
* Class that models the physical Raspberry Pi resources and represents them in XML.
* Access methods to read and write physical I/O state are synchronized to
* maintain consistent state of the GPIO when multiple users are accessing
* the controls.
* Only one object of this class is to ever exist, as it is a representation
* of this physical real world device that it resides on.
*/
@XmlRootElement
public class GpioRepresentation implements GpioSubject, EventSubject
{
private static GpioRepresentation gpioRepresentation = null;
private GpioObserver observingResource;
private EventObserver eventObserver;
private final GpioController gpio;
...
private final AdcGpioProvider provider;
private final GpioPinAnalogInput rawInput;
...
@XmlTransient
private double panelTemperature;
private GpioRepresentation() throws IOException
{
//get instance of gpio factory object
gpio = GpioFactory.getInstance();
...
// Create custom MCP3008 analog gpio provider
provider = new MCP3008GpioProvider(SpiChannel.CS0, SpiMode.MODE_0);
// Provision gpio analog input pins for all channels of the MCP3008.
rawInput= gpio.provisionAnalogInputPin(provider, MCP3008Pin.CH0, "MyAnalogInput-CH0");
// Define the amount that the ADC input conversion value must change before
// a 'GpioPinAnalogValueChangeEvent' is raised. This is used to prevent unnecessary
// event dispatching for an analog input that may have an acceptable or expected
// range of value drift.
provider.setEventThreshold(100, rawInput);
// Set the background monitoring interval timer for the underlying framework to
// interrogate the ADC chip for input conversion values.
provider.setMonitorInterval(250);
// Create an analog pin value change listener
GpioPinListenerAnalog aDClistener = new GpioPinListenerAnalog()
{
public void handleGpioPinAnalogValueChangeEvent(GpioPinAnalogValueChangeEvent event)
{
// get RAW value
double value = event.getValue();
//calculate the temperature
calculateTemperature(value);
}
};
// Register the gpio analog input listener for input
gpio.addListener(aDClistener, rawInput);
}
public void calculateTemperature(double raw)
{
double millivolts = raw * ( 3300.0 / 1023.0 );
panelTemperature = ((millivolts - 500.0) / 10.0);
}
@XmlElement
public synchronized double getPanelTemperature()
{
return panelTemperature;
}
... (other methods omitted)
}
As an FYI, SPI has been configured/enabled on my Pi. I am using Ubuntu Mate as my OS.
Here are some pictures of the physical connections.
Please note that on the MCP3008 connections, Pin 10 is correctly grounded, and that pins 11, 12, 13, and 14 are connected to the Pi.
Here is the schematic for the MCP3008 connections. Ignore the pin numbers, I need to update this.
And here is the CAD drawing showing the interconnections. Please note I have redlined the prints I am working for and need to update this drawing to show that I already swapped the white and black wire on the breakout board for MOSI and MISO.