Use the Phantom YoYo High Sensitivity Water Sensor on the MCP3008 8-Channel 10-Bit ADC with SPI interface.
In an upcoming project I am using the MCP3008 to monitor several sensors. In this project I want to cover the details of using the Phantom YoYo High Sensitivity Water Sensor on the MCP3008 8-Channel 10-Bit ADC with SPI interface with the Raspberry Pi 2, Windows 10 IoT Core and C#.
Using the MCP3008
An ADC is an analog to digital converter. An analog signal is converted to a number and read into your application. The MCP3008 is a 10 bit ADC which means that it uses 10 bits to represent the value on the channel. The value will be represented as a number from 0 to 1023 (for a total 1024 possible values). This number is then converted into a meaningful value. For example, let’s say I want to measure a voltage on one of the channels and the value read from the channel is 523. I know that the maximum voltage is 3.3V. The voltage on the channel is calculated using the formula
Value / Max Value * Vref
solving for my voltage I get
523 / 1023 * 3.3
which gives a value of 1.687V. I calculated this value by first normalizing the reading and then multiplying the normalized reading value by the known maximum value of 3.3V.
When getting an accurate voltage measurement is important, I highly recommend measuring the actual voltage of the Raspberry Pi and using this value in your calculations to get a more accurate conversion from the ADC. When I measured mine I found that the out put was 3.301V (the value found in the source code). Not far off the actual, however, other types of boards may vary more.
Of course, this makes sense when I want to calculate voltage, but every sensor has a different meaning. For each sensor connected to a channel on the MCP3008 I need to know the specific details and interpret the reading appropriately.
Wiring the MCP3008 is straightforward. The chip itself is marked with a notch at one end which represents pins 1 and 16 (see the data sheet here).
Pins 1 through 8 are the eight input pins and are referred to as channels 0 to 7. Channel 0 is pin 1. Pin 16 is Vdd and connects to the voltage source (either 3.3V or 5V on the Raspberry Pi). Pin 9 connects to the ground pin on the Raspberry Pi. Pins 15 and 14 are used to reference the analog circuit. Pin 15 is Vref and is used by the MCP3008 to determine what the maximum voltage on one of the channels would be. In my example I connected this pin to the 3.3V source on the Raspberry Pi. When a voltage is applied to one of the channels the MCP adjusts the reading so that 1023 represents 3.3V and 0 represents 0V. This allows the calculation I used above to work. Pin 14 is the analog ground pin. In my example I connected it to the ground pin on the Raspberry Pi. If there is a need to keep the analog circuit isolated from the digital circuit then this pin would be connected to ground on the analog circuit. The remaining four pins, 10 through 13, are the SPI Serial Interface pins used to communicate with the Raspberry Pi. The wiring diagram I have included with this projects shows how to connect these pins to the Raspberry Pi.
In this project, I have included a simple voltage measurement to demonstrate this concept. The water sensor reading will demonstrate an alternative interpretation of the value read from the channel.
In this project I have connected up two circuits in one. The first is a simple potentiometer that will allow a voltage to be varied on one of the MCP3008 pins (channel 0). This is simply to demonstrate how the MCP3008 works. The second circuit is the water sensor connected to a second channel (channel 1) on the MCP3008.
The Phantom YoYo Water Sensor has three pins. The first pin is ground (labeled ‘-‘ on the device) which will get connected to the ground pin on the Raspberry Pi. The next pin is the power (labeled ‘+’ on the device) and it will get connected to the 3.3V pin on the Raspberry Pi (the device can also be connected to 5V). The third and final pin is the signal (labeled ‘s’ on the device. This pin has the voltage signal that will vary based on the amount of water on the device. Note this device is NOT a water level sensor. It simply senses varying amounts of water that come in contact with the device. The source pin will be connected to one of the inputs on the MCP3008.
The circuit to support the sensor is really simple. The device connects directly to the board Raspberry Pi without the need of any additional components.
The application I created for this project is a Universal Windows Applicationand shows two meters in the main view. The first meter shows the current voltage being measured on the potentiometer circuit. The second shows a reading from the water sensor that is normalized to a value of 0 to 100. The software also allow for a calibration of the water sensor. The link to the source code can be found near the bottom of the page.
The MCP3008 Library
The software project also contains a separate project for interacting with the MCP3008. This code can be used in your application to easily integrate the MCP3008 chip into your projects.
To use it, first declare an class object as follows:
private Mcp3008 _mcp3008 = null;
In the OnNavigatedTo event add the following code:
_mcp3008 = new Mcp3008(0);
To read the voltage from channel 0 use the following line of code:
float voltage = _mcp3008.Read(Mcp3008.Channels.Single0).AsScaledValue(3.3f);
Note the use of Channel.Single0 which indicates that the value is read from one channel. It is possible to specify that the device read the difference between two pins. This could be specified as Mcp3008.Channels.Differential0 which would indicate that the measurement should be taken as the different between channel 0 and channel 1 where channel 0 is positive and channel 1 is negative. The source code is document and will provide tooltips explaining each value.
When you are done using the object, typically in your OnNavigatedFromevent dispose of the object.
_mcp3008 = null;
Assemble the Circuit
Use this guide to assemble the circuit while using the diagram located near the bottom of the page as a guide (note the color of the wires are optional and have been selected to help make the circuit easy to follow when it is constructed).
Note: this project uses an optional multimeter to measure the voltage across the potentiometer. This is done to compare the value to the value read by the MCP3008. Note this is optional. If you do not have a multimeter then you will not be able to compare this voltage. This is done to show that the value read by the MCP3008 is the same as the value read by the multimeter. Set the multimeter to measure DC voltage as shown in the image below (your multimeter may look different).
- Place the T-shaped cobbler at the left end of the bard (where the numbers start at 1). The two left most pins will be in E3 and F3 on the board. The two right most pins will be at E22 and F22
- Place the 50K Ω potentiometer at positions J56, J58 and J60 with the adjustment knob facing the 5v side of the breadboard
- Place the 10K Ω resistor between I58 and I53
- Place the MCP3008 into E31 to E38 and F31 to F38 (the corner of the chip that has the indented circle will be placed at E31)
- Optional: Place one end of a black male to male jumper at position G60 (if you are using a multimeter then connect the black lead to this wire)
- Optional: Place one end of a red male to male jumper at position G58 (if you are using a multimeter then connect the red lead to this wire)
- Connect a blue male to male jumper wire between F60 and Ground
- Connect an orange male to male jumper wire between F58 and C31(channel 1 of the MCP3008)
- Connect an orange male to male jumper wire between F53 and 3.3V+
- Connect a red male to male jumper wire between J31 and 3.3V
- Connect a red male to male jumper wire between J32 and 3.3V
- Connect a black male to male jumper wire between J33 and Ground
- Connect a green male to male jumper wire between J34 and A14
- Connect a yellow male to male jumper wire between J35 and A13
- Connect a white male to male jumper wire between J36 and A12
- Connect a green male to male jumper wire between J37 and J14
- Connect a black male to male jumper wire between J38 and Ground
- Connect the female end of a blue female to male jumper to the S pin on the water sensor. Connect the male end to C32 (channel 1 on the MCP3008)
- Connect the female end of a red female to male jumper to the pin on the water sensor. Connect the male end to 3.3V
- Connect the female end of a black female to male jumper to the – pin on the water sensor. Connect the male end to Ground
- Optional: Connect the black lead from step 5 to the common terminal on your multimeter (use a hook clip type connector for best results)
- Optional: Connect the red lead from step 6 to the voltage terminal on your multimeter (use a hook clip type connector for best results)
- Connect the ribbon cable between the Raspberry Pi and the cobbler
Starting the Application
Choose Debug, ARM configuration and Remote Machine. Now right-click the project, and select Property and then click Debug tag. Next put the Raspberry Pi 2 IP address in the Remote machine field, and uncheck Use authentication.
Press F5. The application will deploy to the device which may take a few minutes the first time.
The video below is a demonstration the application:
Note: The application uses a linear 360° gauge to display the amount of water. I must note that this sensor does not have any linear correlation or any other correlation that I know of between the amount of water and the reading from the sensor. It does produces smaller values when there are a few drops versus higher values when more water is present. I use the linear gauge more to help understand the concept of the ADC. It is possible to wire the water sensor similar to how I wired my Opto-Isolated AC Voltage Sensor to produce either a high or low signal that could be picked up by a GPIO pin. This device could be wired to provide a wet or dry signal. Having said that, I am attaching this water sensor to an ADC because I want to detect the difference between a little water and a lot of water and the approach outlined in this project achieves this goal.