Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Here are references for how to connect and code each physical input in your SparkFun Photon kit:
Ultrasonic Sensor (not standard part of SparkFun Photon kit, but your teacher may have added it)
OTHER SENSORS: There are references for other sensors such as RFID Reader, Fingerprint Scanner, and GPS Receiver in the old project guidebook. These references will eventually be transferred into this new code guidebook.
Your Photon kit includes a "trimpot" (trimmable potentiometer) that can be rotated and used as a dial. A potentiometer is a variable resistor that can be adjusted by sliding, rotating, or another type of physical interaction. Potentiometers are used in various devices such as: joysticks and game controllers, control knobs and sliders, dimmer switches for lights, volume knobs for stereos, etc.
The trimpot dial can be rotated clockwise or counterclockwise approximately 270° (it does NOT rotate all the way around). The position of the dial can be measured and used as an input for a value that has a range from minimum to maximum.
The trimpot dial has 3 metal legs that will be inserted into pin holes on the breadboard.
To connect a trimpot dial to your Photon using the breadboard, you will need:
Trimpot
3 jumper wires (use different colors to help identify them)
3.3V MAXIMUM: Analog inputs, such as the trimpot, require 3.3V of power for accurate measurements. Connect the trimpot to the 3.3V pin on your Photon, or connect it to a positive power rail that's connected to the 3.3V pin.
TWIN PINS: Analog pins A2, A3, A4, and A5 are each represented by two pins on the Photon board. The duplicate pins are labeled as: SS/A2, SCK/A3, MISO/A4, MOSI/A5. If you use one of these pins, you cannot use its twin at the same time.
Here are the steps to connect the trimpot to your Photon using the breadboard:
Insert the three metal legs of the trimpot into different terminal strip rows on the breadboard. (Different terminal strip rows have different row numbers.)
Plug one end of a jumper wire into the same terminal strip row as an outer leg of the trimpot. Plug the other end of this jumper wire into the 3.3V pin on the Photon circuit board (or plug it into a positive power rail that's connected to the 3.3V pin via a different jumper wire).
Plug one end of a second jumper wire into the same terminal strip row as the middle leg of the trimpot. Plug the other end of this jumper wire into any analog I/O pin on the Photon circuit board.
Plug one end of the third jumper wire into the same terminal strip row as the other outer leg of the trimpot. Plug the other end of this jumper wire into a pin hole connected to GND: either plug it into a negative power rail (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect a trimpot (ignore the wiring for the three push buttons):
Keep in mind that your connection can look different than this example diagram:
Your trimpot legs could be inserted into different row numbers. (The example connects the trimpot legs to rows 26-28 on the right side of the breadboard).
Your trimpot legs could be inserted into a different column of the breadboard. (The example connects the trimpot legs into column F of the terminal strip rows).
Your trimpot could connect (through a jumper wire) to a different analog I/O pin. (The example connects the trimpot to the A0 pin.)
Your trimpot could connect (through a jumper wire) either directly to the 3.3V pin or to a positive power rail on the breadboard that's connected to the 3.3V pin.
Your trimpot could connect (through a jumper wire) either directly to a GND pin or to a negative power rail that's connect to a GND pin. (There are three available GND pins.)
The basic steps to control a trimpot dial in your app code are:
Declare a global variable to store the I/O pin number for the trimpot.
Use the analogRead()
method to measure the trimpot dial position.
OPTIONAL: Use the map()
method to convert the trimpot reading to a custom range.
You should declare a global variable to store the I/O pin number that the trimpot is connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the trimpot to a different pin number).
Add this code statement (modify if necessary) before the setup()
function:
This line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variable will be called trimpot
. You can change the variable name, but choose a name that will make sense to anyone reading the code.
It assigns a value to the variable. In this example, the variable's value will be equal to A0
. If necessary, modify this value to match the actual I/O pin that your speaker is connected to.
PIN MODE: Analog inputs do NOT need to have their pin mode set within the setup()
function. Their pin mode gets automatically set when the analogRead()
method is used.
The analogRead()
method is used to read the trimpot, which indicates the trimpot dial position.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
A local variable named trimpotRead
is declared that will have a data type of int
(integer). This variable is made equal to whatever value is returned by the analogRead()
method. You can change the name of this variable, but it will make sense if it's similar to the variable name used for the trimpot pin number.
The analogRead()
method requires one parameter insides its parentheses:
The I/O pin number, which can be the actual pin number (such as: A0
, etc.) or a variable that stores a pin number. In this example, the variable named trimpot
is listed. If necessary, change this to match the variable name for your trimpot's pin number.
The analogRead()
method will return an integer (whole number) value ranging from 0-4095:
If the dial is rotated all the way to the left (counterclockwise), the value will be 0.
If the dial is rotated all the way to the right (clockwise), the value will be 4095.
If the dial is rotated somewhere in-between, the value will be proportional to the dial's position. For example, if the dial is rotated exactly halfway, the value will be 2048.
You'll need to add code to do something with the reading stored as trimpotRead
. For example, this might be an if-else statement to perform certain actions based on whether trimpotRead
is greater than (or less than) one or more specific values.
In many cases, it may not be convenient to work with a value that ranges from 0-4095. Instead, it might be easier to have a value within a smaller custom range (such as: 0-10, 0-100, etc.) that makes more sense for your particular task.
The map()
function can be used to convert a value from its original range (such as 0-4095) into a new range of your choice. You decide the minimum and maximum values for the new range.
For example, if a trimpot dial were being used to control the brightness of an LED light, you might want the trimpot to return a value between 0-255 because the analogWrite()
method used to set the brightness of an LED requires a value in this range.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
As necessary, change the values assigned to minValue
and maxValue
to whatever numbers you want to use for your custom range. Also, the minValue
doesn't have to be zero.
Be sure to add code to do something with trimpotValue
. For example, this might be an if-else statement to perform certain actions based on whether trimpotValue
is greater than (or less than) one or more specific values.
NOTE: The code uses the round()
method to round the mapped value to the nearest integer because the map()
method returns a float
(decimal value). Also, inside the map()
method, the code intentionally adds 1 to the maxValue
because otherwise it is very difficult to get the maximum value even if the trimpot dial is turned clockwise all the way.
You could incorporate this code into a custom function called checkSensor()
that will read an analog sensor and return a value mapped to a custom range:
When calling the checkSensor()
function within the loop()
function, you will need to include values for these 3 parameters (in order) inside its parentheses:
the sensor's pin number, which will most likely be a variable that stores the pin number
the desired minimum value for the range, which should be an integer (whole number)
the desired maximum value for the range, which should be an integer (whole number)
The checkSensor()
function will return the mapped sensor value as an integer, which your code should store in a variable of data type int
.
For example, to call the checkSensor()
function within the loop()
function:
The checkSensor()
function could also be used to read other analog sensors, such as a light sensor:
Trimpot
Photon Pin
Outer Leg (pick one)
3.3V
Middle Leg
any analog I/O pin (A0, A1, A2, A3, A4, A5)
Other Outer Leg
GND
The soil moisture sensor in your Photon kit can be inserted into soil or similar materials (sand, etc.) to measure the amount of moisture in the material.
The moisture sensor is a variable resistor with two gold-plated legs that are inserted into soil. Moisture in the soil will conduct electricity from one sensor leg to the other. The amount of electricity conducted depends on the amount of soil moisture.
The soil moisture sensor in your Photo kit has a 3-pin screw terminal. You'll need to attach 3 jumper wires to the screw terminal. The back of the sensor has labels for the 3 pins: SIG, GND, VCC.
To attach jumper wires to the soil moisture sensor, you will need:
Soil moisture sensor with 3-pin screw terminal
3 jumper wires (use different colors to help identify them; recommend red, black, and yellow)
Small flat-head screwdriver (obtain from teacher, if necessary)
Use a small flat-head screwdriver to turn each screw counterclockwise until slightly loosened (but don't remove them). This creates openings on the top of the terminal to insert the jumper wires.
Insert one end of the first jumper wire (yellow) into the terminal slot for SIG. Then use the screwdriver tighten that terminal's screw (turn clockwise) until the jumper wire is held firmly.
Insert one end of the second jumper wire (black) into the terminal slot for GND. Then use the screwdriver tighten that terminal's screw (turn clockwise) until the jumper wire is held firmly.
Insert one end of the third jumper wire (red) into the terminal slot for VCC. Then use the screwdriver tighten that terminal's screw (turn clockwise) until the jumper wire is held firmly.
To connect a soil moisture sensor to your Photon using the breadboard, you will need:
Soil Moisture Sensor with 3 attached jumper wires
DUAL I/O PINS: The soil moisture sensor is connected to two different I/O pins. The sensor's SIG wire is connected to an analog I/O pin that will be used as an input to read data signals from the sensor. The sensor's VCC wire is connected to another I/O pin that will be used as an output to provide power to the sensor when taking a reading.
TWIN PINS: Analog pins A2, A3, A4, and A5 are each represented by two pins on the Photon board. The duplicate pins are labeled as: SS/A2, SCK/A3, MISO/A4, MOSI/A5. If you use one of these pins, you cannot use its twin at the same time.
Here are the steps to connect the soil moisture sensor to your Photon using the breadboard:
Plug the SIG jumper wire into any analog I/O pin on the Photon circuit board.
Plug the GND jumper wire into a pin hole connected to GND: either plug it into a negative power rail on the breadboard (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Plug the VCC jumper wire into any I/O pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect a soil moisture sensor:
Keep in mind that your connection can look different than this example diagram:
Your moisture sensor's SIG wire could connect to a different analog I/O pin. (The example connects to the A2 pin.)
Your moisture sensor's GND wire could connect either to a different GND pin or to a negative power rail connected to a GND pin. (There are three available GND pins.)
Your moisture sensor's VCC wire could connect to a different I/O pin. (The example connects to the D6 pin.)
Alternatively, you could connect the sensor's wires into different terminal strip rows on a breadboard, and then use 3 additional jumper wires to connect to the Photon circuit board.
Once the moisture sensor is connected to the Photon, insert the sensor legs into the soil (or similar material) where you need to take moisture measurements.
The basic steps to control a soil moisture sensor in your app code are:
Declare global variables to store the I/O pin numbers for the moisture sensor.
Set the pin mode for the sensor's power pin in the setup()
function, and turn off the sensor.
Use a sequence of digitalWrite()
and analogRead()
statements to briefly turn on the sensor and read the soil moisture.
OPTIONAL: Use the map()
method to convert the sensor reading to a custom range.
You should declare global variables to store the I/O pin numbers that the moisture sensor's SIG wire (data signal) and VCC wire (power) are connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the trimpot to a different pin number).
Add this code statement (modify if necessary) before the setup()
function:
Each line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variables will be called soil
and soilPower
. You can change the names, but choose names that will make sense to anyone reading the code.
It assigns a value to the variable. In this example, soil
will be equal to A2
and soilPower
will be equal to D6
. If necessary, modify these values to match the actual I/O pins that your sensor's SIG and VCC wires are connected to.
You need to set the pin mode for the moisture sensor's power pin to be used as an output. Then you need turn off the power to the sensor until you're ready to actually take a sensor reading.
Add this code (modify if necessary) within the setup()
function:
The pinMode()
method requires two parameters inside its parentheses (in this order):
The I/O pin number, which can be the actual pin number (such as: D6
, etc.) or a variable that stores a pin number. In this example, the variable named soiPower
is listed. If necessary, change this to match the variable name for your moisture sensor's power pin.
The mode value, which will always be OUTPUT
for an LED light because your app will send "on" and "off" signals (or brightness signals) to the LED light.
The digitalWrite()
method requires two parameters inside its parentheses (in this order):
The I/O pin number, which can be the actual pin number (such as: D6
, etc.) or a variable that stores a pin number. In this example, the variable named soiPower
is listed. If necessary, change this to match the variable name for your moisture sensor's power pin.
The signal value, which can be HIGH
or LOW
. Your Photon uses this value to send an electrical signal through the pin: HIGH
is a signal of 3.3 volts which represents "on," while LOW
is a signal of 0 volts which represents "off." In this case, LOW
is being used to turn off the moisture sensor.
PIN MODE: Analog inputs do NOT need to have their pin mode set within the setup()
function. Their pin mode gets automatically set when the analogRead()
method is used. That's why there's no pinMode()
statement for the soil
pin.
A constant flow of electricity across the moisture sensor legs could cause them to corrode over time due to the natural salts and other minerals found in soil. The gold-plating on the sensors legs resist corrosion, but it's still better to only briefly turn on the sensor's power when taking a reading.
Reading the soil moisture always requires a sequence of four steps:
Turn on the sensor's power using the digitalWrite()
method.
Allow time for electricity to flow through the soil by using the delay()
method.
Read the soil moisture using the analogRead()
method.
Turn off the sensor's power using the digitalWrite()
method.
A local variable named soilRead
is declared that will have a data type of int
(integer). This variable is made equal to whatever value is returned by the analogRead()
method. You can change the name of this variable, but it will make sense if it's similar to the variable name used for the trimpot pin number.
The analogRead()
method requires one parameter insides its parentheses:
The I/O pin number, which can be the actual pin number (such as: A2
, etc.) or a variable that stores a pin number. In this example, the variable named soil
is listed. If necessary, change this to match the variable name for the pin number of your sensor's SIG wire.
The analogRead()
method will return an integer (whole number) value ranging from 0-4095:
When there is less moisture detected, the reading will have a lower value.
When there is more moisture detected, the reading will have a higher value.
You'll need to add code to do something with the reading stored as soilRead
. For example, this might be an if-else statement to perform certain actions based on whether soilRead
is greater than (or less than) one or more specific values.
Depending on the specific purpose of the moisture sensor in your device, you may need to gather some test values under different conditions (such as dry vs. wet) to see what the moisture values might actually be where your device will be used. This will help you determine which values to use in your code to make decisions. For example, if the moisture sensor will be used to send notifications when the soil is either too dry or too wet, what values will be used to decide this?
For example, the code below uses a value of 500
to decide whether the soil is too dry and a value of 3500
to decide whether the soil is too wet. However, you would need to gather test data to determine whether these values should be higher or lower.
In many cases, it may not be convenient to work with a value that ranges from 0-4095. Instead, it might be easier to have a value within a smaller custom range (such as: 0-10, 0-100, etc.) that makes more sense for your particular task.
The map()
function can be used to convert a value from its original range (such as 0-4095) into a new range of your choice. You decide the minimum and maximum values for the new range.
For example, if the moisture sensor were being used to automatically turn a sprinkler system on and off, you might want the sensor to return a value between 0-100 as an easier way to determine the relative soil moisture.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
As necessary, change the values assigned to minValue
and maxValue
to whatever numbers you want to use for your custom range. Also, the minValue
doesn't have to be zero.
Be sure to add code to do something with soilValue
. For example, this might be an if-else statement to perform certain actions based on whether soilValue
is greater than (or less than) one or more specific values.
NOTE: The code uses the round()
method to round the mapped value to the nearest integer because the map()
method returns a float
(decimal value). Also, inside the map()
method, the code intentionally adds 1 to the maxValue
because otherwise it is very difficult to get the maximum value even if the soil moisture is very high.
You could incorporate this code into a custom function called checkSoil()
that will read the soil moisture sensor and return a value mapped to a custom range:
If necessary, change the variable names for the sensor's pins to match your variable names. You can also change the values assigned to minValue
and maxValue
to whatever numbers you want to use for your custom range.
The checkSoil()
function will return the mapped sensor value as an integer, which your code should store in a variable of data type int
.
For example, to call the checkSoil()
function within the loop()
function:
Your Photon kit includes a magnetic switch that can be used to detect whether a door, window, drawer, box, etc. is open or closed.
The switch consists of two pieces, and it can detect whether these two pieces are close to each other:
The piece with the wires contains a reed switch that moves in response to the presence or absence of a magnetic field.
The other piece without the wires contains a magnet, so it can activate the reed switch when the two pieces are close to each other.
If the two pieces of the magnetic switch are within 20 mm (0.75 inches) of each other, the switch detects that it's "closed" – otherwise, the switch will detect that it's "open."
These magnetic switches are commonly used in security systems for doors and windows, but they are also used in many other products. For example, a doorbell uses a magnetic switch to detect when it is being pressed. Magnetic switches are also used in many laptops and tablets to detect when the lid/cover is open or closed, in order to automatically wake up the device or put it to sleep.
The reed switch (the piece with the wires) will be connected to the Photon. Then the reed switch will be attached to a stationary edge near something that opens (such as: door, window, drawer, etc.). For example, the reed switch could be attached to the edge of a door frame – but not to the door itself.
The magnet (the piece without wires) would be attached to the object (door, window, etc.) that actually moves when opened. The two pieces of the magnetic switch should be positioned so they are very close together (no more than 0.75 inches apart) when the object (door, window, etc.) is closed.
To connect a magnetic switch to your Photon using the breadboard, you will need:
Magnetic Switch
2 jumper wires (use different colors to help identify them)
Here are the steps to connect the magnetic switch to your Photon using the breadboard:
Insert the two wires of the magnetic switch into different terminal strip rows on the breadboard. (Different terminal strip rows have different row numbers.)
Plug one end of a jumper wire into the same terminal strip row as one switch wire. Plug the other end of this jumper wire into an I/O pin on the Photon circuit board.
Plug one end of the other jumper wire into the same terminal strip row as the other switch wire. Plug the other end of this jumper wire into a pin hole connected to GND: either plug it into a negative power rail on the breadboard (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect a magnetic switch:
Keep in mind that your connection can look different than this example diagram:
Your magnetic switch wires could be inserted into different row numbers on either breadboard side. (The example connects the switch wires to rows 17-18 on the left side of the breadboard.)
Your magnetic switch wires could be inserted into a different column on the breadboard. (The example connects the switch wires into column A of the terminal strip rows.)
Your magnetic switch could connect (through a jumper wire) to a different I/O pin. (The example connects to the D0 pin on the Photon circuit board.)
Your magnetic switch could connect (through a jumper wire) either to a different GND pin or to a negative power rail connected to a GND pin. (There are three available GND pins on the Photon circuit board.)
The basic steps to use a magnetic switch in your app code are:
Declare a global variable to store the I/O pin number for the switch.
Set the pin mode for the switch pin in the setup()
function.
Use a digitalRead()
statement to check whether the switch is currently open or closed, and add code statements that should be performed depending on the result.
You should declare a global variable to store the I/O pin number that the switch is connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the button to a different pin number).
Add this code statement (modify if necessary) before the setup()
function:
This line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variable will be called magSwitch
. You can change the variable name, but choose a name that will make sense to anyone reading the code.
It assigns a value to the variable. In this example, the variable's value will be equal to D0
. If necessary, modify this value to match the actual I/O pin number that your switch is connected to.
SWITCH = KEYWORD: You cannot use "switch" as the name of a variable (or a custom function) because switch()
is a reserved keyword in the Wiring programming language.
You need to set the pin mode for the magnetic switch to be used as an input.
Add this code statement (modify if necessary) within the setup()
function:
The pinMode()
method requires two parameters inside its parentheses (in this order):
The I/O pin number, which can be the actual pin number (such as: D0
, etc.) or a variable that stores a pin number. In this example, a variable named magSwitch
is listed. If necessary, change this to match the variable name for your magnetic switch.
The mode value, which will always be INPUT_PULLUP
for a magnetic switch.
The digitalRead()
method is used to check whether a magnetic switch is currently open or closed.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
In the first code statement, a local variable named switchState
is declared that will have a data type of int
(integer). This variable is made equal to whatever value is returned by the digitalRead()
method. You can change the name of this variable, but it will make sense if it's similar to the variable name used for the switch pin number.
The digitalRead()
method requires one parameter insides its parentheses:
The I/O pin number, which can be the actual pin number (such as: D2
, etc.) or a variable that stores a pin number. In this example, the variable named magSwitch
is listed. If necessary, change this to match the variable name for your switch's pin number.
The digitalRead()
method will return a value of either HIGH
or LOW
(which are treated as if they were int
values):
HIGH
indicates that the magnetic switch is currently open.
LOW
indicates that the magnetic switch is currently closed.
The condition listed inside the parentheses of the if statement checks whether the value of switchState
is equivalent to HIGH
:
If this condition is true, the code within the curly braces of the if
statement will be performed. You will need to add code statements within the curly braces that perform the actions you want when the magnetic switch is open.
Otherwise, if this condition is false (because switchState
is LOW
), the code within the curly braces of the else
statement will be performed. You will need to add code statements within the curly braces that perform the actions you want when the magnetic switch is closed.
Alternatively, you could check for just one condition (either HIGH
or LOW
) without including an else
statement to perform actions for the opposite condition.
The Photon kit includes a light sensor (also known as a photocell) which is a variable resistor that changes its resistance in response to the amount of ambient light in the environment.
For example, some outdoor lights on houses and buildings use photocells to automatically turn the light on or off depending on whether it is dark or light outside. Most smartphones have light sensors to automatically adjust the brightness of the screen depending on the amount of ambient light detected.
The light sensor is a variable resistor: its resistance changes (depending on the amount of light it is exposed to). A static resistor (which has a fixed resistance) will be connected in series with the photocell to create a voltage divider. This will allow the Photon to measure the resistance of the photocell, which indicates the amount of light reaching the sensor.
A static resistor will be used to connect one leg of the light sensor to a GND (-) pin.
Your Photon kit contains a set of resistors with a resistance rating of 330 Ohms. In order to insert a resistor into the pin holes of a breadboard, you will need to bend both resistor legs into ~90° angles:
The light sensor has 2 metal legs that will be inserted into pin holes on the breadboard. One of the legs will actually have two connections – this is the voltage divider created using a static resistor.
To connect a light sensor to your Photon using the breadboard, you will need:
Light sensor (aka photocell)
Resistor with bent legs
2 jumper wires (use different colors to help identify them)
3.3V MAXIMUM: Analog inputs, such as the light sensor, require 3.3V of power for accurate measurements. Connect the light sensor to the 3.3V pin on your Photon, or connect it to a positive power rail that's connected to the 3.3V pin.
RESISTOR REQUIRED: A static resistor will be used to create a voltage divider that allows the variable resistance of the light sensor to be measured.
TWIN PINS: Analog pins A2, A3, A4, and A5 are each represented by two pins on the Photon board. The duplicate pins are labeled as: SS/A2, SCK/A3, MISO/A4, MOSI/A5. If you use one of these pins, you cannot use its twin at the same time.
Here are the steps to connect the light sensor to your Photon using the breadboard:
Insert the two legs of the light sensor into different terminal strip rows on the breadboard. (Different terminal strip rows have different row numbers.)
Plug one end of a jumper wire into the same terminal strip row as one sensor leg. Plug the other end of this jumper wire into the 3.3V pin on the Photon circuit board (or plug it into a positive power rail that's connected to the 3.3V pin via a different jumper wire).
Plug one end of a second jumper wire into the same terminal strip row as the second sensor leg. Plug the other end of this jumper wire into any analog I/O pin on the Photon circuit board.
Insert one end of the resistor into the same terminal strip row as the second sensor leg. Insert the other end of the resistor into a pin hole of the negative column of the closest power rail on the breadboard.
If the negative power rail isn't already connected to a GND pin on the Photon circuit board, then plug one end of a third jumper wire into another pin hole in the negative power rail, and plug the other end of this jumper wire into a GND pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect a light sensor (ignore the wiring at the top for the temperature sensor):
Keep in mind that your connection can look different than this example diagram:
Your light sensor legs could be inserted into different row numbers on the breadboard. (The example connects the legs to row 27 and row 30.)
Your light sensor legs could be inserted into a different column on the breadboard. (The example connects the legs into column F of the terminal strip rows.)
Your light sensor could connect to a different analog I/O pin. (The example connects to the A0 pin.)
Your light sensor could connect (through a jumper wire) either directly to the 3.3V pin or to a positive power rail on the breadboard that's connected to the 3.3V pin.
The negative power rail on your breadboard could connect to a different GND pin. (There are three available GND pins.)
The basic steps to control a light sensor (photocell) in your app code are:
Declare a global variable to store the I/O pin number for the light sensor.
Use the analogRead()
method to measure the amount of light.
OPTIONAL: Use the map()
method to convert the sensor reading to a custom range.
You should declare a global variable to store the I/O pin number that the light sensor is connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the trimpot to a different pin number).
Add this code statement (modify if necessary) before the setup()
function:
This line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variable will be called light
. You can change the variable name, but choose a name that will make sense to anyone reading the code.
It assigns a value to the variable. In this example, the variable's value will be equal to A0
. If necessary, modify this value to match the actual I/O pin that your speaker is connected to.
PIN MODE: Analog inputs do NOT need to have their pin mode set within the setup()
function. Their pin mode gets automatically set when the analogRead()
method is used.
The analogRead()
method is used to read the light sensor, which indicates the amount of ambient light reaching the sensor.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
A local variable named lightRead
is declared that will have a data type of int
(integer). This variable is made equal to whatever value is returned by the analogRead()
method. You can change the name of this variable, but it will make sense if it's similar to the variable name used for the trimpot pin number.
The analogRead()
method requires one parameter insides its parentheses:
The I/O pin number, which can be the actual pin number (such as: A0
, etc.) or a variable that stores a pin number. In this example, the variable named light
is listed. If necessary, change this to match the variable name for your trimpot's pin number.
The analogRead()
method will return an integer (whole number) value ranging from 0-4095:
When there is less light detected, the reading will have a lower value.
When there is more light detected, the reading will have a higher value.
You'll need to add code to do something with the reading stored as lightRead
. For example, this might be an if-else statement to perform certain actions based on whether lightRead
is greater than (or less than) one or more specific values.
Depending on the specific purpose of the light sensor in your device, you may need to gather some test values under different conditions to see how dark or how bright the environment will actually be where your device will be used. This will help you determine which values to use in your code to make decisions. For example, if the light sensor will be used to turn on an LED light when a room is too dark, what value will be used to decide that the room is too dark?
For example, the code below uses a value of 250
to decide whether a room is too dark. However, you would need to gather test data to determine whether this value should be higher or lower.
In many cases, it may not be convenient to work with a value that ranges from 0-4095. Instead, it might be easier to have a value within a smaller custom range (such as: 0-10, 0-100, etc.) that makes more sense for your particular task.
The map()
function can be used to convert a value from its original range (such as 0-4095) into a new range of your choice. You decide the minimum and maximum values for the new range.
For example, if the light sensor were being used to automatically turn on an LED light when the environment is too dark, you might want the sensor to return a value between 0-100 as an easier way to determine the relative brightness of the environment.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
As necessary, change the values assigned to minValue
and maxValue
to whatever numbers you want to use for your custom range. Also, the minValue
doesn't have to be zero.
Be sure to add code to do something with lightValue
. For example, this might be an if-else statement to perform certain actions based on whether lightValue
is greater than (or less than) one or more specific values.
NOTE: The code uses the round()
method to round the mapped value to the nearest integer because the map()
method returns a float
(decimal value). Also, inside the map()
method, the code intentionally adds 1 to the maxValue
because otherwise it is very difficult to get the maximum value even if the ambient light in the environment is very bright.
You could incorporate this code into a custom function called checkSensor()
that will read an analog sensor and return a value mapped to a custom range:
When calling the checkSensor()
function within the loop()
function, you will need to include values for these 3 parameters (in order) inside its parentheses:
the sensor's pin number, which will most likely be a variable that stores the pin number
the desired minimum value for the range, which should be an integer (whole number)
the desired maximum value for the range, which should be an integer (whole number)
The checkSensor()
function will return the mapped sensor value as an integer, which your code should store in a variable of data type int
.
For example, to call the checkSensor()
function within the loop()
function:
The checkSensor()
function could also be used to read other analog sensors, such as a trimpot dial:
Physical buttons that people can push are used as inputs on many different types of devices.
Your Photon kit has a set of 4 push buttons with different cap colors: red, yellow, green, and blue.
The buttons in your Photon kit are classified as momentary switches, which means they detect when they are being pressed or pushed. For example, the keys on a computer keyboard are momentary switches: they are only "on" when you press them (and they turn "off" when you release them).
This is different from maintained switches, which physically toggle between one state and another state. For example, a light switch is a maintained switch: pressing (or flipping) the switch will turn it on, and it will stay this way until pressed again (or flipped back).
However, you can make a push button act like a maintained switch by adding a global variable in your app code to track the button's current status ("on" or "off"), and then toggling this status in your code each time the button is pushed.
Each push button has 2 pairs of metal legs on opposite sides of its base. Unlike other components that connect to only one half of a breadboard, the push button has to connect to both halves of the breadboard across the gap in the middle. This is simply due to the width of the button – there isn't enough space to connect the push button plus jumper wires on one half of the breadboard.
To connect a push button to your Photon using the breadboard, you will need:
Push button
2 jumper wires (use different colors to help identify them)
Here are the steps to connect the push button to your Photon using the breadboard:
Place the push button along the middle divider of the breadboard, so one pair of legs will align with pin holes in column D on the left half of the breadboard, while the other pair of legs (on the opposite side) will align with pin holes in column G on the right half of the breadboard. If necessary, you can gently bend the metal legs to align them better with the pin holes.
Firmly press the button down to "snap" its base into place, so it's flat against the breadboard.
Plug one end of a jumper wire into the same terminal strip row as one of the button legs on the right half of the breadboard. Plug the other end of this jumper wire into an I/O pin on the Photon circuit board.
Plug one end of the other jumper wire into the same terminal strip row as the other button leg on the right half of the breadboard. Plug the other end of this jumper wire into a pin hole connected to GND: either plug it into a negative power rail (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect a push button (you can ignore the wiring for the LED and resistor):
Keep in mind that your connection can look different than this example diagram:
Your button legs could be inserted into different row numbers. (The example connects the button legs to row 4 and row 6.)
Your button leg could connect (through a jumper wire) to a different I/O pin. (The example connects to the D2 pin.)
Your button could connect (through a jumper wire) either directly to a GND pin or to a negative power rail that's connect to a GND pin. (There are three available GND pins.)
The basic steps to use a push button in your app code are:
Declare a global variable to store the I/O pin number for the button.
Set the pin mode for the button pin in the setup()
function.
Use a digitalRead()
statement to check whether the button is currently pressed, and add code statements that should be performed depending on the result.
You should declare a global variable to store the I/O pin number that the button is connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the button to a different pin number).
Add this code statement (modify if necessary) before the setup()
function:
This line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variable will be called button
. You can change the variable name, but choose a name that will make sense to anyone reading the code.
It assigns a value to the variable. In this example, the variable's value will be equal to D2
. If necessary, modify this value to match the actual I/O pin number that your button is connected to.
If you have multiple buttons connected to your Photon, then be sure to give each button a unique variable name by adding an adjective or number to the variable names. For example:
You need to set the pin mode for the button to be used as an input.
Add this code statement (modify if necessary) within the setup()
function:
The pinMode()
method requires two parameters inside its parentheses (in this order):
The I/O pin number, which can be the actual pin number (such as: D2
, etc.) or a variable that stores a pin number. In this example, a variable named button
is listed. If necessary, change this to match the variable name for your button.
The mode value, which will always be INPUT_PULLUP
for a push button.
If you have multiple buttons connected to your Photon, then be sure to set the pin mode for each button pin variable. For example:
The digitalRead()
method is used to check whether a button is currently pressed.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
In the first code statement, a local variable named buttonState
is declared that will have a data type of int
(integer). This variable is made equal to whatever value is returned by the digitalRead()
method. You can change the name of this variable, but it will make sense if it's similar to the variable name used for the button pin number.
The digitalRead()
method requires one parameter insides its parentheses:
The I/O pin number, which can be the actual pin number (such as: D2
, etc.) or a variable that stores a pin number. In this example, the variable named button
is listed. If necessary, change this to match the variable name for your button's pin number.
The digitalRead()
method will return a value of either HIGH
or LOW
(which are treated as if they were int
values):
HIGH
indicates that the button is NOT currently pressed.
LOW
indicates that the button is currently pressed.
The condition listed inside the parentheses of the if statement checks whether the value of buttonState
is equivalent to LOW
:
If this condition is true, the code within the curly braces of the if
statement will be performed. You will need to add code statements within the curly braces that perform the actions you want.
If this condition is false (because the buttonState
is HIGH
), the code within the curly braces will NOT be performed. Optionally, you can add an else statement to perform a different set of code statements when the button is not pressed.
The motion sensor included in your Photon kit uses passive infrared (PIR) light to detect movement in the surrounding environment up to about 10 feet away.
The motion sensor has a 3-wire JST connector with 3 pins for plugging into a breadboard. (If the end of your connector doesn't have 3 metal pins, attach the JST right angle connector included in your kit.)
To connect a motion sensor to your Photon using the breadboard, you will need:
Motion sensor (with 3-pin JST right angle connector)
3 jumper wires (use different colors to help identify them; it may help to match the sensor wires)
5V REQUIRED: The motion sensor requires 5V of power to operate.
If your Photon is being powered through the barrel jack, connect to the VIN pin.
If your Photon is being powered through the Micro-USB port, connect to the V-USB pin.
Here are the steps to connect the motion sensor to your Photon using the breadboard:
Insert the 3 pins of the motion sensor connector into different terminal strip rows on the breadboard. (Different terminal strip rows have different row numbers.)
Plug one end of a jumper wire into the same terminal strip row as the sensor's black wire. Plug the other end of this jumper wire into an I/O pin on the Photon circuit board.
Plug one end of a second jumper wire into the same terminal strip row as the sensor's white wire. Plug the other end of this jumper wire into a pin hole connected to GND: either plug it into a negative power rail (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Plug one end of a third jumper wire into the same terminal strip row as the sensor's red wire. Plug the other end of this jumper wire into either the VIN pin or V-USB pin on the Photon circuit board (or to a positive power rail on the breadboard that is connected to VIN or V-USB). If your Photon is being powered through the barrel jack, connect to the VIN pin. Otherwise, if your Photon is being powered through the Micro-USB port, connect to the V-USB pin.
Here's a wiring diagram showing a possible way to connect a motion sensor:
Keep in mind that your connection can look different than this example diagram:
Your motion sensor pins could be inserted into different row numbers. (The example connects the sensor pins to rows 16-18 on the left side of the breadboard.)
Your motion sensor pins could be inserted into a different column of the breadboard. (The example connects the sensor pins into column A of the terminal strip rows.)
Your sensor's black wire could connect (through a jumper wire) to a different I/O pin. (The example connects to the D0 pin.)
Your sensor's white wire could connect (through a jumper wire) to either to a different GND pin or to a negative power rail connected to a GND pin. (There are three available GND pins.)
Your sensor's red wire could connect (through a jumper wire) to either the VIN pin or V-USB pin (or to a positive power rail that's connected to one of these pins). (The example connects directly to the V-USB pin.)
The basic steps to use a motion sensor in your app code are:
Declare a global variable to store the I/O pin number for the motion sensor.
Set the pin mode for the motion sensor pin in the setup()
function.
Use a digitalRead()
statement to check whether the sensor detects any motion, and add code statements that should be performed if motion is detected (or not detected).
You should declare a global variable to store the I/O pin number that the motion sensor's data wire is connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the motion sensor to a different pin number).
Add this code statement (modify if necessary) before the setup()
function:
This line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variable will be called motion
. You can change the variable name, but choose a name that will make sense to anyone reading the code.
It assigns a value to the variable. In this example, the variable's value will be equal to D0
. If necessary, modify this value to match the actual I/O pin number that your button is connected to.
You need to set the pin mode for the motion sensor to be used as an input.
Add this code statement (modify if necessary) within the setup()
function:
The pinMode()
method requires two parameters inside its parentheses (in this order):
The I/O pin number, which can be the actual pin number (such as: D0
, etc.) or a variable that stores a pin number. In this example, a variable named motion
is listed. If necessary, change this to match the variable name for your button.
The mode value, which will always be INPUT_PULLUP
for a motion sensor.
The digitalRead()
method is used to check whether the sensor currently detects any motion.
Add this code (modify as necessary) to your app within the loop()
function or a custom function:
In the first code statement, a local variable named motionState
is declared that will have a data type of int
(integer). This variable is made equal to whatever value is returned by the digitalRead()
method. You can change the name of this variable, but it will make sense if it's similar to the variable name used for the motion sensor pin number.
The digitalRead()
method requires one parameter insides its parentheses:
The I/O pin number, which can be the actual pin number (such as: D0
, etc.) or a variable that stores a pin number. In this example, the variable named motion
is listed. If necessary, change this to match the variable name for your motion sensor's pin number.
The digitalRead()
method will return a value of either HIGH
or LOW
(which are treated as if they were int
values):
HIGH
indicates that motion is NOT currently detected.
LOW
indicates that motion is currently detected.
The condition listed inside the parentheses of the if statement checks whether the value of motionState
is equivalent to LOW
:
If this condition is true, the code within the curly braces of the if
statement will be performed. You will need to add code statements within the curly braces that perform the actions you want.
If this condition is false (because the motionState
is HIGH
), the code within the curly braces will NOT be performed. Optionally, you can add an else statement to perform a different set of code statements when motion is not detected.
IMPORTANT: You will notice that a delay()
of 2 seconds is included when motion is detected. This delay is needed to allow the motion sensor to capture a new "snapshot" of the environment before checking the sensor again.
The RHT03 sensor in your Photon kit can measure the relative humidity and temperature of the air.
To connect the RHT03 sensor to your Photon using the breadboard, you will need:
RHT03 Humidity and Temperature Sensor
3 jumper wires (use different colors to help identify them)
The RHT03 humidity and temperature sensor has 4 metal legs. The front side of the sensor has openings to allow air in.
If you were looking at the front of the sensor and the sensor legs were numbered left to right as 1-4, the wiring connections would be:
3.3V OR 5V: The RHT03 sensor can operate on either 3.3V or 5V of power.
If your Photon is being powered through the barrel jack, you can connect the RHT03 sensor to either the 3.3V pin or VIN pin.
If your Photon is being powered through the Micro-USB port, you can connect the RHT03 sensor to either the 3.3V pin or V-USB pin.
Here are the steps to connect the RHT03 sensor to your Photon using the breadboard:
Insert the four metal legs of the sensor into different terminal strip rows on the breadboard. (Different terminal strip rows have different row numbers.)
Plug one end of a jumper wire into the same terminal strip row as the power leg of the sensor. Plug the other end of this jumper wire into the 3.3V pin or a 5V pin (VIN or V-USB) on the Photon circuit board (or to a positive power rail on the breadboard connected to 3.3V, VIN, or V-USB). If your Photon is being powered through the barrel jack, connect to either the 3.3V pin or VIN pin. Otherwise, if your Photon is being powered through the Micro-USB port, connect to either the 3.3V pin or V-USB pin.
Plug one end of a second jumper wire into the same terminal strip row as the data leg of the sensor. Plug the other end of this jumper wire into any I/O pin on the Photon circuit board.
Plug one end of the third jumper wire into the same terminal strip row as the ground leg of the sensor. Plug the other end of this jumper wire into a pin hole connected to GND: either plug it into a negative power rail (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect the RHT03 humidity and temperature sensor (ignore the wiring for the light sensor):
Keep in mind that your connection can look different than this example diagram:
Your RHT03 sensor legs could be inserted into different row numbers. (The example connects the RHT03 sensor legs to rows 1-4 on the right side of the breadboard).
Your RHT03 sensor legs could be inserted into a different column of the breadboard. (The example connects the RHT03 sensor legs into column H of the terminal strip rows).
Your RHT03 sensor could connect (through a jumper wire) to a different I/O pin. (The example connects the RHT03 sensor to the D3 pin.)
Your RHT03 sensor could connect (through a jumper wire) directly to the 3.3V pin or a 5V pin (VIN or V-USB) – or it could connect to a positive power rail on the breadboard that's connected to the 3.3V pin or a 5V pin.
Your RHT03 sensor could connect (through a jumper wire) either directly to a GND pin or to a negative power rail that's connect to a GND pin. (There are three available GND pins.)
The basic steps to control the RHT03 humidity and temperature sensor in your app code are:
Include the SparkFun RHT03 library in your app.
Declare a global variable to store the I/O pin number for the RHT03 sensor.
Create a RHT03
object assigned to a global variable called rht
.
Use the rht.begin()
method to start the RHT03 sensor in the setup()
function.
Use a sequence of rht.update()
, rht.humidity()
, and rht.tempF()
statements to get new humidity and temperature readings.
Your Photon app must include a code library that will allow you to control the RHT03 sensor.
In Particle Build, click on the Libraries icon to open the Libraries menu panel.
Type rht
into the search field. Select the result called: SparkFunRHT03
Click the button to "Include in Project"
Select the title of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert this #include
statement at the beginning of your app code:
You should declare a global variable to store the I/O pin number that the RHT03 sensor's data leg is connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the motion sensor to a different pin number).
You will also need to create an object using the RHT03
class in the included library, and assign this object to a global variable.
Add this code statement (modify if necessary) before the setup()
function:
The first line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variable will be called rhtData
. You can change the variable name, but choose a name that will make sense to anyone reading the code.
It assigns a value to the variable. In this example, the variable's value will be equal to D3
. If necessary, modify this value to match the actual I/O pin number that your sensor is connected to.
The second line of code creates a new object using the RHT03
class, and assigns the object to a global variable named rht
.
The rht.begin()
method is used to start the RHT03 sensor, which will automatically set its pin mode.
Add this code statement within the setup()
function to start the RHT03 sensor:
The rht.begin()
method requires the sensor's I/O pin number. In this case, the global variable named rhtData
stores this value. If you used a different name for the global variable storing your RHT03 sensor pin number, then insert that name instead.
The rht.update()
method is used to get new sensor readings for the relative humidity and temperature of the air.
If the update is successful, the rht.update()
method will return a value of 1
(which is equivalent totrue
). Then you can use these other rht
methods to get the updated values for the relative humidity (%) and temperature (in Fahrenheit or Celsius):
The rht.humidity()
method returns the relative humidity of the air as a value between 0-100, representing a percentage. A higher number means the air is more humid (has more water vapor).
The rht.tempF()
method returns the temperature of the air in degrees Fahrenheit – while the rht.tempC()
method will return the temperature of the air in degrees Celsius.
Each humidity and temperature measurement is returned as a float
value (decimal number). In most cases, it will be simpler to round these values to the nearest integer (whole number).
Add this code (modify as necessary) within the loop()
function or a custom function:
This code creates two variables named temperature
and humidity
to store the values returned by the sensor, which have been rounded to integer values.
If you want the temperature in degrees Celsius, then replace rht.tempF()
with rht.tempC()
.
Be sure to add code to do something with the temperature
and/or humidity
values.
The triple-axis accelerometer included in your Photon kit can be used to detect changes in motion or orientation in 3 dimensions (x, y, z).
Like the name implies, an accelerometer works by detecting acceleration – a change in motion. If a device with an accelerometer experiences a change in motion (i.e., speeding up, slowing down, or changing direction), the accelerometer can sense this change and measure the amount of acceleration in each of the 3 dimensions (x, y, z).
For example, fitness trackers use accelerometers to count steps by detecting changes in motion.
Your accelerometer is sensitive enough that it can be used to even tiny changes in motion caused by a nearby tap or bump. For example, if your Photon device is on a table, the accelerometer would be able to detect if you tapped the table with a finger.
Even if a device with an accelerometer is not moving, the accelerometer can detect the orientation (tilt) of the device by measuring the acceleration due to Earth's gravity, which is a constant downward force acting on all objects. The accelerometer can determine if the object is parallel to the Earth's surface or if it's tilted.
For example, smartphones and tablets use accelerometers to sense the orientation of the device, in order to change the screen's orientation to match.
Your accelerometer can be used to measure the tilt (in degrees) for pitch and roll:
Pitch is rotation on the Y-axis, which means an object is tilted up or down.
Roll is rotation on the X-axis, which means an object is tilted right or left.
NOTE: An accelerometer cannot measure yaw because Earth's gravity acts in the same direction as the Z-axis, which prevents the accelerometer from measuring rotation on the Z-axis. Instead, a different sensor called a magnetometer (i.e., digital compass) could be used to measure yaw by measuring an object's orientation relative to Earth's magnetic north pole.
The MMA8452Q triple-axis accelerometer in your Photon kit has 6 pins located along its front edge (which determines its orientation for measuring pitch and roll). There are labels for each pin printed on the accelerometer circuit board. However, only 4 of the pins will need to be connected to your Photon.
To connect the accelerometer to your Photon using the breadboard, you will need:
Accelerometer (MMA8452Q)
4 jumper wires (use different colors to help identify them)
3.3V MAXIMUM: The accelerometer operates at 3.3V of power. Connect it to the 3.3V pin on your Photon, or connect it to a positive power rail that's connected to the 3.3V pin.
Do NOT connect it to VIN or V-USB because the higher voltage could damage it.
Here are the steps to connect the accelerometer to your Photon using the breadboard:
Insert the six metal pins of the accelerometer into different terminal strip rows on the breadboard. (Different terminal strip rows have different row numbers.)
Plug one end of a jumper wire into the same terminal strip row as the accelerometer's 3.3V pin. Plug the other end of this jumper wire into the 3.3V pin on the Photon circuit board (or to a positive power rail on the breadboard connected to the 3.3V pin).
Plug one end of a second jumper wire into the same terminal strip row as the accelerometer's SDA pin. Plug the other end of this jumper wire into the D0 pin on the Photon circuit board.
Plug one end of a third jumper wire into the same terminal strip row as the accelerometer's SCL pin. Plug the other end of this jumper wire into the D1 pin on the Photon circuit board.
Plug one end of a fourth jumper wire into the same terminal strip row as the accelerometer's GND pin. Plug the other end of this jumper wire into a pin hole connected to GND: either plug it into a negative power rail (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect the accelerometer (ignore the wiring for the push button):
Keep in mind that your connection can look different than this example diagram:
Your accelerometer pins could be inserted into different row numbers. (The example connects the accelerometer pins to rows 1-6 on the right side of the breadboard).
Your accelerometer pins could be inserted into a different column of the breadboard. (The example connects the accelerometer pins into column H of the terminal strip rows).
Your accelerometer could connect (through a jumper wire) directly to the 3.3V pin or to a positive power rail on the breadboard that's connected to the 3.3V pin.
Your accelerometer could connect (through a jumper wire) either directly to a GND pin or to a negative power rail that's connect to a GND pin. (There are three available GND pins.)
The basic steps to control the accelerometer in your app code are:
Include the SparkFun MMA8452Q library and Math library in your app.
Create a MMA8452Q
object assigned to a global variable called accel
.
Use the accel.begin()
method to start the accelerometer in the setup()
function. If app will detect taps, use the accel.setupTap()
method to initialize the tap settings.
Use custom functions to detect taps or measure tilt angles using the accelerometer.
Your Photon app must include a code library that will allow you to control the accelerometer (which is an MMA8452Q accelerometer). You'll also add a Math library that will be used to calculate tilt angles.
In Particle Build, click on the Libraries icon to open the Libraries menu panel.
Type mma8452q
into the search field. Select the result called: SparkFunMMA8452Q
Click the button to "Include in Project"
Select the title of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert this #include
statement at the beginning of your app code:
In addition, you will include a Math library that has additional mathematical functions and constants, which will be needed to calculate tilt angles. (The Math library is available in Particle Build, but it won't show up in a search of the community libraries.)
You need to manually add this #include
statement (on new line after other #include
statement):
You need to create a new object using the MMA8452Q
class in the included SparkFun MMA8452Q library, and assign this object to a global variable named accel
.
Add this code statement before the setup()
function:
The accel.begin()
method is used to start the accelerometer, which will initialize its settings. (You do not need to set any pin modes for the accelerometer.)
Add this code statement within the setup()
function to start the accelerometer:
The accel.begin()
method can accept two parameters inside its parentheses (in this order):
The scale range, which determines the range and precision of the acceleration detection. The options for the scale are: SCALE_2G
, SCALE_4G
, or SCALE_8G
. A higher scale can detect larger changes in acceleration but is less precise. A lower scale is more precise. For your app, using SCALE_2G
is the probably the best choice because it will be the most precise.
The output data range (ODR), which determines how frequently it outputs new measurements. The ODR is set in Hz (number of times per second). The options for the ODR are: ODR_1
, ODR_6
, ODR_12
, ODR_50
, ODR_100
, ODR_200
, ODR_400
, or ODR_800
. A higher ODR is faster (more frequent), while a lower ODR is slower (less frequent). If your device is being powered by a battery, a lower ODR is more energy-efficient. For your app, using ODR_50
is probably a good choice.
Alternatively, you can exclude the parameters from the accel.begin()
statement. If you do this, the accelerometer will default to using SCALE_2G
and ODR_800
.
If your app will use the accelerometer to detect taps, then use the accel.setupTap()
method to initialize the settings for tap detection.
If detecting taps, add this code within the setup()
function (after the accel.begin()
statement):
If your app will NOT be detecting taps, then this code can be excluded.
If your app will use the accelerometer to detect an object's tilt, you'll add a custom function named checkTilt()
that measures tilt angles for pitch and roll using the accelerometer.
Add this checkTilt()
function after the loop()
function:
You'll need to add code within the function to do something with the values of pitch
and roll
, which indicate the direction(s) and angle(s) that the accelerometer is tilted.
Pitch is rotation on the Y-axis, which means the object is rotated up or down:
If the accelerometer is tilted up, the pitch will be a positive angle (between 1° to 180°).
If the accelerometer is tilted down, the pitch will be a negative angle (between -1° to -180°).
Roll is rotation on the X-axis, which means the object is rotated to the right or left:
If the accelerometer is tilted right, the roll will be a positive angle (between 1° to 180°).
If the accelerometer is tilted left, the roll will be a negative angle (between -1° to -180°).
When the accelerometer is perfectly level, the pitch and roll will both be equal to 0 (zero).
To check the tilt, call this function within the loop()
function (or within another custom function):
If your app will use the accelerometer to detect taps, you'll add a custom function named checkTap()
that detects taps using the accelerometer.
Add this checkTap()
function after the loop()
function:
The accel.readTap()
method is used to detect a tap. The method returns a value of 0
when no tap is detected. When a tap is detected, the method returns a non-zero value. The if
statement condition checks whether a non-zero value was returned (indicating a tap was detected).
You'll need to add code within the curly braces of the if
statement to do something when a tap is detected. Optionally, you can add code within the curly braces of the else
statement to do something when no tap is detected.
To check for a tap, call this function within the loop()
function (or within another custom function):
ADD-ON COMPONENT: The SparkFun Photon Kit does NOT include an ultrasonic sensor as a standard component. However, SparkFun sells the , which can be easily connected to a Photon. Your teacher may have added this sensor to your kit.
An ultrasonic sensor uses sonar to measure the distance to an object, similar to how bats and dolphins use for navigation and hunting.
An ultrasonic sensor has a transmitter (i.e., speaker) that produces high-frequency sound (beyond the range of human hearing). The sensor also has a matching receiver (i.e., microphone) that detects the echo of the high-frequency sound when it reflects back from an object. By measuring how much time it takes for the echo to arrive, you can calculate the distance between the sensor and the object.
The HC-SR04 ultrasonic sensor measures distances in a narrow cone of about 15° directly in front of the sensor. This sensor can detect obstacles located up to 400 cm away (about 13 feet). The sensor measurements are very accurate, within about 3 mm (about 0.1 inch) of the actual distance.
The HC-SR04 ultrasonic sensor has 4 pins for plugging into a breadboard. Each pin is labeled on the sensor's circuit board.
To connect the ultrasonic sensor to your Photon using the breadboard, you will need:
Ultrasonic Sensor (HC-SR04)
4 jumper wires (use different colors to help identify them)
5V REQUIRED: The ultrasonic sensor requires 5V of power to operate.
If your Photon is being powered through the barrel jack, connect to the VIN pin.
If your Photon is being powered through the Micro-USB port, connect to the V-USB pin.
Here are the steps to connect the ultrasonic sensor to your Photon using the breadboard:
Insert the 4 pins of the ultrasonic sensor into different terminal strip rows on the breadboard. (Different terminal strip rows have different row numbers.) It is recommended to insert the sensor on the left half of the breadboard with the transmitter and receiver facing away from the Photon.
Plug one end of a jumper wire into the same terminal strip row as the sensor's VCC pin. Plug the other end of this jumper wire into either the VIN pin or V-USB pin on the Photon circuit board (or to a positive power rail on the breadboard that is connected to VIN or V-USB). If your Photon is being powered through the barrel jack, connect to the VIN pin. Otherwise, if your Photon is being powered through the Micro-USB port, connect to the V-USB pin.
Plug one end of a second jumper wire into the same terminal strip row as the sensor's Trig pin. Plug the other end of this jumper wire into an I/O pin on the Photon circuit board.
Plug one end of a third jumper wire into the same terminal strip row as the sensor's Echo pin. Plug the other end of this jumper wire into an I/O pin on the Photon circuit board.
Plug one end of a fourth jumper wire into the same terminal strip row as the sensor's GND pin. Plug the other end of this jumper wire into a pin hole connected to GND: either plug it into a negative power rail (which is connected to GND via a different jumper wire), or plug it directly into a GND pin on the Photon circuit board.
Here's a wiring diagram showing a possible way to connect the ultrasonic sensor:
Keep in mind that your connection can look different than this example diagram:
Your ultrasonic sensor pins could be inserted into different row numbers. (The example connects the sensor pins to rows 23-26 on the left side of the breadboard.)
Your motion sensor pins could be inserted into a different column of the breadboard. (The example connects the sensor pins into column B of the terminal strip rows.)
Your sensor's VCC pin could connect (through a jumper wire) to either the VIN pin or V-USB pin (or to a positive power rail that's connected to one of these pins). (The example connects directly to the VIN pin.)
Your sensor's Trig pin could connect (through a jumper wire) to a different I/O pin. (The example connects to the D2 pin.)
Your sensor's Echo pin could connect (through a jumper wire) to a different I/O pin. (The example connects to the D3 pin.)
Your sensor's GND pin could connect (through a jumper wire) to either to a GND pin or to a negative power rail connected to a GND pin. (There are three available GND pins.)
The basic steps to use an ultrasonic sensor in your app code are:
Declare global variables to store the I/O pin numbers for the ultrasonic sensor.
Set the pin modes for the sensor in the setup()
function, and turn off the transmitter.
Use a custom function that will measure and return the distance to the nearest object.
You should declare global variables to store the I/O pin numbers that the ultrasonic sensor's transmitter (Trig) and receiver (Echo) are connected to. This will make it easier to understand your code (and easier to modify the code if you were to connect the trimpot to a different pin number).
Add this code (modify if necessary) before the setup()
function:
Each line of code does 3 things (in order):
It declares a data type for the variable's value. In this case, int
stands for integer (whole number). Photon pin numbers are always treated as int
values (even though they have letters).
It declares the variable's name. In this example, the variables will be called TRIG_PIN
(transmitter) and ECHO_PIN
(receiver). You can change the variable names, but choose names that will make sense to anyone reading the code. You will need to make sure the same variable names are listed in the custom function which measures the distance to the nearest object.
It assigns a value to the variable. In this example, the variables will be equal to D2
and D3
. If necessary, modify these values to match the I/O pins that your sensor pins are connected to.
You need to set the pin modes for the sensor's transmitter (Trig) and receiver (Echo). Then you need turn off the sensor's transmitter until you're ready to actually take a distance measurement.
Add this code (modify if necessary) within the setup()
function:
The pinMode()
method requires two parameters inside its parentheses (in this order):
The I/O pin number, which can be the actual pin number (such as: D2
, etc.) or a variable that stores a pin number. In this example, the variables named TRIG_PIN
and ECHO_PIN
are listed. If necessary, change these to match the variable names for your sensor's pins.
The mode value, which will be OUTPUT
for the sensor's transmitter pin and INPUT
for the sensor's receiver pin.
The digitalWrite()
method requires two parameters inside its parentheses (in this order):
The I/O pin number, which can be the actual pin number (such as: D2
, etc.) or a variable that stores a pin number. In this example, the variable named TRIG_PIN
is listed. If necessary, change this to match the variable name for your sensor's transmitter pin.
The signal value, which can be HIGH
or LOW
. Your Photon uses this value to send an electrical signal through the pin: HIGH
is a signal of 3.3 volts which represents "on," while LOW
is a signal of 0 volts which represents "off." In this case, LOW
is being used to turn off the transmitter.
You'll add a custom function named measureDistance()
than can be called to measure the distance from the ultrasonic sensor to the nearest object. The function will return the distance as a float
value (decimal number).
Add this measureDistance()
function after the loop()
function:
Possible modifications to this custom function:
If you used different names for the global variables representing the transmitter (TRIG_PIN
) and receiver (ECHO_PIN
), then be sure to modify this function to use those variable names instead.
If you want the function to return the distance measurement in units of centimeters (instead of inches), then modify the return
statement towards the end of the function.
Each time you need a new distance measurement, you'll need to call the measureDistance()
function.
To call this custom function, add this code within the loop()
function (or within another custom function):
A local variable named sensorDist
is declared that will have a data type of float
(decimal number). This variable will be made equal to the value returned by the measureDistance()
function.
You'll need add code to do something with the distance measurement stored in sensorDist
. It's common to use an if
statement (or an if-else statement) to perform certain actions based on whether the distance is less than (or greater than) a specific value.
For example, this code example will turn on an LED light if the distance is less than 6 inches (otherwise it will turn the LED off):
A good way to test your ultrasonic sensor is to connect the Micro OLED display to your Photon, so you can show the value of sensorDist
on the OLED screen to verify the sensor is working accurately.
For example, once you've added the other necessary code for the Micro OLED, you could add this code within the loop()
function:
Soil Moisture Sensor
Photon Pin
SIG (Signal) – Yellow
any analog I/O pin (A0, A1, A2, A3, A4, A5)
GND (Ground) – Black
GND
VCC (Power) – Red
any I/O pin
Magnetic Switch
Photon Pin
First Wire (either one)
any I/O pin
Second Wire
GND
Light Sensor (Photocell)
Photon Pin
First Leg (either one)
3.3V
Second Leg
(1) any analog I/O pin (A0, A1, A2, A3, A4, A5)
(2) GND using resistor
Push Button
Photon Pin
One Leg (any leg)
any I/O pin
Adjacent Leg on same side
GND
Motion Sensor
Photon Pin
Black - Data
any I/O pin
White - Ground
GND
Red - Power (5-12V)
5V through VIN or V-USB
RHT03 Temperature Sensor
Photon Pin
Leg 1 – Power (3.3-6V)
3.3V or 5V (through VIN or V-USB)
Leg 2 – Data
any I/O pin
Leg 3 – Unused
(none)
Leg 4 – Ground
GND
Accelerometer
Photon Pin
3.3V
3.3V
SDA
D0 (SDA)
SCL
D1 (SCL)
I2
(none)
I1
(none)
GND
GND
Ultrasonic Sensor | Photon Pin |
VCC | 5V through VIN or V-USB |
Trig | any I/O pin |
Echo | any I/O pin |
GND | GND |